diff --git a/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh b/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh index 0395ae254..1a3edccbf 100644 --- a/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh +++ b/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh @@ -30,9 +30,11 @@ cp -rp RUN_OnDemandFULL_BKP.sh ${INSTHOME}/bin/ cp -rp runstats_rebind.sh ${INSTHOME}/bin/ cp -rp CreateRoles.sh ${INSTHOME}/bin/ cp -rp grant_check.sh ${INSTHOME}/bin/ -cp -rp reorgTablesIndexesInplace2.sh ${INSTHOME}/bin/ +cp -rp reorgTablesIndexesInplace.sh ${INSTHOME}/bin/ cp -rp extract_authorization.sh ${INSTHOME}/bin cp -rp HADRMON.sh ${INSTHOME}/bin +cp -rp auditExtractUpload.sh ${INSTHOME}/bin/ + echo -e "\nCopying the file to bin/ITCS104 directory under Instance Home . . ." cp -rp FixInvalidObjects.sh ${INSTHOME}/bin/ITCS104/ @@ -48,7 +50,7 @@ cp PostBackFlow.sh ${INSTHOME}/Managed cp OwnerCheck.txt ${INSTHOME}/Managed echo -e "\nCopying files to maintenance directory under Instance Home . . . "; -cp -rp reorgTablesIndexesInplace2_maintenance.sh ${INSTHOME}/maintenance/reorgTablesIndexesInplace2.sh +cp -rp reorgTablesIndexesInplace2_maintenance.sh ${INSTHOME}/maintenance/reorgTablesIndexesInplace.sh if [ ! -d ${INSTHOME}/maintenance/logs ] ; then mkdir -p ${INSTHOME}/maintenance/logs echo "${DATETIME}:Creating directory ${INSTHOME}/maintenance/logs" diff --git a/instance-applications/120-ibm-db2u-database/files/DB2_Backup.sh b/instance-applications/120-ibm-db2u-database/files/DB2_Backup.sh index d8f21436c..984c68e3d 100755 --- a/instance-applications/120-ibm-db2u-database/files/DB2_Backup.sh +++ b/instance-applications/120-ibm-db2u-database/files/DB2_Backup.sh @@ -1,12 +1,9 @@ #!/bin/ksh -set -x - ######################################################### -# DB2_Backup.sh -# -# Things to do: -# Recovery history retention (days) (REC_HIS_RETENTN) = 0 >>> Need to set to 15 days +# DB2_Backup.sh # +# Things to do: +# Recovery history retention (days) (REC_HIS_RETENTN) = 0 >>> Need to set to 15 days # # The cron job on the cluster will supply the needed parameters for this script # If an on demand backup (Full) is required, the DB2_Backup.sh script can be called with the following parameters @@ -18,287 +15,319 @@ set -x # ######################################################### - -. /mnt/backup/bin/.PROPS +# -- Script Usage +if [[ $# -eq 4 ]]; then + typeset -l instance=$1 dbname=$2 + typeset -u INSTANCE=$1 DBNAME=$2 + typeset -i NUM_BACKUPS_TO_KEEP=$3 + typeset -l BKUP_TYPE=$4 -#### COSBACKUPBUCKET=masms-pp-1-cos-backup-pseg-test-pr-wdc -#### For testing -TESTMSG="######## TESTING ###########" -echo ${COSBACKUPBUCKET} -COSBACKUPBUCKET=${CONTAINER} -#### TESTING URL - -Server=`hostname` -instance=`whoami` -FULLIMAGE= -DATETIME=`date +%Y-%m-%d_%H%M%S`; -BACKUP_BASE=/mnt/backup -BACKUP_LOGS=${BACKUP_BASE}/${DB2INSTANCE} -BACKUP_PATH=DB2REMOTE://AWSCOS/${COSBACKUPBUCKET}/backups-manage/${HOSTNAME} -ARCBKP_PATH=${BACKUP_PATH}/${DATETIME} -CLEAN_LOG=${BACKUP_PATH}/.cleanup.log -instance_home=`/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${instance}" | awk -F ',' '{print $5}'| cut -d/ -f 1,2,3,4,5` -IP=`/sbin/ifconfig | grep "inet" | grep broadcast | awk '{print $2}'` -BACK_LOG=$instance_home/bin/.$2_BackupLOG.out -Maillog="/tmp/.backup_maillog" - - -SLACK_NOTIFY() -{ - des="$instance - Backup - $Server ${database} -- DATABASE Backup issues" - echo "${CUSTNAME} - $instance - Backup - $Server $IP ${database} DATABASE Backup issues" > .Maillive.log - echo "############################" >> .Maillive.log - cat ${BACK_LOG} >> .Maillive.log - longdes=`cat .Maillive.log | sed 's/"//g' | sed "s/'//g"` - slackdes=" BACKUP FAILED for ${Server} - ${CONTAINER}} ...Please investigate " - -### Send Failure notification to a slack channel ## -cat << ! >.curl_$database.sh - curl -X POST -H 'Content-type: application/json' --data '{"text":"$slackdes"}' ${SLACKURL} -! -if [[ -n "${SLACKURL}" ]]; then - /bin/bash .curl_$database.sh > .curl_$database.out 2>&1 +else + print $(tput smso) "Usage! $0 instance database number_of_backups_to_keep" $(tput rmso) + exit 1 fi - ##### Create ICD Incident #### - ####### If Backup fails ### - des="${CUSTNAME} - ${instance} - Backup - ${HOSTNAME} ${database} - MASMS -- Backup Failed" - echo "############################" >> .Maillive.log - longdes=`cat .Maillive.log | sed 's/"//g' | sed "s/'//g"` - longdes=`echo "
${longdes} "`
- ICD_URL="https://servicedesk.mro.com"
- if ! curl -k -s --connect-timeout 3 ${ICD_URL} >/dev/null; then
- ICD_URL="https://servicedesk.cds.mro.com"
- fi
-cat << ! >.curl_${database}_ICD.sh
- curl --insecure --location --request POST "${ICD_URL}/maximo_mif/oslc/os/hsincident?lean=1" \
- --header "Authorization: Basic ${ICD_AUTH_KEY}" \
- --header 'Content-Type: application/json' \
- --data '{
- "description":"$des",
- "reportedpriority":4,
- "internalpriority":4,
- "reportedby":"DB2",
- "affectedperson":"CTGINST1",
- "description_longdescription":"$longdes",
- "siteid":"001",
- "classstructureid":"1341",
- "classificationid":"IN-DBPERF",
- "hshost":"{servicedesk-pdb-sjc03-2.cds.mro.com:0:50}",
- "hstype":"BACKUP"
- }'
-!
-if [[ -n "${ICD_AUTH_KEY}" ]]; then
- /bin/bash .curl_${database}_ICD.sh > .curl_${database}_ICD.out 2>&1
+# -- Standard Parameters
+HOSTNAME=$(hostname)
+HOSTIP=$(/sbin/ifconfig | grep "inet" | grep broadcast | awk '{print $2}')
+DATETIME=$(date +'%Y%m%d_%H%M%S');
+DBINSTANCE=$(whoami);
+NAMESPACE=$(hostname -A | awk -F '.' '{print $3}')
+INSTANCE_HOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${DBINSTANCE}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//' )
+CUSTNAME=$(hostname | sed 's/c-db2wh-//; s/c-db2u-//; s/c-//; s/-db2u-0//; s/db2u/-/; ' | tr '[:lower:]' '[:upper:]' )
+SCRIPT_DIR=${INSTANCE_HOME}/bin
+ICD_LOG=${SCRIPT_DIR}/.Maillive.log
+Maillog="/tmp/.backup_maillog"
+
+# -- Source DB2 Profile
+
+if [[ ! -f "${INSTANCE_HOME}/sqllib/db2profile" ]]; then
+ echo "ERROR - ${INSTANCE_HOME}/sqllib/db2profile not found"
+ EXIT_STATUS=1
+else
+ . ${INSTANCE_HOME}/sqllib/db2profile
fi
-}
+# -- Debug Mode
+ set -x; # Uncomment to debug this shell script
+# set -n; # Uncomment to check your syntax, without execution.
+# -- Source the PROPS file
+. /mnt/backup/bin/.PROPS
+
+# -- Backup Parameters
+COSBACKUPBUCKET="${CONTAINER}"
+BUCKET_ALIAS=$(db2 list storage access | grep ${COSBACKUPBUCKET} -B4 | grep ALIAS | awk -F '=' '{print $2}')
+BACKUP_BASE="/mnt/backup"
+BACKUP_LOGS=${SCRIPT_DIR}/${DBINSTANCE}
+BACKUP_PATH=DB2REMOTE://${BUCKET_ALIAS}/${COSBACKUPBUCKET}/backups-${APPENV}/${HOSTNAME}
+ARCBKP_PATH=${BACKUP_LOGS}/${DATETIME}
+CLEAN_LOG=${BACKUP_LOGS}/.cleanup.LOG
+BACK_LOG=${SCRIPT_DIR}/.${DBNAME}_BackupLOG.out
+HSTYPE="Backup"
-if [ ! -f "$instance_home/sqllib/db2profile" ]
-then
- echo "ERROR - $instance_home/sqllib/db2profile not found"
- EXIT_STATUS=1
+# -- Valid only for MAS-CP4D Customers
+if (( ${CUSTNAME} )) ; then
+ CUSTNAME=$(echo ${CONTAINER} | awk -F '-backup-' '{print $2}' | awk -F '-pr-' '{print $1}' | tr '[:lower:]' '[:upper:]')
+fi
+
+# -- Database Environment
+if [[ ${BUCKET_ALIAS} == "IBMCOS" ]]; then
+ DBENV="MASMS"
else
- . $instance_home/sqllib/db2profile
+ DBENV="MASSaaS"
fi
+# -- For mapping Hostname with Servicedesk
-if [ -f $Maillog ]
-then
- rm $Maillog
+NS=$( echo ${NAMESPACE} | sed 's/mas-//; s/-core//; s/-manage//; s/-facilities//; s/-db2u//;' );
+if [[ "$NAMESPACE" =~ "manage" ]] ; then
+ HSHOSTS="main.manage.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "core" ]]; then
+ HSHOSTS="main.home.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "monitor" ]]; then
+ HSHOSTS="main.monitor.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "facilities" ]]; then
+ HSHOSTS="main.facilities.${NS}.suite"
fi
-echo "COS bucket = ${COSBACKUPBUCKET} " > $BACK_LOG
-echo "BACKUP Start time : ${DATETIME}" >> $BACK_LOG
-echo " " >> $BACK_LOG
-echo ${HOSTNAME} >> $BACK_LOG
-echo " " >> $BACK_LOG
-echo " " >> $BACK_LOG
-
-if [[ $# -eq 4 ]]
-then
- typeset -l instance=$1 database=$2
- typeset -u INSTANCE=$1 DATABASE=$2
- typeset -i num_backups_to_keep=$3
- typeset -l BKUP_TYPE=$4
-
- ##### until the db is bounced to pickup the TRACKMOD parm..We have to hardcode a FULL backup
- #####BKUP_TYPE=full
- ### BKUP_TYPE = full or inc ####
-else
- print `tput smso` "Usage! $0 instance database number_of_backups_to_keep" `tput rmso`
- exit 1
+# -- Function to send Slack notification
+
+SLACK_NOTIFY() {
+
+ SLACKDES="$1"
+ # -- Send Failure notification to a slack channel
+ cat << ! >.curl_${DBNAME}.sh
+ curl -X POST -H 'Content-type: application/json' --data '{"text":"${SLACKDES}"}' ${SLACKURL}
+!
+ /bin/bash .curl_${DBNAME}.sh > .curl_${DBNAME}.out 2>&1
+
+}
+
+# -- Create ICD Incident , If Backup fails
+
+CREATE_ICD() {
+ HTYPE=$(echo ${HSTYPE} | tr '[:lower:]' '[:upper:]')
+ DES="$1"
+ LONGDES=$(cat ${ICD_LOG} | sed 's/"//g' | sed "s/'//g")
+ LONGDES=$(echo "${LONGDES}")
+
+ # -- Verify the ICD Status
+ if curl -k -s --connect-timeout 3 ${ICD_URL_SAAS} >/dev/null; then
+ CURL_REQ="--request POST --url ${ICD_URL_SAAS} "
+ AUTH_REQ="apikey: ${ICD_API_KEY}"
+ fi
+
+ # -- Generate Curl Syntax to push to ICD
+ cat << ! >.curl_${DBNAME}_ICD.sh
+ curl ${CURL_REQ} \
+ --header '${AUTH_REQ}' \
+ --header 'Content-Type: application/json' \
+ --data '{
+ "description":"${DES}",
+ "reportedpriority":4,
+ "internalpriority":4,
+ "reportedby":"DB2",
+ "affectedperson":"${DBENV}",
+ "ownergroup":"HSDBA",
+ "description_longdescription":"${LONGDES}",
+ "siteid":"001",
+ "classstructureid":"1341",
+ "classificationid":"IN-DBPERF",
+ "hshost":"${HSHOSTS}",
+ "hstype":"${HTYPE}"
+ }'
+!
+ /bin/bash .curl_${DBNAME}_ICD.sh > .curl_${DBNAME}_ICD.out 2>&1
+
+}
+
+# -- Delete old log file
+if [[ -f $Maillog ]]; then
+ rm $Maillog
+fi
+
+# -- Create the backup log directory if it doesnt exists
+if [[ ! -d ${BACKUP_LOGS} ]]; then
+ mkdir -m 755 ${BACKUP_LOGS}
fi
-
-### Check for the existance of /home/ctginst1/sqllib/db2dump/libdb2compr.so...if it exists, delete it
-COMPRESS_LOC=$instance_home/sqllib/db2dump/libdb2compr.so
-if [[ -f ${COMPRESS_LOC} ]]
-then
- rm ${COMPRESS_LOC}
+
+# -- Setting backup type
+if [[ ${BKUP_TYPE} == 'full' ]]; then
+ BKPTYPE="FULL"
+else
+ BKPTYPE="DIFF"
fi
-
-### Check to see if the database is Running
-ps -ef | grep db2sys | grep -v grep > /dev/null 2>&1
-if [ $? -eq 1 ]; then
- echo "Database is not active "
- echo "$Server,Database Not Active,BACKUP Not Run" > $instance_home/bin/LASTbkupRUN
-
- ### Send error alert
- SLACK_NOTIFY
- exit
+
+# -- Script Execution starts from here
+
+ln=80
+printf "%${ln}s\n" | tr ' ' '-' | tee ${BACK_LOG};
+echo -e "\nBackup Start Time \t :: ${DATETIME}" | tee -a ${BACK_LOG};
+echo -e "COS Bucket \t\t :: ${COSBACKUPBUCKET}" | tee -a ${BACK_LOG};
+echo -e "\nHostname \t\t :: ${HOSTNAME}" | tee -a ${BACK_LOG};
+echo -e "Namespace \t\t :: ${NAMESPACE}" | tee -a ${BACK_LOG};
+echo -e "HostIP \t\t\t :: ${HOSTIP}" | tee -a ${BACK_LOG};
+printf "\n%${ln}s\n" | tr ' ' '-' | tee -a ${BACK_LOG};
+
+# -- Check for the existance of /home/ctginst1/sqllib/db2dump/libdb2compr.so...if it exists, delete it
+COMPRESS_LOC=${INSTANCE_HOME}/sqllib/db2dump/libdb2compr.so
+if [[ -f ${COMPRESS_LOC} ]]; then
+ rm ${COMPRESS_LOC}
fi
-
-### Check to see if the database is HADR
-db2pd -hadr -db ${database} | awk -F= '/HADR_ROLE/ {print $2}' | grep STANDBY > /dev/null 2>&1
-if [ $? -eq 0 ]; then
- echo "This is a HADR database"
- echo "Backup successful. The timestamp for this backup image is : HADR_DB"
- echo "$Server,HADR,NO BACKUPS" > $instance_home/bin/LASTbkupRUN
- exit 0
+
+# -- Check to see if the Instance is up and Running
+ps -ef | grep db2sysc | grep -v grep > /dev/null 2>&1
+if [[ $? -eq 1 ]]; then
+ cat ${BACK_LOG} > ${ICD_LOG}
+ echo "Instance is not Active, Backup cannot Initiate !!!" | tee -a ${INSTANCE_HOME}/bin/LASTbkupRUN ${ICD_LOG} >/dev/null
+
+ SLACKDES="${CUSTNAME} - ${DBENV} - ${HOSTNAME}, Instance is not Active, Backup cannot Initiate !! "
+ DES="${CUSTNAME} - ${DBENV} - ${DBNAME} - ${HOSTNAME} -- Instance is not Active, Backup cannot Initiate !! "
+
+ # -- Send error notification to Slack
+ SLACK_NOTIFY "${SLACKDES}"
+
+ # -- Create ICD ticket if fails
+ CREATE_ICD "${DES}"
+
+ # -- End the script execution
+ exit
fi
-
-### Create the backup directory if it doesnt already exist
-if [[ -d $BACKUP_LOGS ]]
-then :
- else mkdir -m 755 ${BACKUP_LOGS}
+
+# -- Verify whether Database is Standby
+db2pd -hadr -db ${DBNAME} | awk -F= '/HADR_ROLE/ {print $2}' | grep STANDBY > /dev/null 2>&1
+if [[ $? -eq 0 ]]; then
+ echo "This is a HADR Database" | tee -a ${ICD_LOG}
+ echo "Backup successful. The timestamp for this backup image is : HADR_DB" | tee -a ${ICD_LOG}
+ echo "${HOSTNAME}, HADR, NO BACKUPS" > ${INSTANCE_HOME}/bin/LASTbkupRUN
+ exit 0
fi
-
-echo "BACKUP Start time : ${DATETIME}"
-echo " "
-echo $Server
-echo " "
-echo " "
-
-db2 -v archive log for db $database | tee -a $BACK_LOG
-sleep 30
-
-if [[ $num_backups_to_keep -gt 0 ]]
-then
- ### Backup database
- if [ ${BKUP_TYPE} = 'full' ] ; then
- db2 -v backup db $database online to $BACKUP_PATH compress UTIL_IMPACT_PRIORITY 50 include logs without prompting | tee -a $BACK_LOG
- else
- db2 -v backup db $database online INCREMENTAL DELTA to $BACKUP_PATH compress UTIL_IMPACT_PRIORITY 50 include logs without prompting | tee -a $BACK_LOG
- fi
- grep -Fq "Backup successful." $BACK_LOG
- if [ $? = 0 ]; then
- Backup_timestamp=`grep timestamp $BACK_LOG | cut -d: -f2`
-
- ### Need to find all the files associate with the backup ##
- ###
- ###
- ### Need to change this to the db2RemStgManager command to get a list of all backup images just created
- ###
- ###
-
- # fi
- else
- SLACK_NOTIFY
- #exit
- fi
+
+# -- Archive the logs for Database
+db2 -v "ARCHIVE LOG FOR DB ${DBNAME}" | tee -a ${BACK_LOG}
+sleep 20
+
+# -- Starting backup for the database
+if [[ ${NUM_BACKUPS_TO_KEEP} -gt 0 ]]; then
+
+ if [[ ${BKUP_TYPE} = 'full' ]]; then
+ db2 -v "BACKUP DB ${DBNAME} ONLINE TO ${BACKUP_PATH} COMPRESS UTIL_IMPACT_PRIORITY 50 INCLUDE LOGS WITHOUT PROMPTING" | tee -a ${BACK_LOG}
+ else
+ db2 -v "BACKUP DB ${DBNAME} ONLINE INCREMENTAL DELTA TO ${BACKUP_PATH} COMPRESS UTIL_IMPACT_PRIORITY 50 INCLUDE LOGS WITHOUT PROMPTING" | tee -a ${BACK_LOG}
+ fi
+
+ grep -Fq "Backup successful." ${BACK_LOG}
+ if [[ $? -ne 0 ]]; then
+ #echo "${CUSTNAME} - ${DBENV} - ${HOSTNAME} - ${BKPTYPE} ${HSTYPE} Failed !!!" > ${ICD_LOG}
+ cat ${BACK_LOG} > ${ICD_LOG}
+
+ SLACKDES="${CUSTNAME} - ${DBENV} - ${HOSTNAME} -- ${BKPTYPE} ${HSTYPE} Failed . . . Please investigate ! ! ! "
+ DES="${CUSTNAME} - ${DBENV} - ${DBNAME} - ${HOSTNAME} -- ${BKPTYPE} ${HSTYPE} Failed !"
+
+ # -- Send error notification to Slack
+ SLACK_NOTIFY "${SLACKDES}"
+ # -- Create ICD ticket if fails
+ CREATE_ICD "${DES}"
+ fi
fi
-######## Copy keystore to COS
-set -x
+# -- Copy keystore to COS
SOURCE1=/mnt/blumeta0/db2/keystore/keystore.p12
SOURCE2=/mnt/blumeta0/db2/keystore/keystore.sth
-TARGET1=backups-manage/${HOSTNAME}/KEYSTORE/keystore.p12
-TARGET2=backups-manage/${HOSTNAME}/KEYSTORE/keystore.sth
-
-DB2V=`db2level | grep Inform | awk '{print $5}' | sed 's/",//'`
-if [ ${DB2V} = "v11.5.7.0" ]
-then
- db2RemStgManager S3 put server=${SERVER} auth1=${PARM1} auth2=${PARM2} container=${CONTAINER} source=${SOURCE1} target=${TARGET1}
- db2RemStgManager S3 put server=${SERVER} auth1=${PARM1} auth2=${PARM2} container=${CONTAINER} source=${SOURCE2} target=${TARGET2}
+TARGET1=backups-${APPENV}/${HOSTNAME}/KEYSTORE/keystore.p12
+TARGET2=backups-${APPENV}/${HOSTNAME}/KEYSTORE/keystore.sth
+
+DB2V=$(db2level | grep Inform | awk '{print $5}' | sed 's/",//')
+if [[ ${DB2V} == "v11.5.7.0" ]]; then
+
+ db2RemStgManager S3 put server=${HOSTNAME} auth1=${PARM1} auth2=${PARM2} container=${CONTAINER} source=${SOURCE1} target=${TARGET1}
+ db2RemStgManager S3 put server=${HOSTNAME} auth1=${PARM1} auth2=${PARM2} container=${CONTAINER} source=${SOURCE2} target=${TARGET2}
+
else
- db2RemStgManager ALIAS PUT source=${SOURCE1} target=DB2REMOTE://AWSCOS//${TARGET1}
- db2RemStgManager ALIAS PUT source=${SOURCE2} target=DB2REMOTE://AWSCOS//${TARGET2}
+ db2RemStgManager ALIAS PUT source=${SOURCE1} target=DB2REMOTE://${BUCKET_ALIAS}//${TARGET1}
+ db2RemStgManager ALIAS PUT source=${SOURCE2} target=DB2REMOTE://${BUCKET_ALIAS}//${TARGET2}
fi
-# exclude files that arent backups, e.g. backhist listing.
-typeset -i no_backups=`./CheckCOS.sh | grep -i ${database}| cut -d/ -f3| grep 001 |wc -l`
-echo " number of backups $no_backups"
-### Prune the history file, if and only if the last backup succeeded.
-### Remove archive transaction logs for expired backups, if there are a requisite number of successful backups.
-### Remove expired backups in step.
-
-if [[ $num_backups_to_keep -gt 0 && $no_backups -ge $num_backups_to_keep ]]
-then
- db2 -v connect to $database | tee -a $BACK_LOG
-
- timestmp=$(db2 -x "select coalesce(max(start), 17890713235959) from \
- (select bigint(start_time) - 1 as start, \
- row_number() over(order by start_time desc) as backup \
- from sysibmadm.db_history \
- where operation = 'B' \
- and objecttype = 'D' \
- and devicetype = 'D' \
- and sqlcode is null \
- and sqlwarn is null \
- ) as zzz \
- where backup = $num_backups_to_keep" )
-
- db2 -v prune history $timestmp WITH FORCE OPTION and delete | tee -a $BACK_LOG
-
- ### loop until the recovery history file is stable and then report it
- RC=999
- typeset -i no_loops=0
- while [[ $RC -gt 0 ]]
- do
- db2 -v list history backup since $timestmp for $database > ${BACKUP_LOGS}/backhist
- RC=$?
- print RC for list history was $RC
- cat ${BACKUP_LOGS}/backhist >> $BACK_LOG
- if [[ $no_loops -gt 720 ]]
- then
- ### then youve been waiting an hour
- print $0 "Im tired of waiting for the recovery history file to stabilise. Im giving up"
- break
- else
- sleep 5
- let no_loops=no_loops+1
- fi
- done
- echo "Content of backhist file:"
- cat ${BACKUP_LOGS}/backhist
- db2 -v commit | tee -a $BACK_LOG
-
- db2 -v connect reset | tee -a $BACK_LOG
- db2 -v terminate | tee -a $BACK_LOG
-fi
+# -- Exclude files that arent backups, e.g. backhist listing.
+
+typeset -i NO_BACKUPS=$(~/bin/CheckCOS.sh | grep -i ${DBNAME} | cut -d/ -f3 | grep 001 | wc -l)
+echo "Number of Backups in the bucket :: ${NO_BACKUPS}" | tee -a ${BACK_LOG}
+
+# -- Prune the history file, if and only if the last backup succeeded.
+
+if [[ ${NUM_BACKUPS_TO_KEEP} -gt 0 && ${NO_BACKUPS} -ge ${NUM_BACKUPS_TO_KEEP} ]]; then
+ db2 -v CONNECT TO ${DBNAME} > /dev/null 2>&1
+
+ TIMESTMP=$(db2 -x "select coalesce(max(start), 17890713235959) from \
+ (select bigint(start_time) - 1 as start, \
+ row_number() over(order by start_time desc) as backup \
+ from sysibmadm.db_history \
+ where operation = 'B' \
+ and objecttype = 'D' \
+ and devicetype = 'D' \
+ and sqlcode is null \
+ and sqlwarn is null \
+ ) as zzz \
+ where backup = ${NUM_BACKUPS_TO_KEEP}" | tr -d ' ' )
+
+ db2 -v "PRUNE HISTORY ${TIMESTMP} WITH FORCE OPTION AND DELETE" | tee -a ${BACK_LOG}
+
+ # -- Loop until the recovery history file is stable and then report it
+ RC=999
+ typeset -i no_loops=0
+ while [[ $RC -gt 0 ]]
+ do
+ db2 -v list history backup since ${TIMESTMP} for ${DBNAME} > ${BACKUP_LOGS}/backhist
+ RC=$?
+ #print RC for list history was $RC
+ #cat ${BACKUP_LOGS}/backhist >> ${BACK_LOG}
+ if [[ $no_loops -gt 720 ]]; then
+ # -- then youve been waiting an hour
+ print $0 "Im tired of waiting for the recovery history file to stabilise. Im giving up" | tee -a ${BACK_LOG}
+ break
+ else
+ sleep 5
+ let no_loops=no_loops+1
+ fi
+ done
+
+ #echo "Content of backhist file: "
+ #cat ${BACKUP_LOGS}/backhist
+ db2 -v commit > /dev/null 2>&1
+ db2 -v connect reset > /dev/null 2>&1
+ db2 -v terminate > /dev/null 2>&1
-sleep 30
-
-if [[ $num_backups_to_keep -eq 0 ]]
-then
- db2 -v connect to $database | tee -a $BACK_LOG
- db2 -x "select location \
- from sysibmadm.db_history \
- where operation = 'X' \
- and operationtype = '1' " > $BACKUP_LOGS/archivelog.zaplist
- for log in `cat $BACKUP_LOGS/archivelog.zaplist`
- do
- printf "`date +'%F %T'`\t%-110s\t%12d k\n" "${log}" "`du -sk ${log} | awk '{print $1}'`" >> ${CLEAN_LOG}
- done
- ### prune history in step
- timestmp=$(db2 -x "select max(start_time) from sysibmadm.db_history where operation = 'X' and operationtype = '1'")
- db2 -v prune history $timestmp WITH FORCE OPTION and delete | tee -a $BACK_LOG
- wait
- db2 -v commit | tee -a $BACK_LOG
- db2 -v connect reset | tee -a $BACK_LOG
- db2 -v terminate | tee -a $BACK_LOG
fi
-
-DATETIME=`date +%Y-%m-%d_%H%M%S`;
-echo "BACKUP End time : ${DATETIME}" >> $BACK_LOG
-
-if [[ ${BKUP_STATUS} -gt 0 ]]
-then
- ### Send error alert
- SLACK_NOTIFY
+
+sleep 20
+
+# -- Prune the archive logs and archive log history file
+if [[ ${NUM_BACKUPS_TO_KEEP} -eq 0 ]]; then
+ db2 -v connect to ${DBNAME} > /dev/null 2>&1
+ db2 -x "select location from sysibmadm.db_history where operation = 'X' and operationtype = '1' " > ${BACKUP_LOGS}/archivelog.zaplist
+
+ for LOG in $(cat ${BACKUP_LOGS}/archivelog.zaplist)
+ do
+ printf "$(date +'%F %T')\t%-110s\t%12d k\n" "${LOG}" "$(du -sk ${LOG} | awk '{print $1}')" >> ${CLEAN_LOG}
+ done
+
+ # -- prune history in step
+ TIMESTMP=$(db2 -x "select max(start_time) from sysibmadm.db_history where operation = 'X' and operationtype = '1'" | tr -d ' ')
+ db2 -v PRUNE HISTORY ${TIMESTMP} WITH FORCE OPTION AND DELETE | tee -a ${BACK_LOG}
+ wait
+ db2 -v commit > /dev/null 2>&1
+ db2 -v connect reset > /dev/null 2>&1
+ db2 -v terminate > /dev/null 2>&1
+
fi
-### Copy the current backup log to the Backup log history file
-cat $BACK_LOG >> ${BACKUP_LOGS}/.BackupLOG
+
+DATETIME=$(date +%Y-%m-%d_%H%M%S);
+echo "BACKUP End time :: ${DATETIME}" >> ${BACK_LOG}
+
+# -- Copy the current backup LOG to the Backup LOG history file
+cat ${BACK_LOG} >> ${BACKUP_LOGS}/.BackupLOG
+
+# -- END OF SCRIPT
\ No newline at end of file
diff --git a/instance-applications/120-ibm-db2u-database/files/RUN_OnDemandFULL_BKP.sh b/instance-applications/120-ibm-db2u-database/files/RUN_OnDemandFULL_BKP.sh
index f8b97fd73..c1ca7e223 100755
--- a/instance-applications/120-ibm-db2u-database/files/RUN_OnDemandFULL_BKP.sh
+++ b/instance-applications/120-ibm-db2u-database/files/RUN_OnDemandFULL_BKP.sh
@@ -1,103 +1,145 @@
#!/bin/bash
-#set -x
-
#########################################################
-# Run_Backup.sh
-# Run_Backup.sh will be called from the Cron Jobs
+# RUN_OnDemandFULL_BKP.sh
+# RUN_OnDemandFULL_BKP.sh will be called by OnDemand Jobs
# This script will list all local databases running in the instance on a node. It will call the
# DB2_Backup.sh script to run a backup for each running database.
# Variables are set at the top of the DB2_Backup.sh script to determine if a full backup needs to be run
# based on the day of the week. Currently, Saturday is when the full backup runs, incremental backups run
# every all other days.
#
-# Variables to be set
+# Variables to be set
# SLACKURL = The channel were notifications are send
-# BACKUP_SCRIPT = The backup script that Run_Backup.sh calls
-# DAYOFFULL = Defines the day of the week that the full backup will on on (must match the same format as the output from `date`)
+# BACKUP_SCRIPT = The backup script that RUN_OnDemandFULL_BKP.sh calls
+# DAYOFFULL = Defines the day of the week that the full backup will on on (must match the same format as the output from $(date))
# NUMOFBKUPTOKEEP = This defines the number of days to keep a backup image on local disk
#
-# Variables determined by the environment
-# BACKUPTYPE = Is determined from the `date` command and the DAYOFFULL value
+# Variables determined by the environment
+# BACKUPTYPE = Is determined from the $(date) command and the DAYOFFULL value
# DB2INSTANCE = Pulled from the environment
# HOSTNAME
-# DBNAME = Pulled from the `db2 list db directory`
+# DBNAME = Pulled from the $(db2 list db directory)
#
-# Backup command issued
+# Backup command issued
# ./DB2_Backup.sh ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BACKUPTYPE} 2>>.BackupLOG.stderr > .BackupLOG.out
#########################################################
-. /mnt/backup/bin/.PROPS
+# -- Standard Parameters
+HOSTNAME=$(hostname)
+NAMESPACE=$(hostname -A | awk -F '.' '{print $3}')
+DBINSTANCE=$(whoami);
+DATETIME=$(date +'%F_%T');
+INSTANCE_HOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${DBINSTANCE}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//' )
+HOSTIP=$(/sbin/ifconfig | grep "inet" | grep broadcast | awk '{print $2}')
+CUSTNAME=$(hostname | sed 's/c-db2wh-//; s/c-db2u-//; s/c-//; s/-db2u-0//; s/db2u/-/; ' | tr '[:lower:]' '[:upper:]' )
+SCRIPT_DIR=${INSTANCE_HOME}/bin
+ICD_LOG=${SCRIPT_DIR}/.Maillive.log
-DBINSTANCE=`whoami`
-HOSTNAME=`hostname`
-BACKUP_DIR=${HOME}/bin
-BACKUP_SCRIPT=DB2_Backup.sh
-DATETIME=`date +%Y-%m-%d_%H%M%S`;
+# -- Verify and source db2profile
-if [ ! -f "${HOME}/sqllib/db2profile" ]
-then
- echo "ERROR - ${HOME}/sqllib/db2profile not found"
+if [[ ! -f "${INSTANCE_HOME}/sqllib/db2profile" ]]; then
+ echo "ERROR - ${INSTANCE_HOME}/sqllib/db2profile not found"
EXIT_STATUS=1
else
- . ${HOME}/sqllib/db2profile
+ . ${INSTANCE_HOME}/sqllib/db2profile
fi
+# -- Source the PROPS File
+. /mnt/backup/bin/.PROPS
+# -- Debug Mode
+# set -x; # Uncomment to debug this shell script
+# set -n; # Uncomment to check your syntax, without execution.
-DOW=`date | awk '{print $1}'`
+# -- Backup parameters
+BACKUPTYPE=full
+BACKUP_SCRIPT="${SCRIPT_DIR}/DB2_Backup.sh"
+BUCKET_ALIAS=$(db2 list storage access | grep ${CONTAINER} -B4 | grep ALIAS | awk -F '=' '{print $2}')
+HSTYPE="Backup"
-# if [ ${DOW} = ${DAYOFFULL} ] ; then
- BACKUPTYPE=full
-# else
-# BACKUPTYPE=inc
-# fi
+# -- Valid only for MAS-CP4D customers
+if (( ${CUSTNAME} )) ; then
+ CUSTNAME=$(echo ${CONTAINER} | awk -F '-backup-' '{print $2}' | awk -F '-pr-' '{print $1}' | tr '[:lower:]' '[:upper:]')
+fi
-DBS=`db2 list db directory | grep -B5 "Indirect" | grep "Database name" | awk '{ print $4 }'`
-for DBNAME in ${DBS}
-do
- cd ${BACKUP_DIR}
- ./DB2_Backup.sh ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BACKUPTYPE} 2>.BackupLOG.stderr > .BackupLOG.out
+# -- Database Environment
+if [[ ${BUCKET_ALIAS} == "IBMCOS" ]]; then
+ DBENV="MASMS"
+else
+ DBENV="MASSaaS"
+fi
+
+# -- For mapping Hostname with Servicedesk
+
+NS=$( echo ${NAMESPACE} | sed 's/mas-//; s/-core//; s/-manage//; s/-facilities//; s/-db2u//;' );
+if [[ "$NAMESPACE" =~ "manage" ]] ; then
+ HSHOSTS="main.manage.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "core" ]]; then
+ HSHOSTS="main.home.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "monitor" ]]; then
+ HSHOSTS="main.monitor.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "facilities" ]]; then
+ HSHOSTS="main.facilities.${NS}.suite"
+fi
- RC=$?
- if [ ${RC} -ne 0 ]; then
+# -- Create ICD Incident , If Backup fails
- longdes="Failure to start the Backup job ${DATETIME} CUST=${CUSTNAME} ${RC}"
- ## Send Failure notification to a slack channel ##
- cat << ! >.curl_${DBNAME}_RUN.sh
- curl -X POST -H 'Content-type: application/json' --data '{"text":"$longdes"}' $SLACKURL
+CREATE_ICD() {
+ HTYPE=$(echo ${HSTYPE} | tr '[:lower:]' '[:upper:]')
+ DES="$1"
+ LONGDES=$(cat ${ICD_LOG} | sed 's/"//g' | sed "s/'//g")
+ LONGDES=$(echo "${LONGDES} ")
+
+ # -- Verify the ICD Status
+ if curl -k -s --connect-timeout 3 ${ICD_URL_SAAS} >/dev/null; then
+ CURL_REQ="--request POST --url ${ICD_URL_SAAS} "
+ AUTH_REQ="apikey: ${ICD_API_KEY}"
+ fi
+
+ # -- Generate Curl Syntax to push to ICD
+ cat << ! >.curl_${DBNAME}_ICD.sh
+ curl ${CURL_REQ} \
+ --header '${AUTH_REQ}' \
+ --header 'Content-Type: application/json' \
+ --data '{
+ "description":"${DES}",
+ "reportedpriority":4,
+ "internalpriority":4,
+ "reportedby":"DB2",
+ "affectedperson":"${DBENV}",
+ "ownergroup":"HSDBA",
+ "description_longdescription":"${LONGDES}",
+ "siteid":"001",
+ "classstructureid":"1341",
+ "classificationid":"IN-DBPERF",
+ "hshost":"${HSHOSTS}",
+ "hstype":"${HTYPE}"
+ }'
!
-/bin/bash .curl_${DBNAME}_RUN.sh > .curl_${DBNAME}_RUN.out 2>&1
-
- ##### Create ICD Incident ####
- ####### If Backup fails ###
- des="${DBINSTANCE} - Backup - ${HOSTNAME} ${DBNAME} ${CUSTNAME} - MASMS -- Backup Failed"
- echo "TESTING $instance - Backup - $ ${DBNAME} - Backup Failed" > .Maillive.log
- echo "############################" >> .Maillive.log
- #cat $BACK_LOG >> .Maillive.log
- longdes=`cat .Maillive.log | sed 's/"//g' | sed "s/'//g"`
- ICD_URL="https://servicedesk.mro.com"
- if ! curl -k -s --connect-timeout 3 ${ICD_URL} >/dev/null; then
- ICD_URL="https://servicedesk.cds.mro.com"
- fi
-
-cat << ! >.curl_${DBNAME}_ICD.sh
- curl --insecure --location --request POST "${ICD_URL}/maximo_mif/oslc/os/hsincident?lean=1" \
- --header "Authorization: Basic ${ICD_AUTH_KEY}" \
- --header 'Content-Type: application/json' \
- --data '{
- "description":"$des",
- "reportedpriority":4,
- "internalpriority":4,
- "reportedby":"DB2",
- "affectedperson":"CTGINST1",
- "description_longdescription":"$longdes",
- "siteid":"001",
- "classstructureid":"1341",
- "classificationid":"IN-DBPERF",
- "hshost":"{servicedesk-pdb-sjc03-2.cds.mro.com:0:50}",
- "hstype":"BACKUP"
- }'
+ /bin/bash .curl_${DBNAME}_ICD.sh > .curl_${DBNAME}_ICD.out 2>&1
+
+}
+
+# -- Loop through the available databases in the instance
+
+DBS=$(db2 list db directory | grep -B5 "Indirect" | grep "Database name" | awk '{ print $4 }')
+for DBNAME in ${DBS}
+do
+ cd ${SCRIPT_DIR}
+ ${BACKUP_SCRIPT} ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BACKUPTYPE} 2>.BackupLOG.stderr > .BackupLOG.out
+ RC=$?
+ if [[ ${RC} -ne 0 ]]; then
+
+ LONGDES="Failure to start the Backup job ${DATETIME} CUST=${CUSTNAME} - ${RC}"
+ # -- Send Failure notification to a slack channel
+ cat << ! >.curl_${DBNAME}_RUN.sh
+ curl -X POST -H 'Content-type: application/json' --data '{"text":"$LONGDES"}' ${SLACKURL}
!
-#####/bin/bash .curl_${DBNAME}_ICD.sh > .curl_${DBNAME}_ICD.out 2>&1
+ /bin/bash .curl_${DBNAME}_RUN.sh > .curl_${DBNAME}_RUN.out 2>&1
-fi
+ # -- Create ICD ticket if fails
+ DES="${CUSTNAME} - ${DBENV} - ${DBNAME} - ${HOSTNAME} -- Failed to Start Backup!! "
+ CREATE_ICD "${DES}"
+ fi
done
+
+# -- END OF SCRIPT
\ No newline at end of file
diff --git a/instance-applications/120-ibm-db2u-database/files/Run_Backup.sh b/instance-applications/120-ibm-db2u-database/files/Run_Backup.sh
index 72f29f0c8..eaf65f317 100755
--- a/instance-applications/120-ibm-db2u-database/files/Run_Backup.sh
+++ b/instance-applications/120-ibm-db2u-database/files/Run_Backup.sh
@@ -1,8 +1,6 @@
#!/bin/bash
-#set -x
-
#########################################################
-# Run_Backup.sh
+# Run_Backup.sh
# Run_Backup.sh will be called from the Cron Jobs
# This script will list all local databases running in the instance on a node. It will call the
# DB2_Backup.sh script to run a backup for each running database.
@@ -10,100 +8,161 @@
# based on the day of the week. Currently, Saturday is when the full backup runs, incremental backups run
# every all other days.
#
-# Variables to be set
+# Variables to be set
# SLACKURL = The channel were notifications are send
# BACKUP_SCRIPT = The backup script that Run_Backup.sh calls
-# DAYOFFULL = Defines the day of the week that the full backup will on on (must match the same format as the output from `date`)
+# DAYOFFULL = Defines the day of the week that the full backup will on on (must match the same format as the output from $(date))
# NUMOFBKUPTOKEEP = This defines the number of days to keep a backup image on local disk
#
-# Variables determined by the environment
-# BACKUPTYPE = Is determined from the `date` command and the DAYOFFULL value
+# Variables determined by the environment
+# BKPTYPE = Is determined from the $(date) command and the DAYOFFULL value
# DB2INSTANCE = Pulled from the environment
# HOSTNAME
-# DBNAME = Pulled from the `db2 list db directory`
+# DBNAME = Pulled from the $(db2 list db directory)
#
-# Backup command issued
-# ./DB2_Backup.sh ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BACKUPTYPE} 2>>.BackupLOG.stderr > .BackupLOG.out
+# Backup command issued
+# ./DB2_Backup.sh ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BKPTYPE} 2>>.BackupLOG.stderr > .BackupLOG.out
+#
+# -- Revision of script to include new ICD URL
#########################################################
-. /mnt/backup/bin/.PROPS
+# -- Standard Parameters
+HOSTNAME=$(hostname)
+IP=$(/sbin/ifconfig | grep "inet" | grep broadcast | awk '{print $2}')
+DATETIME=$(date +'%Y%m%d_%H%M%S');
+DBINSTANCE=$(whoami);
+NAMESPACE=$(hostname -A | awk -F '.' '{print $3}')
+INSTANCE_HOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${DBINSTANCE}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//' )
+CUSTNAME=$(hostname | sed 's/c-db2wh-//; s/c-db2u-//; s/c-//; s/-db2u-0//; s/db2u/-/; ' | tr '[:lower:]' '[:upper:]' )
+SCRIPT_DIR=${INSTANCE_HOME}/bin
+ICD_LOG=${SCRIPT_DIR}/.Maillive.log
-DBINSTANCE=`whoami`
-HOSTNAME=`hostname`
-BACKUP_DIR=${HOME}/bin
-BACKUP_SCRIPT=DB2_Backup.sh
-DATETIME=`date +%Y-%m-%d_%H%M%S`;
+# -- Verify and source db2profile
-if [ ! -f "${HOME}/sqllib/db2profile" ]
-then
+if [[ ! -f "${HOME}/sqllib/db2profile" ]]; then
echo "ERROR - ${HOME}/sqllib/db2profile not found"
EXIT_STATUS=1
else
. ${HOME}/sqllib/db2profile
fi
+# -- Source the Props File
+. /mnt/backup/bin/.PROPS
+
+# -- Debug Mode
+# set -x; # Uncomment to debug this shell script
+# set -n; # Uncomment to check your syntax, without execution.
+
+# -- Backup Parameters
+BACKUP_SCRIPT="${SCRIPT_DIR}/DB2_Backup.sh"
+BUCKET_ALIAS=$(db2 list storage access | grep ${CONTAINER} -B4 | grep ALIAS | awk -F '=' '{print $2}' )
+DOW=$(date | awk '{print $1}')
+HSTYPE="Backup"
+
+# -- Valid only for MAS-CP4D customers
+if (( ${CUSTNAME} )) ; then
+ CUSTNAME=$( echo ${CONTAINER} | awk -F '-backup-' '{print $2}' | awk -F '-pr-' '{print $1}' | tr '[:lower:]' '[:upper:]' )
+fi
+
+# -- Database Environment
+if [[ ${BUCKET_ALIAS} == "IBMCOS" ]]; then
+ DBENV="MASMS"
+else
+ DBENV="MASSaaS"
+fi
+
+# -- For mapping Hostname with Servicedesk
+
+NS=$( echo ${NAMESPACE} | sed 's/mas-//; s/-core//; s/-manage//; s/-facilities// ; s/-db2u//;' );
+if [[ "$NAMESPACE" =~ "manage" ]] ; then
+ HSHOSTS="main.manage.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "core" ]]; then
+ HSHOSTS="main.home.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "monitor" ]]; then
+ HSHOSTS="main.monitor.${NS}.suite"
+elif [[ "$NAMESPACE" =~ "facilities" ]]; then
+ HSHOSTS="main.facilities.${NS}.suite"
+fi
+
-DOW=`date | awk '{print $1}'`
+# -- Create ICD Incident , If Backup fails
- if [ ${DOW} = ${DAYOFFULL} ] ; then
- BACKUPTYPE=full
- else
- BACKUPTYPE=inc
- fi
+CREATE_ICD() {
+ HTYPE=$(echo ${HSTYPE} | tr '[:lower:]' '[:upper:]')
+ DES="$1"
+ LONGDES=$(cat ${ICD_LOG} | sed 's/"//g' | sed "s/'//g")
+ LONGDES=$(echo "${LONGDES}")
-DBS=`db2 list db directory | grep -B5 "Indirect" | grep "Database name" | awk '{ print $4 }'`
+ # -- Verify the ICD Status
+ if curl -k -s --connect-timeout 3 ${ICD_URL_SAAS} >/dev/null; then
+ CURL_REQ="--request POST --url ${ICD_URL_SAAS} "
+ AUTH_REQ="apikey: ${ICD_API_KEY}"
+ fi
+
+ # -- Generate Curl Syntax to push to ICD
+ cat << ! >.curl_${DBNAME}_ICD.sh
+ curl ${CURL_REQ} \
+ --header '${AUTH_REQ}' \
+ --header 'Content-Type: application/json' \
+ --data '{
+ "description":"${DES}",
+ "reportedpriority":4,
+ "internalpriority":4,
+ "reportedby":"DB2",
+ "affectedperson":"${DBENV}",
+ "ownergroup":"HSDBA",
+ "description_longdescription":"${LONGDES}",
+ "siteid":"001",
+ "classstructureid":"1341",
+ "classificationid":"IN-DBPERF",
+ "hshost":"${HSHOSTS}",
+ "hstype":"${HTYPE}"
+ }'
+!
+ /bin/bash .curl_${DBNAME}_ICD.sh > .curl_${DBNAME}_ICD.out 2>&1
+
+}
+
+# -- Verify the day of the week
+if [[ ${DOW} = ${DAYOFFULL} ]] ; then
+ BKPTYPE="FULL"
+else
+ BKPTYPE="DIFF"
+fi
+
+# -- Loop through the available databases in the instance
+
+DBS=$(db2 list db directory | grep -B5 "Indirect" | grep "Database name" | awk '{ print $4 }')
for DBNAME in ${DBS}
do
- cd ${BACKUP_DIR}
- ./DB2_Backup.sh ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BACKUPTYPE} 2>.BackupLOG.stderr > .BackupLOG.out
-
- RC=$?
- if [ ${RC} -ne 0 ]; then
-
- longdes="Failure to start the Backup job ${DATETIME} CUST=${CUSTNAME} ${RC}"
- ## Send Failure notification to a slack channel ##
- cat << ! >.curl_${DBNAME}_RUN.sh
- if [[ -n "${SLACKURL}" ]]; then
- curl -X POST -H 'Content-type: application/json' --data '{"text":"$longdes"}' $SLACKURL
- fi
+ cd ${SCRIPT_DIR}
+ ${BACKUP_SCRIPT} ${DB2INSTANCE} ${DBNAME} ${NUMOFBKUPTOKEEP} ${BKPTYPE} 2>.BackupLOG.stderr > .BackupLOG.out
+ RC=$?
+ if [[ ${RC} -ne 0 ]]; then
+ LONGDES="Failure to start the Backup job ${DATETIME} CUST=${CUSTNAME} ${RC}"
+ # -- Send Failure notification to a slack channel
+ cat << ! >.curl_${DBNAME}_RUN.sh
+ curl -X POST -H 'Content-type: application/json' --data '{"text":"$LONGDES"}' ${SLACKURL}
!
-/bin/bash .curl_${DBNAME}_RUN.sh > .curl_${DBNAME}_RUN.out 2>&1
-
- ##### Create ICD Incident ####
- ####### If Backup fails ###
- des="${DBINSTANCE} - Backup - ${HOSTNAME} ${DBNAME} ${CUSTNAME} - MASMS -- Backup Failed"
- echo "TESTING $instance - Backup - $ ${DBNAME} - Backup Failed" > .Maillive.log
- echo "############################" >> .Maillive.log
- #cat $BACK_LOG >> .Maillive.log
- longdes=`cat .Maillive.log | sed 's/"//g' | sed "s/'//g"`
- ICD_URL="https://servicedesk.mro.com"
- if ! curl -k -s --connect-timeout 3 ${ICD_URL} >/dev/null; then
- ICD_URL="https://servicedesk.cds.mro.com"
- fi
-
-cat << ! >.curl_${DBNAME}_ICD.sh
- curl --insecure --location --request POST "${ICD_URL}/maximo_mif/oslc/os/hsincident?lean=1" \
- --header "Authorization: Basic ${ICD_AUTH_KEY}" \
- --header 'Content-Type: application/json' \
- --data '{
- "description":"$des",
- "reportedpriority":4,
- "internalpriority":4,
- "reportedby":"DB2",
- "affectedperson":"CTGINST1",
- "description_longdescription":"$longdes",
- "siteid":"001",
- "classstructureid":"1341",
- "classificationid":"IN-DBPERF",
- "hshost":"{servicedesk-pdb-sjc03-2.cds.mro.com:0:50}",
- "hstype":"BACKUP"
- }'
-!
-if [[ -n "${ICD_AUTH_KEY}" ]]; then
- /bin/bash .curl_${DBNAME}_ICD.sh > .curl_${DBNAME}_ICD.out 2>&1
-fi
+ /bin/bash .curl_${DBNAME}_RUN.sh > .curl_${DBNAME}_RUN.out 2>&1
+
+ # -- Create ICD ticket if fails
+ DES="${CUSTNAME} - ${DBENV} - ${DBNAME} - ${HOSTNAME} -- Failed to Initiate Backup!! "
+ CREATE_ICD "${DES}"
+ fi
+
+ # -- Execute Online Reorgs for qualified tables and indexes after every Full Backup
+ if [[ ${DOW} = ${DAYOFFULL} ]] ; then
+ /bin/bash ${SCRIPT_DIR}/reorgTablesIndexesInplace.sh -db ${DBNAME} -s MAXIMO -tb_stats -ix_stats -tr -window 180 >${INSTANCE_HOME}/maintenance/logs/reorgTablesIndexesInplace_${DATETIME}.log 2>&1
+ fi
-fi
done
-/bin/bash ${HOME}/bin/runstats_rebind.sh >${HOME}/bin/.runstats_rebind.out 2>&1
-/bin/bash ${HOME}/bin/grant_check.sh bludb >${HOME}/bin/.grant_check.out 2>&1
+
+# -- Exeucte Runstats and Rebind for all tables on weekly after full backup
+/bin/bash ${SCRIPT_DIR}/runstats_rebind.sh >${SCRIPT_DIR}/.runstats_rebind.out 2>&1
+#/bin/bash ${SCRIPT_DIR}/grant_check.sh bludb >${SCRIPT_DIR}/.grant_check.out 2>&1
+
+# -- Extract the audit logs and transfer to Bucket
+/bin/bash ${SCRIPT_DIR}/auditExtractUpload.sh >${INSTANCE_HOME}/maintenance/logs/auditExtractUpload_${DATETIME}.log & disown
+
+# -- END OF SCRIPT
\ No newline at end of file
diff --git a/instance-applications/120-ibm-db2u-database/files/auditExtractUpload.sh b/instance-applications/120-ibm-db2u-database/files/auditExtractUpload.sh
new file mode 100644
index 000000000..af0e40d4d
--- /dev/null
+++ b/instance-applications/120-ibm-db2u-database/files/auditExtractUpload.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+
+# ----------------------------------------------------------------------------
+#% Script Name : auditExtractUpload.sh
+#% Description : Script to Archive, Extract the audit logs and upload to COS
+#% Created On : 10th February 2026
+#%
+#% Author : Mujibur Rahman
+#% Email : mujibur.rahman1@ibm.com
+# ----------------------------------------------------------------------------
+# Version Date Changed By Description
+# ----------------------------------------------------------------------------
+# 0.1 10-02-2026 Mujib Initial Version
+# 0.2 04-05-2026 Prudhviraj P Updated the loggging, clean up of old archives, induced compression to archives
+#
+# ----------------------------------------------------------------------------
+# ************** THIS NEEDS TO BE RUN AS INSTANCE OWNER. *****************
+# USAGE:
+# auditExtractUpload.sh
+#
+# ***************************************************************************
+
+#set -euo pipefail
+
+# ============================================================================
+# Parameters/Inputs
+# ============================================================================
+
+HOSTNAME=$(hostname)
+HOSTIP=$(hostname -i)
+WHOAMI=$(whoami)
+INST=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | awk -F, '{print $4}')
+INSTHOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${INST}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//')
+BASE_DIR=${INSTHOME}/bin
+DT=$(date +"%Y%m%d_%H%M%S")
+DBNAME="BLUDB"
+
+# ===========================================================================
+# Invoking DB2 Profile
+# ===========================================================================
+
+. ${INSTHOME}/sqllib/db2profile
+
+# -------------------------------
+# Load COS parameters
+# -------------------------------
+. /mnt/backup/bin/.PROPS
+
+# ===========================================================================
+# Debug Options
+# ===========================================================================
+
+# set -x; # Uncomment to debug this shell script
+# set -n; # Uncomment to check your syntax, without execution.
+
+
+# -- Extract the info needed from db2audit
+
+DATA_DIR=$( db2audit describe | grep "Audit Data Path: " | awk -F ': ' '{gsub(/"/, ""); print $2}' | sed 's/\/$//' );
+ARCHIVE_DIR=$( db2audit describe | grep "Audit Archive Path:" | awk -F ': ' '{gsub(/"/, ""); print $2}' | sed 's/\/$//' );
+
+# -------------------------------
+# Functions
+# -------------------------------
+log() {
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
+}
+
+cleanup() {
+ log "INFO :: Ensuring db2audit is running "
+ db2audit start >/dev/null 2>&1 || true
+}
+
+trap cleanup EXIT
+
+# -------------------------------
+# Start processing
+# -------------------------------
+log "INFO :: Starting DB2 audit extraction for database $DBNAME"
+
+: '
+# Stop audit
+db2audit stop
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: db2audit stopped"
+else
+ log "ERROR :: db2audit cannot be stopped"
+fi
+'
+
+# Flush records
+db2audit flush > /dev/null 2>&1
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: db2audit flushed"
+else
+ log "ERROR :: db2audit cannot be flushed"
+fi
+
+# Archive audit logs
+db2audit archive database "$DBNAME" > /dev/null 2>&1
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: db2audit archived"
+else
+ log "ERROR :: db2audit cannot be archived"
+ exit
+fi
+#db2audit.db.BLUDB.log.0.20260504093246
+#db2audit.db."$DBNAME".log.0.
+DTN=$( date +'%Y%m%d%H' )
+
+# Identify latest archived audit file
+AUDIT_LOG=$(ls -t "$ARCHIVE_DIR"/db2audit.db."$DBNAME".log.0.$DTN* 2>/dev/null | head -1)
+AUDIT_FILE="${ARCHIVE_DIR}/db2audit_report.${DT}"
+AUDIT_ZIP="${AUDIT_FILE}.zip"
+
+log "INFO :: Verifying whether audit log is available or not"
+
+if [[ -z "${AUDIT_LOG:-}" ]]; then
+ log "ERROR :: No archived audit file found"
+ exit 1
+fi
+
+log "INFO :: Extracting audit data from $AUDIT_LOG"
+
+# Extract audit data
+db2audit extract file "$AUDIT_FILE" from files "$AUDIT_LOG" > /dev/null 2>&1
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: Audit log extract and created as $AUDIT_FILE"
+else
+ log "ERROR :: Audit Failed to extract. "
+ exit
+fi
+
+log "INFO :: Compressing the Audit file : $AUDIT_FILE"
+zip -r ${AUDIT_ZIP} ${AUDIT_FILE} > /dev/null 2>&1
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: Audit log Compressed to $AUDIT_ZIP"
+ log "INFO :: Removing the extracted and archived files "
+ log "INFO :: ${AUDIT_FILE} "
+ log "INFO :: ${AUDIT_LOG} "
+ rm ${AUDIT_FILE} ${AUDIT_LOG}
+ RC2=$?
+ if [[ $RC2 -eq 0 ]]; then
+ log "INFO :: Removed both extracted/Archive audit files "
+ else
+ log "ERROR :: Failed to delete the extracted/Archive audit files "
+ exit
+ fi
+else
+ log "ERROR :: Audit Failed to Compress. "
+ exit
+fi
+
+# Restart audit
+#db2audit start
+#log "db2audit started"
+
+# Upload to COS
+log "INFO :: Uploading audit extract to COS"
+
+AUDZIP=$( echo $AUDIT_ZIP | awk -F '/' '{print $NF}' )
+COS_TARGET="DB2REMOTE://AWSCOS//AUDIT_LOGS/${AUDZIP}"
+
+db2RemStgManager alias put \
+ source="$AUDIT_ZIP" \
+ target="$COS_TARGET" > /dev/null 2>&1
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: Upload completed to $COS_TARGET"
+else
+ log "ERROR :: Failed to Upload. "
+ exit
+fi
+
+
+# -- Clean the old archives more than 30 days
+log "INFO :: Deleting the old archive more than 30 Days from Pod "
+find ${ARCHIVE_DIR} -name db2audit_report.*.zip -type f -mtime +30 -exec rm {} \;
+RC=$?
+if [[ $RC -eq 0 ]]; then
+ log "INFO :: Cleaned archives more than 30 Days"
+else
+ log "ERROR :: Failed to clean the old archives "
+ exit
+fi
+
+log "INFO :: Execution of audit extract and upload has completed. "
+exit 0
+
+
+# -- End of the Script
\ No newline at end of file
diff --git a/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace.sh b/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace.sh
new file mode 100644
index 000000000..28a993c4e
--- /dev/null
+++ b/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace.sh
@@ -0,0 +1,1348 @@
+#!/bin/sh
+##
+## HPS created Jan 2019
+##
+## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/
+## see Identifying fragmented indexes from statistics
+## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
+##0 23 * * 5 (. ~/sqllib/db2profile; ~/maintenance/bin/misc/reorgTablesIndexesInplace.sh -db dbname -s MAXIMO -tb_stats -if_stats -window 120 -tr >> ~/maintenance/logs/reorgTablesIndexesInplace.sh.log 2>&1 )
+## script to reorg tables online and indexes offline based on different criteria
+## we need to be able to perform an online table reorg and an offline indexes all reorg in the same run of the script
+##
+#
+# -- Modifications/Updates on 01/May/26 by Prudhviraj Patrata
+# -- Increased the default tablesize from 20GB to 100GB
+# -- Updated to use single database at a time
+# -- Improved the readability of output of logs
+#
+
+UsageHelp()
+{
+ echo "Script to perform reorg tables, indexes online (inplace) "
+ echo " also to REORG INDEXES ALL FOR TABLE offline"
+ echo " db2 performs the online reorgs asynchronously"
+ echo ""
+ echo "Usage: ${0} [options]"
+ echo " where [options] is one of the following:"
+ echo " -h: displays this usage screen"
+ echo " -db: dbname, default is all cataloged databases"
+ echo ""
+ echo " -s: table schemaname"
+ echo " -t: table(s) to reorg"
+ echo "-tb_stats: reorg tables reported by REORGCHK_TB_STATS"
+ echo " -ti: reorg table index(s), format must be TABSCHEMA.TABNAME.INDSCHEMA.INDNAME"
+ echo "-ix_stats: reorg table index(s) reported by REORGCHK_IX_STATS"
+ echo "-if_stats: reorg indexes all for table(s) offline as reported by index fragmentation NLEAF/SEQUENTIAL_PAGES columns"
+ echo ""
+ echo " -ls: list valid table sizes for a particular schema"
+ echo " -lf: list all fragmented index details for a particular schema, based on valid table sizes"
+ echo " -lt: list all tables to reorg based on REORGCHK_TB_STATS reorg column, based on valid table sizes"
+ echo " -li: list all indexes to reorg based on REORGCHK_IX_STATS reorg column, based on valid table sizes"
+ echo " -l: list tables/indexes that would be reorged"
+ echo ""
+ echo " -ittx: ignore tables over a specific threshold size in MBs, default is 100000 MB ie 100 GB"
+ echo " -ittn: ignore tables under a specific threshold size in MBs, default is 10 MB"
+ echo " -mar: maximum asynchronous reorgs allowed, default is 3"
+ echo " -log: don't kick off a reorg if transaction log usage is over a certain percentage, default is 90%"
+ echo " -window: stop reorg tables/indexes/runstats after a set maintenance timeout window, default is 240 minutes"
+ echo " -twa: timeout window action: default=2 for online, 1 for offline"
+ echo " 1=allow current reorg(s) to continue"
+ echo " 2=stop current reorg(s)"
+# echo " 3=stop current reorg(s) if < 80% complete and continue script"
+ echo " -ignore: ignore specific tables from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1 "
+ echo " eg \"$IGNORE_TABLES_EX\""
+ echo " -reorg: table F1 F2 F3 filter reorg, default is *"
+ echo " -sleep: SLEEP_INTERVAL_TIME, default is 60 seconds"
+ echo ""
+ echo " -tr: execute inplace table/index reorg"
+ echo ""
+ echo " -trsi: Retrieve table reorganization snapshot information from snap_get_tab_reorg and db2pd -reorgs index"
+ echo ""
+ echo "Examples :"
+ echo " 1. ${0} -h"
+ echo " 2. ${0} -db dbname -s MAXIMO -ls"
+ echo " 3. ${0} -db dbname -s MAXIMO -t \"YFS_ITEM YFS_TASK_Q YFS_SHIPMENT\" -tb_stats -tr "
+ echo " 4. ${0} -db dbname -s MAXIMO -ti \"MAXIMO.YFS_SNAPSHOT.MAXIMO.YFS_SNAPSHOT_I1 MAXIMO.YFS_ITEM.MAXIMO.YFS_ITEM_PK\" -ix_stats -tr"
+ echo " 5. ${0} -db dbname -s MAXIMO -t \"YFS_ITEM YFS_SNAPSHOT YFS_IMPORT YFS_EXPORT\" -if_stats -tr"
+ echo " 6. ${0} -db dbname -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ittx 30000 -tr"
+ echo " 7. ${0} -db dbname -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ignore \"$IGNORE_TABLES_EX\" -reorg \"***\" -tr"
+ echo " 8. ${0} -db dbname -s MAXIMO -tb_stats -if_stats -ittx 100 -ittn 20 -tr"
+ echo " 9. ${0} -trsi"
+
+ echo ""
+
+}
+
+##
+## function to check if a string is numeric
+##
+isNumeric()
+{
+ echo $1 | grep -E '^[0-9]+$' > /dev/null
+
+ return $?
+}
+
+
+TRSI()
+{
+ db2 -v "select varchar(tabschema,9) as tabschema, varchar(tabname,32) as tabname,
+ REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER,
+ VARCHAR_FORMAT(REORG_START, 'YYYY-MM-DD-HH24:MI:SS') as REORG_START,
+ VARCHAR_FORMAT(REORG_END, 'YYYY-MM-DD-HH24:MI:SS') as REORG_END,
+-- REORG_START, REORG_END,
+ REORG_INDEX_ID, REORG_TBSPC_ID
+ from table(snap_get_tab_reorg(''))
+ order by REORG_START asc
+ with ur"
+
+ db2pd -db $DBNAME -reorgs index | sed -n "/Index Reorg Stats:/,//p" > /dev/null 2>&1
+
+}
+
+log()
+{
+ TYPE=$1
+ MSG="$2"
+
+ DATE=$( date '+%d-%m-%Y %H:%M:%S' );
+
+ # TYPE:
+ # 0 = Critical
+ # 1 = Warn
+ # 3 = Info
+ # 5 = Debug'
+ if [ ${TYPE} -eq 0 ]; then
+ TYPEMSG="Error"
+ elif [ ${TYPE} -eq 1 ]; then
+ TYPEMSG="Warning"
+ elif [ ${TYPE} -eq 3 ]; then
+ TYPEMSG="Info"
+ elif [ ${TYPE} -eq 5 ]; then
+ TYPEMSG="Debug"
+ else
+ TYPEMSG="Other"
+ fi
+
+ echo -e "${DATE} ${TYPEMSG} : ${MSG}" | tee -a $REORG_TABLE_INDEX_LOG
+
+ return 0
+}
+
+initTABLE_IN_USE_ARRAY()
+{
+
+ local NUM_ITEMS=$1
+ local jj;
+
+ ##
+ ## initialise the db2 TABLE_IN_USE_ARRAY
+ ##
+ for((jj=0; jj<$NUM_ITEMS; jj++))
+ do
+ TABLE_IN_USE_ARRAY[$jj]=""
+ done
+
+ return 0
+
+}
+
+existTABLE_TABLE_IN_USE_ARRAY()
+{
+
+ local TABLE=$1
+ local jj;
+ ##
+ ## check if table is in use
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
+ return 0;
+ fi
+ done
+
+ return 1;
+
+}
+
+addTABLE_TABLE_IN_USE_ARRAY()
+{
+
+ local TABLE=$1
+ local jj;
+
+ ##
+ ## add table in empty slot
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "" ]; then
+ TABLE_IN_USE_ARRAY[$jj]=$TABLE;
+ return 0;
+ fi
+ done
+
+ return 1;
+}
+
+removeTABLE_TABLE_IN_USE_ARRAY()
+{
+
+ local TABLE=$1
+ local jj;
+ ##
+ ## remove entry
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
+ TABLE_IN_USE_ARRAY[$jj]="";
+ return 0;
+ fi
+ done
+
+ return 1;
+
+}
+
+
+listTABLE_IN_USE_ARRAY()
+{
+
+ local jj;
+ ##
+ ## list table entries
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ log 5 "TABLE_IN_USE_ARRAY $jj ${TABLE_IN_USE_ARRAY[$jj]}";
+ done
+
+ return 0;
+
+}
+
+getValidTablesToReorg()
+{
+
+ getValidTableSizes
+
+ VALID_TABLES_TO_REORG=""
+ VALID_TABLES_TO_REORG_RAW=""
+ NUM_VALID_TABLES_TO_REORG=0
+ for TABNAME in $VALID_TABLES
+ do
+
+ RAW=$( db2 -x "call REORGCHK_TB_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
+ RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 12) print $0 }' | sed 's/ \+/ /g' | grep $REORG )
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ TABNAME=$( echo "$RAW" | awk '{print $2}' );
+ [ "$VALID_TABLES_TO_REORG_RAW_DATA" == "" ] && VALID_TABLES_TO_REORG_RAW_DATA="$RAW" || VALID_TABLES_TO_REORG_RAW_DATA="$VALID_TABLES_TO_REORG_RAW_DATA\n$RAW"
+ fi
+
+ done
+
+ ## sort the tables based on REORG column
+ VALID_TABLES_TO_REORG_RAW_DATA=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | sort -k12 -r);
+ VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | awk '{print $2}' );
+ NUM_VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG" | wc -l );
+
+ return 0
+
+}
+
+getValidIndexesToReorg()
+{
+
+ getValidTableSizes
+
+ VALID_INDEXES_TO_REORG=""
+ VALID_INDEXES_TO_REORG_RAW=""
+ NUM_VALID_INDEXES_TO_REORG=0
+ for TABNAME in $VALID_TABLES
+ do
+
+ RAW=$( db2 -x "call REORGCHK_IX_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
+ ## this can return multiple indexes for same TABNAME
+ RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 21) print $0 }' | sed 's/ \+/ /g' | grep $REORG );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ INDNAME=$( echo "$RAW" | awk '{print $1"."$2"."$3"."$4}' );
+ [ "$VALID_INDEXES_TO_REORG_RAW_DATA" == "" ] && VALID_INDEXES_TO_REORG_RAW_DATA=$RAW || VALID_INDEXES_TO_REORG_RAW_DATA="$VALID_INDEXES_TO_REORG_RAW_DATA\n$RAW"
+ fi
+
+ done
+
+ ## sort the indexes based on REORG column
+ VALID_INDEXES_TO_REORG_RAW_DATA=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | sort -k21 -r);
+ VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | awk '{print $1"."$2"."$3"."$4}' );
+ NUM_VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG" | wc -l );
+
+ return 0
+
+}
+
+getValidFragmentedIndexes()
+{
+
+ ##
+ ## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
+ ##
+
+ getValidTableSizes
+
+ VALID_FRAGMENTED_INDEXES_RAW_DATA=$( db2 -x "select rtrim(tabschema)||' '||rtrim(tabname)||' '||rtrim(indschema)||' '||rtrim(indname)
+ ||' '||indcard||' '||stats_time||' '||lastused||' '||nleaf||' '||sequential_pages
+ from syscat.indexes where tabschema='$SCHEMANAME_IN'
+ and not (nleaf = 1 and sequential_pages = 0)
+ and not (nleaf = 0 and sequential_pages = 1)
+ and (nleaf - sequential_pages > 10)
+ and tabname in ( $VALID_TABLES_FORMATTED )
+ order by tabname
+ with ur"; );
+
+ VALID_FRAGMENTED_INDEXES_RAW_DATA=$(echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' );
+ VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' | cut -d' ' -f2 | uniq )
+ NUM_VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES}" | wc -l )
+}
+
+getValidTableSizes()
+{
+
+ VALID_TABLE_SIZES_RAW_DATA=$( db2 "select t0.tabname,
+ ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB,
+ cast ((INDEX_OBJECT_P_SIZE / 1024 ) as integer) as INDEX_SIZE_MB
+ from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1
+ where t0.tabschema='$SCHEMANAME_IN'
+ and t0.tabschema=t1.tabschema
+ and t0.tabname=t1.tabname
+ $IGNORE_TABLES
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
+ order by 2 desc
+ with ur"; );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES_RAW_DATA" | sed '1,3d' | sed '$d' | sed '$d' );
+ VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; printf "\n"; }');
+ VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | awk '{print $1}' );
+ NUM_VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | wc -l );
+ # log 3 "NUM_VALID_TABLES=$NUM_VALID_TABLES"
+
+ VALID_TABLES_FORMATTED=""
+ for TABLE in $VALID_TABLES
+ do
+ VALID_TABLES_FORMATTED="$VALID_TABLES_FORMATTED'$TABLE',"
+ done
+ VALID_TABLES_FORMATTED=$( echo "$VALID_TABLES_FORMATTED" | sed 's/,$//g' )
+ else
+ VALID_TABLES_FORMATTED="'UNKNOWN_TABNAME'"
+ fi
+
+}
+
+## is TABLE within size limits < IGNORE_TABLE_SIZE_THRESHOLD_MAX and > IGNORE_TABLE_SIZE_THRESHOLD_MIN
+isTableWithinSizeLimit()
+{
+ local SCHEMANAME=$1
+ local TABNAME=$2
+ local RC=""
+ local rc=0
+
+ RC=$( db2 -x "select tabname,
+ ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB
+ from SYSIBMADM.ADMINTABINFO
+ where tabschema='$SCHEMANAME'
+ and tabname = '$TABNAME'
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
+ order by 2 desc
+ with ur" );
+
+ rc=$?
+ return $rc
+
+}
+
+## create an list/array of table objects to reorg based on tabnames
+createTableOBJECT_ARRAY()
+{
+ local TABNAMES="$1"
+ local OBJECT_REORG_TABLE_TYPE=$2
+
+ ##
+ ## make the OBJECT_ARRAY for tables and indexes
+ ##
+ if [ -z "$OBJECT_ARRAY" ]; then
+ local let index=0;
+ else
+ local let index=${#OBJECT_ARRAY[@]};
+ fi
+ local TID=0 ## Table ID - always 0 for online table reorg
+ local INDSCHEMA=NULL;
+ local INDNAME=NULL;
+ local LOCK_COUNT=0
+
+ for TABNAME in $TABNAMES
+ do
+ ## we need TABLEID, TBSPACEID for IF_STATS as the full TableName: may not be dispalyed in the db2pd output
+ local RC=$( db2 -x "select TABLEID, TBSPACEID from syscat.tables where tabname='$TABNAME' and tabschema='$SCHEMANAME_IN'" )
+ local rc=$?
+ if [ $rc -eq 0 ]; then
+ local TABLEID=$( echo $RC | awk '{print $1}' );
+ local TBSPACEID=$( echo $RC | awk '{print $2}' );
+ OBJECT_ARRAY[$index]="$SCHEMANAME_IN#$TABNAME#$INDSCHEMA#$INDNAME#$TID#NOTSTARTED#-#-#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ let index+=1
+ fi
+ done
+
+}
+
+## create an list/array of table objects to reorg based on indnames
+createIndexOBJECT_ARRAY()
+{
+
+ local INDNAMES="$1"
+ local OBJECT_REORG_TABLE_TYPE=$2
+ local let index=0
+ local TABLEID=9999;
+ local TBSPACEID=9999;
+ local LOCK_COUNT=0;
+
+ for INDEX in $INDNAMES
+ do
+ local TABSCHEMA=$( echo $INDEX | cut -d. -f1);
+ local TABNAME=$( echo $INDEX | cut -d. -f2);
+ local INDSCHEMA=$( echo $INDEX | cut -d. -f3);
+ local INDNAME=$( echo $INDEX | cut -d. -f4);
+ local RC=$( db2 -x "select IID from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
+ local rc=$?
+ if [ $rc -eq 0 ]; then
+ local IID=$( echo $RC | cut -d' ' -f1);
+ OBJECT_ARRAY[$index]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#NOTSTARTED#-#-#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ let index+=1
+ fi
+ done
+
+}
+##
+## list out the objects and state
+## this can be used for debugging
+##
+listOBJECT_ARRAY()
+{
+
+ local ii;
+ log 3 "The following is for debug purposes, Num objects=${#OBJECT_ARRAY[@]}, $OBJECT_NUM_TB_STATS:$OBJECT_NUM_IX_STATS:$OBJECT_NUM_IF_STATS"
+ printf "%-15s %-40s %-15s %-40s %-14s %-20s %-20s %-8s \n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "REORG_STATUS" "REORG_START" "REORG_END" "LOCK_COUNT"
+ : ' for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ echo "${OBJECT_ARRAY[$ii]}" | /usr/bin/column -t -s "#" | tee -a $REORG_TABLE_INDEX_DEBUG
+ done
+ '
+ for ((ii=0; ii<${#OBJECT_ARRAY[@]}; ii++))
+ do
+ IFS="#" read -r TABSCHEMA TABNAME INDSCHEMA INDNAME IID REORG_STATUS OBJECT_REORG_START OBJECT_REORG_END TABLEID TBSPACEID LOCK_COUNT <<< "${OBJECT_ARRAY[$ii]}"
+
+ printf "%-15s %-40s %-15s %-40s %-14s %-20s %-20s %-8s \n" "$TABSCHEMA" "$TABNAME" "$INDSCHEMA" "$INDNAME" "$REORG_STATUS" "$OBJECT_REORG_START" "$OBJECT_REORG_END" "$LOCK_COUNT"
+ done
+}
+
+## get the number tb_stats, ix_stats and if_stats objects
+getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY()
+{
+
+ local rc=0;
+ local ii;
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ if [ $( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 ) -eq $1 ]; then
+ let rc+=1;
+ fi
+ done
+
+ return $rc;
+
+}
+
+##
+## the main event
+##
+reorgTables()
+{
+
+ ## variables that need to be reset on each run of the function
+ NUM_REORGS_IN_PROGRESS=0;
+ NUM_REORGS_KICKED_OFF=0;
+ NUM_REORGS_COMPLETED=0;
+ NUM_REORGS_STOPPED=0;
+ NUM_REORGS_ABORTED=0;
+
+ while true
+ do
+
+ ## check reorg window maintenance time
+ MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
+ DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
+
+ ## safety valve - if for some reason the logic can't stop the reorgs
+ if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + REORG_TIMEOUT_OVERFLOW_VALVE )) ]; then
+ log 1 "REORG_TIMEOUT_OVERFLOW_VALVE detected";
+ log 1 "Aborting reorgs"
+ break;
+ fi
+
+ if [ $DIFF -ge $REORG_TIMEOUT_WINDOW_SECONDS ]; then
+
+ REORG_TIMEOUT_WINDOW_COMPLETED=1;
+
+ ## -twa: timeout window action: default=3
+ ## 1=allow current reorg(s) to continue
+ ## 2=stop current reorg(s)
+ ## 3=stop current reorg(s) if < 80% complete
+ if [ $REORG_TIMEOUT_WINDOW_ACTION -eq 1 ]; then
+
+ log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
+ break
+
+ elif [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ]; then
+
+ ## use of the REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER
+ ## 0 = ABORT those not started and issue a STOP to those STARTED
+ ## 1 = loop again and see if script exits as all reorgs are COMPLETED and STOPPED and ABORTED
+ ## 2 = break out
+ if [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 0 ]; then
+ let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
+ log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
+ log 3 "Aborting reorgs NOTSTARTED and issuing a STOP to those that are STARTED"
+ elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+ let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
+ log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
+ elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 2 ]; then
+ log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
+ log 3 "Breaking out of reorg loop"
+ break;
+ fi
+ fi
+ fi
+
+ ## loop for all OBJECTS - extract relevant data from OBJECT array
+ ## if we have NOTSTARTED in the OBJECT_ARRAY[N] - then kick off a reorg
+ ## then check tables reorg status
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ ## get table related info
+ TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
+ TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
+ INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
+ INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
+ IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
+ OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
+ OBJECT_REORG_START=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f7 );
+ OBJECT_REORG_END=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f8 );
+ TABLEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f9 );
+ TBSPACEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f10 );
+ LOCK_COUNT=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f11 );
+ OBJECT_REORG_TABLE_TYPE=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 );
+ isTable=0;
+ isIndex=0;
+ if [ "$INDSCHEMA" == "NULL" -a "$INDNAME" == "NULL" ]; then
+ isTable=1;
+ else
+ isIndex=1;
+ fi
+
+ if [ $OBJECT_REORG_TABLE_TYPE -ne $REORG_TABLE_TYPE ]; then
+ continue;
+ fi
+
+ # log 5 "${OBJECT_ARRAY[$ii]}"
+
+ ##
+ ## has OBJECT COMPLETED - no need to continue here
+ ##
+ if [[ "$OBJECT_REORG_STATUS" == "COMPLETED" || "$OBJECT_REORG_STATUS" == "STOPPED" || "$OBJECT_REORG_STATUS" == "ABORTED" ]]; then
+ continue;
+ fi
+
+ if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
+
+ ##
+ ## query db2 for REORG_STATUS etc - there may not be an entry so carry on
+ ##
+ RC_SNAP=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER, VARCHAR_FORMAT(REORG_START, 'YYYY-MM-DD-HH24:MI:SS') as REORG_START, VARCHAR_FORMAT(REORG_END, 'YYYY-MM-DD-HH24:MI:SS') as REORG_END, REORG_INDEX_ID, REORG_TBSPC_ID from table(snap_get_tab_reorg('')) where tabschema='$TABSCHEMA' and tabname='$TABNAME' and REORG_START > TIMESTAMP('$WINDOW_START_TIME_DB2') and REORG_INDEX_ID=$IID");
+ rc=$?
+ if [ $rc -ge 2 ]; then
+ log 0 "Possible error running select query against db2\nrc=$rc\nRC=$RC"
+ continue;
+ fi
+
+ if [ $rc -eq 0 ]; then
+ RC=$( echo "$RC_SNAP" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; }')
+ REORG_STATUS=$( echo "$RC_SNAP" | awk '{print $1}' );
+ REORG_COMPLETION=$( echo "$RC_SNAP" | awk '{print $2}' );
+ REORG_CURRENT_COUNTER=$( echo "$RC_SNAP" | awk '{print $4}' );
+ REORG_MAX_COUNTER=$( echo "$RC_SNAP" | awk '{print $5}' );
+ REORG_START=$( echo "$RC_SNAP" | awk '{print $6}' );
+ REORG_END=$( echo "$RC_SNAP" | awk '{print $7}' );
+ REORG_INDEX_ID=$( echo "$RC_SNAP" | awk '{print $8}' );
+
+ declare -i REORG_PERCENT_COMPLETE=0
+ if [[ ! -z "$REORG_CURRENT_COUNTER" && $REORG_CURRENT_COUNTER -gt 0 ]]; then
+ if [[ ! -z "$REORG_MAX_COUNTER" && $REORG_MAX_COUNTER -gt 0 ]]; then
+ if [ $REORG_MAX_COUNTER -ge $REORG_CURRENT_COUNTER ]; then
+ REORG_PERCENT_COMPLETE=$(echo $REORG_CURRENT_COUNTER $REORG_MAX_COUNTER | awk '{ print int (($1/$2)*100) }' );
+ fi
+ fi
+ fi
+ fi
+
+ # log 5 "RC_SNAP=$RC_SNAP"
+
+ elif [ $IF_STATS -eq 3 ]; then
+
+ DB2PD_REORG_INDEX_RECORD=$( db2pd -db $DBNAME -reorgs index | grep -B1 -A11 -w "^TbspaceID: $TBSPACEID" | grep -B1 -A11 -w "TableID: $TABLEID" );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ REORG_START=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | awk '{ print $3,$4}' );
+ REORG_START_SECONDS=$(date --date="$REORG_START" '+%s');
+
+ if [ $REORG_START_SECONDS -ge $IF_STATS_WINDOW_START_TIME_DB2 ]; then
+ REORG_STATUS=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Status:' | awk '{ $1=""; print $0}' | sed 's/^[ \t]*//;s/[ \t]*$//' );
+ ## some differences between snap_get_tab_reorg and db2pd -reogrs index output
+ if [ "$REORG_STATUS" == "In Progress" ]; then
+ REORG_STATUS="STARTED";
+ elif [ "$REORG_STATUS" == "Completed" ]; then
+ REORG_STATUS="COMPLETED";
+ elif [ "$REORG_STATUS" == "Stopped" ]; then
+ REORG_STATUS="STOPPED";
+ fi
+
+ REORG_END=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | grep 'End Time:' | awk '{ print $7,$8}' );
+ REORG_IND_CUR_STATUS=$( echo "$DB2PD_REORG_INDEX_RECORD" | grep "Status:" );
+ REORG_IND_CUR=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep "Cur Index:" );
+ REORG_INDEX_STATUS=$(printf "%-25s %-10s" "$REORG_IND_CUR_STATUS" "$REORG_IND_CUR")
+ fi
+ fi
+ fi
+
+ ##
+ ## has OBJECT been KICKED_OFF or STARTED
+ ## if it has check to see if is STARTED or COMPLETED
+ ## update OBJECT_ARRAY
+ ## update COMPLETION/STOPPED stats
+ ##
+ if [ "$OBJECT_REORG_STATUS" == "KICKED_OFF" ] || [ "$OBJECT_REORG_STATUS" == "STARTED" ]; then
+ if [ ! -z "$REORG_STATUS" ]; then
+ if [ "$REORG_STATUS" == "STARTED" -o "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$REORG_START#$REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ fi
+
+ if [ "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
+
+ removeTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ log 1 "Failed to remove table $TABSCHEMA.$TABNAME from TABLE_IN_USE_ARRAY";
+ fi
+
+ if [ "$REORG_STATUS" == "COMPLETED" ]; then
+ let NUM_REORGS_COMPLETED+=1
+ elif [ "$REORG_STATUS" == "STOPPED" ]; then
+ let NUM_REORGS_STOPPED+=1
+ fi
+
+ let NUM_REORGS_IN_PROGRESS-=1
+ fi
+
+ fi
+
+ ##
+ ## OBJECT is NOSTARTED so KICK_OFF a reorg
+ ##
+ elif [ "$OBJECT_REORG_STATUS" == "NOTSTARTED" ]; then
+
+ ## dont kick off any reorgs if window timeout passed and TWA=2
+ ## OBJECTS become ABORTED - UPDATE OBJECT_ARRAY
+ if [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+ REORG_STATUS=ABORTED;
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ let NUM_REORGS_ABORTED+=1;
+ continue;
+
+ fi
+
+ ## is the TABLE already being used -if it is goto next OBJECT
+ existTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ [ $rc -eq 0 ] && continue;
+
+ ## we only want to kick off so many reorgs at any one time
+ if [ $NUM_REORGS_IN_PROGRESS -eq $MAX_ASYNC_REORGS_ALLOWED ]; then
+ continue;
+ fi
+
+ ##
+ ## The table could already be locked - if it is then by-pass it
+ ## and ABORT if locked more than 10 times
+ ##
+ TABLE_LOCKED=$( db2 "select APPLICATION_HANDLE, LOCK_OBJECT_TYPE, LOCK_MODE, LOCK_CURRENT_MODE, LOCK_STATUS, LOCK_COUNT, LOCK_HOLD_COUNT, TBSP_ID, TAB_FILE_ID from TABLE (MON_GET_LOCKS(NULL, -2)) where TBSP_ID=$TBSPACEID and TAB_FILE_ID=$TABLEID and LOCK_OBJECT_TYPE='TABLE' and LOCK_MODE='IX' with ur"; );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ let LOCK_COUNT+=1;
+ log 1 "Appears table $TABSCHEMA.$TABNAME is already locked by another application(s), LOCK_COUNT=$LOCK_COUNT";
+ log 1 "$TABLE_LOCKED";
+ if [ $LOCK_COUNT -gt 10 ]; then
+ OBJECT_REORG_STATUS=ABORTED;
+ let NUM_REORGS_ABORTED+=1;
+ log 1 "Aborting table $TABSCHEMA.$TABNAME , LOCK_COUNT=$LOCK_COUNT";
+ fi
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$OBJECT_REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ continue;
+ fi
+
+ ##
+ ## do a check to see where we are on transaction log space - this could be improved!!!!
+ ##
+ #LOG_USED=$( db2 "select cast(LOG_UTILIZATION_PERCENT as decimal(5,2)) as PCTUSED, cast((TOTAL_LOG_USED_KB/1024) as Integer) as TOTUSEDMB, cast((TOTAL_LOG_AVAILABLE_KB/1024) as Integer) as TOTAVAILMB, cast((TOTAL_LOG_USED_TOP_KB/1024) as Integer) as TOTUSEDTOPMB FROM SYSIBMADM.LOG_UTILIZATION ");
+ LOG_USED=$( db2 -x "select LOG_UTILIZATION_PERCENT as PCTUSED FROM SYSIBMADM.MON_TRANSACTION_LOG_UTILIZATION " | tr -d ' ' )
+ if [ ! -z "$LOG_USED" ]; then
+ #PCTUSED=$( echo "$LOG_USED" | awk '{ if(NF==4 && $2 ~/^[0-9]+$/) print int($1)}' );
+ PCTUSED=$( echo $LOG_USED | awk '{print int($1)}')
+ if [ ! -z "$PCTUSED" ]; then
+ if [ $PCTUSED -gt $TRANSACTION_LOG_THRESHOLD_PCT ]; then
+ log 1 "Will not kick off another reorg due to logfile PCTUSED above threshold of $LOG_THRESHOLD% : $LOG_USED%"
+ continue
+ else
+ log 3 "Present LOG Utilization Percentage : $LOG_USED%"
+ fi
+ fi
+ fi
+
+ ##
+ ## kick off another reorg
+ ## if rc=0 then ok, else we ABORT the OBJECT and don't try again
+ ##
+
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+
+ if [ $isTable -eq 1 ]; then
+ log 3 "Processing reorg for table $TABSCHEMA.$TABNAME"
+ db2 "reorg table $TABSCHEMA.$TABNAME inplace allow write access" >> /dev/null 2>&1
+ rc=$?
+ #RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+
+ elif [ $isIndex -eq 1 ]; then
+ log 3 "Processing reorg for table $TABSCHEMA.$TABNAME"
+ db2 "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace allow write access" > /dev/null 2>&1
+ rc=$?
+ #RC=$( db2 "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ fi
+
+ elif [ $IF_STATS -eq 3 ]; then
+
+ ## for offline we throw a job at db2 and wait a few seconds and check the output
+ ## output could be "reorg indexes all for table ...",
+ ## or SQL error
+ ## or 'DB20000I The REORG command completed successfully.'
+ ## not sure if there is a better way to do this
+ TMPLOG="/tmp/$TABSCHEMA.$TABNAME.tmp";
+ log 3 "Processing reorg on indexes for table $TABSCHEMA.$TABNAME"
+ db2 -v "reorg indexes all for table $TABSCHEMA.$TABNAME allow write access" > $TMPLOG > /dev/null 2>&1 &
+ sleep 5;
+ cat $TMPLOG;
+ RC=$( grep '^SQL' $TMPLOG);
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ log 1 "Failed to kick off reorg\n$RC";
+ rc=1;
+ else
+ ## reorg could have finished then no need for the big sleep
+ RC=$( grep 'DB20000I The REORG command completed successfully.' $TMPLOG);
+ if [ $? -eq 0 ]; then
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=1;
+ fi
+ rc=0;
+
+ fi
+ rm -f $TMPLOG;
+
+ fi
+
+ if [ $rc -eq 0 ]; then
+ REORG_STATUS=KICKED_OFF;
+ else
+ REORG_STATUS=ABORTED;
+ fi
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ if [ $rc -ne 0 ]; then
+ let NUM_REORGS_ABORTED+=1;
+ continue
+ fi
+
+ ## add the table to the TABLE_IN_USE_ARRAY
+ addTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ log 1 "Failed to add table $TABSCHEMA.$TABNAME to TABLE_IN_USE_ARRAY";
+ fi
+ let NUM_REORGS_KICKED_OFF+=1;
+ let NUM_REORGS_IN_PROGRESS+=1;
+
+ continue;
+ fi
+
+ ##
+ ## ouput STATUS
+ ##
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+ #echo -e "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $RC \t: $REORG_PERCENT_COMPLETE %" | tee -a $REORG_TABLE_INDEX_DEBUG
+ printf "%-15s %-50s %-50s %-10s\n" "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS" "$TABSCHEMA.$TABNAME" "$RC" "COMPLETION: $REORG_PERCENT_COMPLETE %"| tee -a $REORG_TABLE_INDEX_DEBUG
+
+ elif [ $IF_STATS -eq 3 ]; then
+ #echo -e "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $REORG_INDEX_STATUS "| tee -a $REORG_TABLE_INDEX_DEBUG
+ printf "%-15s %-50s %-10s %15s\n" "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS" "$TABSCHEMA.$TABNAME" "$REORG_INDEX_STATUS" | tee -a $REORG_TABLE_INDEX_DEBUG
+ fi
+
+ ##
+ ## if reorg timeout then issue a stop to current reorgs that are STARTED
+ ## no error checking for stopping a reorg
+ ## no need to update OBJECT array as it will be updated on next loop
+ ##
+
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+
+ if [ "$REORG_STATUS" == "STARTED" ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+
+ if [ $isTable -eq 1 ]; then
+ db2 -v "reorg table $TABSCHEMA.$TABNAME inplace stop" > /dev/null 2>&1
+ rc=$?
+ elif [ $isIndex -eq 1 ]; then
+ db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace stop" > /dev/null 2>&1
+ rc=$?
+ fi
+ fi
+ fi
+
+ done ## for OBJECT_ARRAY[@]
+
+ ## check if we are done with all OBJECTS
+ if [ $((NUM_REORGS_COMPLETED + NUM_REORGS_STOPPED + NUM_REORGS_ABORTED)) -ge $NUM_REORG_OBJECTS ]; then
+ log 3 "Reorgs Status :: Completed : $NUM_REORGS_COMPLETED , Stopped : $NUM_REORGS_STOPPED , Aborted : $NUM_REORGS_ABORTED , Total No of Objects : $NUM_REORG_OBJECTS"
+ break
+ fi
+
+ ## wait some time
+ if [ $IF_STATS -eq 3 ] && [ $IF_STATS_BYPASS_SLEEP_INTERVAL_TIME -eq 1 ]; then
+ sleep 1;
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
+ else
+ sleep $SLEEP_INTERVAL_TIME
+ fi
+
+ done ## while true
+
+}
+
+# -- Main function starts here
+
+## init
+if [ -f ${HOME}/sqllib/db2profile ]; then
+ . ${HOME}/sqllib/db2profile
+fi
+
+## script already running ?
+if [ $( ps -ef | grep $0 | grep -v grep | wc -l ) -gt 2 ]; then
+ echo "Warning: appears $0 already running"
+ echo "$( ps -ef | grep $0 | grep -v grep )";
+ exit 1
+fi
+
+SCRIPT=$(basename $0)
+SCRIPT_DIR=$(dirname $0)
+WHOAMI=$(whoami)
+HOSTNAME=$(hostname)
+
+## setup some temp work files
+LOGDATE=$(date '+%Y%m%d');
+REORG_TABLE_INDEX_LOG=/tmp/${SCRIPT}.tmp.123.log
+rm -f $REORG_TABLE_INDEX_LOG
+REORG_TABLE_INDEX_DEBUG=/tmp/${SCRIPT}.debug
+rm -f $REORG_TABLE_INDEX_DEBUG
+
+## control variables
+LIST_ONLY=0
+LIST_FRAGMENTED_INDEXES=0
+LIST_VALID_TABLE_SIZES=0
+LIST_REORGCHK_TB_STATS_TABLES=0
+LIST_REORGCHK_IX_STATS_TABLES=0
+EXECUTE_TABLE_REORG=0
+IGNORE_TABLE_SIZE_THRESHOLD_MAX=100000;
+IGNORE_TABLE_SIZE_THRESHOLD_MIN=10;
+MAINTENANCE_TIMEOUT_WINDOW_MINUTES=240;
+REORG_TIMEOUT_WINDOW_ACTION=2;
+MAX_ASYNC_REORGS_ALLOWED=3;
+TRANSACTION_LOG_THRESHOLD_PCT=90;
+TB_STATS=0;
+IF_STATS=0;
+IX_STATS=0;
+TRSI=0
+IGNORE_TABLES_EX=" and t0.tabname not like '%\_H' escape '\' and t1.volatile != 'C' "
+IGNORE_TABLES="";
+REORG="*";
+SLEEP_INTERVAL_TIME=60;
+REORGCHK_TB_IF_STATS_OPTION="";
+REORGCHK_TB_STATS=1;
+REORGCHK_IF_STATS=3;
+
+## user check
+if [ $WHOAMI == "root" ]; then
+ log 0 " This script should be not run as '$WHOAMI', but as instance owner."
+ exit 1
+fi
+
+##
+## command line arguments
+##
+while [ $# -gt 0 ]
+do
+ case $1 in
+ -h|-H|-help|--help) UsageHelp; exit 1 ;;
+
+ -db|-d) shift; [ ! -z $1 ] && DBNAME=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -s) shift; [ ! -z $1 ] && SCHEMANAME_IN=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -t) shift; [ ! -z "$1" ] && TABLE_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -tb_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_TB_STATS; TB_STATS=1 ;;
+ -ti) shift; [ ! -z "$1" ] && INDEX_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ix_stats) IX_STATS=2 ;;
+ -if_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_IF_STATS; IF_STATS=3 ;;
+ -ittx) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MAX=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ittn) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MIN=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+
+ -l) LIST_ONLY=1 ;;
+ -lf) LIST_FRAGMENTED_INDEXES=1 ;;
+ -ls) LIST_VALID_TABLE_SIZES=1 ;;
+ -lt) LIST_REORGCHK_TB_STATS_TABLES=1 ;;
+ -li) LIST_REORGCHK_IX_STATS_TABLES=1 ;;
+
+ -window) shift; isNumeric $1 && { MAINTENANCE_TIMEOUT_WINDOW_MINUTES=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -twa) shift; isNumeric $1 && { REORG_TIMEOUT_WINDOW_ACTION=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -mar) shift; isNumeric $1 && { MAX_ASYNC_REORGS_ALLOWED=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -log) shift; isNumeric $1 && { TRANSACTION_LOG_THRESHOLD_PCT=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -tr) EXECUTE_TABLE_REORG=1 ;;
+
+ -trsi) TRSI=1 ;;
+ -reorg) shift; [ ! -z "$1" ] && REORG=$( echo "$1" ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ignore) shift; [ ! -z "$1" ] && { IGNORE_TABLES="$1"; } || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -sleep) shift; isNumeric $1 && { SLEEP_INTERVAL_TIME=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+
+ (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
+ (*) break;;
+ esac
+ shift
+done
+
+##
+## some verification
+##
+if [[ -z "$DBNAME" && -z "$SCHEMANAME_IN" ]]; then
+ log 0 "Please provide Database Name and Schema Name "
+ exit 1
+
+fi
+: '
+if [ -z "$SCHEMANAME_IN" ]; then
+ log 0 "must enter a schemaname"
+ exit 1
+fi
+'
+CHECK=1
+if [ $CHECK -eq 0 ]; then
+ rc=0
+ if [ $TB_STATS -eq 1 ] && [ $IX_STATS -eq 2 -o $IF_STATS -eq 3 ]; then
+ rc=1;
+ elif [ $IX_STATS -eq 2 ] && [ $TB_STATS -eq 1 -o $IF_STATS -eq 3 ]; then
+ rc=1;
+ elif [ $IF_STATS -eq 3 ] && [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
+ rc=1;
+ fi
+ if [ $rc -eq 1 ]; then
+ log 0 "can't define more than one of -tb_stats, -ix_stats or -if_stats"
+ exit 1
+ fi
+
+fi ## CHECK
+
+if [ $TB_STATS -eq 1 ] && [ ! -z "$INDEX_IN" ]; then
+ log 0 "can't define -ti with -tb_stats"
+ exit 1
+elif [ $IX_STATS -eq 2 ] && [ ! -z "$TABLE_IN" ]; then
+ log 0 "can't define -t with -ix_stats"
+ exit 1
+elif [ $IF_STATS -eq 3 ] && [ ! -z "$INDEX_IN" ]; then
+ log 0 "can't define -ti with -if_stats"
+ exit 1
+fi
+
+if [ $TRANSACTION_LOG_THRESHOLD_PCT -gt 99 ]; then
+ log 0 "-log option should be less than 100, TRANSACTION_LOG_THRESHOLD_PCT=$TRANSACTION_LOG_THRESHOLD_PCT"
+ exit 1
+fi
+if [ $IGNORE_TABLE_SIZE_THRESHOLD_MIN -ge $IGNORE_TABLE_SIZE_THRESHOLD_MAX ]; then
+ log 0 "option -ittx should be greater than option -ittn"
+ exit 1
+fi
+
+## override some defaults for offline reorgs
+#if [ $IF_STATS -eq 3 ]; then
+# MAX_ASYNC_REORGS_ALLOWED=1;
+# REORG_TIMEOUT_WINDOW_ACTION=1;
+# ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
+# SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
+#fi
+
+## fixup REORG filter string for grep
+REORG=$( echo "$REORG" | sed 's/*/\\*/g' | sed 's/-/\\-/g');
+
+## need to transform to seconds - easier to work with
+## 3/4 time is for reorgs , 1/4 for runstats
+MAINTENANCE_TIMEOUT_WINDOW_SECONDS=$(( 60 * MAINTENANCE_TIMEOUT_WINDOW_MINUTES ))
+REORG_TIMEOUT_WINDOW_SECONDS=$( echo $MAINTENANCE_TIMEOUT_WINDOW_SECONDS | awk '{ print int(0.75*$1) }');
+RUNSTATS_TIMEOUT_WINDOW_SECONDS=$( echo $MAINTENANCE_TIMEOUT_WINDOW_SECONDS | awk '{ print int(0.25*$1) }');
+
+# echo "$MAINTENANCE_TIMEOUT_WINDOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS"
+
+##
+## main
+##
+log 3 "Starting $0 at $(date) on $HOSTNAME"
+
+#DBNAMES=$( db2 list db directory | grep -E "alias|Indirect" | grep -B 1 Indirect | grep alias | awk '{print $4}' | sort )
+
+##
+## loops for all dbs
+##
+#for DBNAME in $DBNAMES
+#do
+
+ ## just process the one db
+# if [ ! -z "$DB" ] && [ "$DB" != "$DBNAME" ] ; then
+# continue
+# fi
+# DBNAME=${DB}
+ ## can't run script on a STANDBY db
+ ROLE=$(db2 "get db cfg for $DBNAME" | grep 'HADR database role' | cut -d '=' -f2 | sed 's/ *//g')
+ if [ -z "$ROLE" ] || [ "$ROLE" == "" ]; then
+ log 1 " Can't determine hadr database role from 'db2 get db cfg for $DBNAME'"
+ continue
+ elif [ "$ROLE" == "STANDBY" ]; then
+ log 1 " Can't run script '${0}' for $DBNAME with hadr database role '$ROLE'"
+ continue
+ fi
+
+ log 3 "DBNAME :: $DBNAME"
+
+ db2 connect to $DBNAME >> /dev/null 2>&1
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 " can't connect to $DBNAME"
+ continue
+ fi
+
+ if [ $TRSI -eq 1 ]; then
+ TRSI
+ continue
+
+ elif [ $LIST_VALID_TABLE_SIZES -eq 1 ]; then
+ getValidTableSizes
+ log 3 "The following $NUM_VALID_TABLES are valid table sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$VALID_TABLE_SIZES_RAW_DATA"
+ continue
+
+ elif [ $LIST_FRAGMENTED_INDEXES -eq 1 ]; then
+ getValidFragmentedIndexes
+ VALID_FRAMENTED_INDEXES_HEADER="TABSCHEMA TABNAME INDSCHEMA INDNAME INDCARD STATS_TIME LAST_USED NLEAF SEQUENTIAL_PAGES";
+ log 3 "The following $NUM_VALID_FRAGMENTED_INDEXES are fragmenated indexes based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$VALID_FRAMENTED_INDEXES_HEADER\n$VALID_FRAGMENTED_INDEXES_RAW_DATA"
+ continue;
+ elif [ $LIST_REORGCHK_TB_STATS_TABLES -eq 1 ]; then
+ getValidTablesToReorg
+ REORGCHK_TB_STATS_HEADER="TABLE_SCHEMA TABLE_NAME CARD OVERFLOW NPAGES FPAGES ACTIVE_BLOCKS TSIZE F1 F2 F3 REORG";
+ log 3 "The following $NUM_VALID_TABLES_TO_REORG are results from REORGCHK_TB_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$REORGCHK_TB_STATS_HEADER\n$VALID_TABLES_TO_REORG_RAW_DATA"
+ continue;
+
+ elif [ $LIST_REORGCHK_IX_STATS_TABLES -eq 1 ]; then
+ getValidIndexesToReorg
+ REORGCHK_IX_STAT_HEADER="TABLE_SCHEMA TABLE_NAME INDEX_SCHEMA INDEX_NAME INDCARD NLEAF NUM_EMPTY_LEAFS NLEVELS NUMRIDS_DELETED FULLKEYCARD LEAF_RECSIZE NONLEAF_RECSIZE LEAF_PAGE_OVERHEAD NONLEAF_PAGE_OVERHEAD PCT_PAGES_SAVED F4 F5 F6 F7 F8 REORG";
+ log 3 "The following $NUM_VALID_INDEXES_TO_REORG are results from REORGCHK_IX_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$REORGCHK_IX_STAT_HEADER\n$VALID_INDEXES_TO_REORG_RAW_DATA"
+ continue;
+
+ fi
+
+ INPLACE=1
+ if [ $INPLACE -eq 1 ]; then
+
+ log 3 "SCHEMA :: $SCHEMANAME_IN"
+ log 3 "TABLES :: $TABLE_IN"
+ log 3 "INDEXES :: $INDEX_IN"
+ log 3 "Looking for Qualified Tables or Indexes for $SCHEMANAME_IN in $DBNAME . . . "
+ echo ""
+
+ ##
+ ## input table(s) verification
+ ## verify input table exist
+ ## and table is within size limits
+ ## create the OBJECT_ARRAY that holds the relevant table information
+ ##
+ if [ ! -z "$TABLE_IN" ]; then
+
+ TABLE_IN=$( echo "$TABLE_IN" | tr ' ' '\n' );
+ for TABNAME in $TABLE_IN
+ do
+
+ ## make sure table exists
+ RC=$( db2 -x "select tabname from syscat.tables where tabname = '$TABNAME' and tabschema = '$SCHEMANAME_IN' and type = 'T'");
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "input command line table '$TABNAME' does not exist or is invalid"
+ exit 1
+ fi
+
+ isTableWithinSizeLimit $SCHEMANAME_IN $TABNAME
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
+ exit 1
+ fi
+
+ done
+
+ if [ $TB_STATS -eq 1 ]; then
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ $IF_STATS -eq 3 ]; then
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+
+ elif [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
+ for REORG_TYPE in 0 1
+ do
+ if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
+ getValidTablesToReorg
+ TABLE_IN="$VALID_TABLES_TO_REORG";
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
+ getValidFragmentedIndexes
+ TABLE_IN="$VALID_FRAGMENTED_INDEXES"
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+ done
+
+ elif [ $TB_STATS -eq 1 ]; then
+ getValidTablesToReorg
+ TABLE_IN="$VALID_TABLES_TO_REORG";
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ $IF_STATS -eq 3 ]; then
+ getValidFragmentedIndexes
+ TABLE_IN="$VALID_FRAGMENTED_INDEXES"
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+
+ ##
+ ## input indexes verification
+ ## verify input indexes exist
+ ##
+ if [ ! -z "$INDEX_IN" ]; then
+ INDEX_IN=$( echo "$INDEX_IN" | tr ' ' '\n' );
+ for INDEX in $INDEX_IN
+ do
+ ## make sure index exists, especially those input on command line
+ TABSCHEMA=$( echo $INDEX | cut -d. -f1);
+ TABNAME=$( echo $INDEX | cut -d. -f2);
+ INDSCHEMA=$( echo $INDEX | cut -d. -f3);
+ INDNAME=$( echo $INDEX | cut -d. -f4);
+ RC=$( db2 -x "select indname from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 " input command line index '$INDEX' does not exist"
+ exit 1
+ fi
+
+ isTableWithinSizeLimit $TABSCHEMA $TABNAME
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
+ exit 1
+ fi
+
+ done
+
+ createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
+ ##
+ ##
+ elif [ $IX_STATS -eq 2 ]; then
+ getValidIndexesToReorg
+ INDEX_IN="$VALID_INDEXES_TO_REORG"
+ createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
+ fi
+
+ ## get the NUMBER of tables per reorg table type
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $TB_STATS; OBJECT_NUM_TB_STATS=$?;
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IX_STATS; OBJECT_NUM_IX_STATS=$?;
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IF_STATS; OBJECT_NUM_IF_STATS=$?;
+
+ ## just list out the OBJECT_ARRAY and exit
+ if [ $LIST_ONLY -eq 1 ]; then
+
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+ listOBJECT_ARRAY;
+ exit 1
+ fi
+
+
+ if [ $EXECUTE_TABLE_REORG -eq 1 ]; then
+
+
+ ##
+ ## this is the main list of what we are going to reorg
+ ##
+ #echo ""
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+
+ listOBJECT_ARRAY;
+
+# exit 1
+
+ ##
+ ## setup some control variables for the main loop
+ ##
+ ## REORG_STATUS COMPLETED PAUSED STARTED STOPPED TRUNCATE
+ ##
+ MAINTENANCE_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+ REORG_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+ WINDOW_START_TIME_DB2=$( date '+%Y-%m-%d-%H.%M.%S' );
+ IF_STATS_WINDOW_START_TIME_DB2=$( date '+%s' );
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
+ NUM_REORG_OBJECTS="${#OBJECT_ARRAY[@]}";
+# NUM_REORGS_IN_PROGRESS=0;
+# NUM_REORGS_KICKED_OFF=0;
+# NUM_REORGS_COMPLETED=0;
+# NUM_REORGS_STOPPED=0;
+# NUM_REORGS_ABORTED=0;
+ REORG_TIMEOUT_OVERFLOW_VALVE=300;
+ REORG_TIMEOUT_WINDOW_COMPLETED=0;
+ REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=0;
+ initTABLE_IN_USE_ARRAY $MAX_ASYNC_REORGS_ALLOWED
+
+ ## multi table reorg option
+ ## online table reorg and offline index reorgs have different options
+ MAX_ASYNC_REORGS_ALLOWED_ORG=$MAX_ASYNC_REORGS_ALLOWED;
+ REORG_TIMEOUT_WINDOW_ACTION_ORG=$REORG_TIMEOUT_WINDOW_ACTION;
+ SLEEP_INTERVAL_TIME_ORG=$SLEEP_INTERVAL_TIME;
+
+ ## override some defaults for offline reorgs
+ #if [ $IF_STATS -eq 3 ]; then
+ # MAX_ASYNC_REORGS_ALLOWED=1;
+ # REORG_TIMEOUT_WINDOW_ACTION=1;
+ # ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
+ # SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
+ #fi
+
+ echo ""
+ log 3 "Starting reorg of ..."
+
+ if [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
+ for REORG_TYPE in 0 1
+ do
+
+ if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
+ TB_STATS=1;
+ IF_STATS=0;
+ NUM_REORG_OBJECTS=$OBJECT_NUM_TB_STATS;
+ REORG_TABLE_TYPE=$TB_STATS;
+ MAX_ASYNC_REORGS_ALLOWED=$MAX_ASYNC_REORGS_ALLOWED_ORG;
+ REORG_TIMEOUT_WINDOW_ACTION=$REORG_TIMEOUT_WINDOW_ACTION_ORG;
+ SLEEP_INTERVAL_TIME=$SLEEP_INTERVAL_TIME_ORG;
+
+ elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
+ TB_STATS=0;
+ IF_STATS=3;
+ NUM_REORG_OBJECTS=$OBJECT_NUM_IF_STATS;
+ REORG_TABLE_TYPE=$IF_STATS;
+ MAX_ASYNC_REORGS_ALLOWED=1;
+ REORG_TIMEOUT_WINDOW_ACTION=1;
+ SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME_ORG | awk '{ print $1/3 }');
+ fi
+
+ reorgTables
+ done
+ else
+ if [ $TB_STATS -eq 1 ]; then
+ REORG_TABLE_TYPE=$TB_STATS;
+ elif [ $IX_STATS -eq 2 ]; then
+ REORG_TABLE_TYPE=$IX_STATS;
+ elif [ $IF_STATS -eq 3 ]; then
+ REORG_TABLE_TYPE=$IF_STATS;
+ fi
+ reorgTables
+ fi
+
+ ## list current state of OBJECT_ARRAY
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+ listOBJECT_ARRAY;
+
+ ##
+ ## now do runstats
+ ##
+ log 3 "Starting runstats of ..."
+ RUNSTATS_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+
+ ## check runstats window maintenance time
+ MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
+ DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
+ if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + RUNSTATS_TIMEOUT_WINDOW_SECONDS)) ]; then
+ #log 3 "$REORG_TIMEOUT_WINDOW_START_TIME_SECONDS $MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS $DIFF"
+ log 3 "Runstats window ending, runstats window time exceeded"
+ break
+ fi
+
+ ## get table info
+ TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
+ TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
+ INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
+ INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
+ IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
+ OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
+
+ ## only do a runstats if table/index has completed
+ ## verify stats time so we dont kick off another runstats on the same table
+ if [ "$OBJECT_REORG_STATUS" == "COMPLETED" ]; then
+ STATS_TIME=$( db2 -x "select stats_time from syscat.tables where tabschema='$TABSCHEMA' and tabname='$TABNAME' and stats_time < TIMESTAMP('$WINDOW_START_TIME_DB2') " );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ log 3 "Starting runstats on $TABSCHEMA.$TABNAME"
+ # db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON ALL COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS";
+ #db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON KEY COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS UTIL_IMPACT_PRIORITY 50" > /dev/null 2>&1
+ db2 -v "runstats on table $TABSCHEMA.$TABNAME ON ALL COLUMNS WITH DISTRIBUTION ON ALL COLUMNS AND DETAILED INDEXES ALL ALLOW WRITE ACCESS " > /dev/null 2>&1
+ log 3 "Finished runstats on $TABSCHEMA.$TABNAME"
+ fi
+ fi
+
+ done
+
+ fi ## EXECUTE_TABLE_REORG
+
+ fi ## INPLACE
+
+#done ## DBNAMES
+
+##
+## cleanup
+##
+
+log 3 "Completed $0 at $(date)"
+exit 0
diff --git a/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2.sh b/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2.sh
deleted file mode 100644
index 6f594ba73..000000000
--- a/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2.sh
+++ /dev/null
@@ -1,1336 +0,0 @@
-#!/bin/sh
-##
-## HPS created Jan 2019
-##
-## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/
-## see Identifying fragmented indexes from statistics
-## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
-##0 23 * * 5 (. ~/sqllib/db2profile; ~/dba/bin/misc/reorgTablesIndexesInplace2.sh -s OMDB -tb_stats -if_stats -window 120 -tr >> ~/dba/logs/reorgTablesIndexesInplace2.sh.log 2>&1 )
-## script to reorg tables online and indexes offline based on different criteria
-## we need to be able to perform an online table reorg and an offline indexes all reorg in the same run of the script
-##
-
-UsageHelp()
-{
-
- echo "Script to perform reorg tables, indexes online (inplace) "
- echo " also to REORG INDEXES ALL FOR TABLE offline"
- echo " db2 performs the online reorgs asynchronously"
- echo ""
- echo "Usage: ${0} [options]"
- echo " where [options] is one of the following:"
- echo " -h: displays this usage screen"
- echo " -db: dbname, default is all cataloged databases"
- echo ""
- echo " -s: table schemaname"
- echo " -t: table(s) to reorg"
- echo "-tb_stats: reorg tables reported by REORGCHK_TB_STATS"
- echo " -ti: reorg table index(s), format must be TABSCHEMA.TABNAME.INDSCHEMA.INDNAME"
- echo "-ix_stats: reorg table index(s) reported by REORGCHK_IX_STATS"
- echo "-if_stats: reorg indexes all for table(s) offline as reported by index fragmentation NLEAF/SEQUENTIAL_PAGES columns"
- echo ""
- echo " -ls: list valid table sizes for a particular schema"
- echo " -lf: list all fragmented index details for a particular schema, based on valid table sizes"
- echo " -lt: list all tables to reorg based on REORGCHK_TB_STATS reorg column, based on valid table sizes"
- echo " -li: list all indexes to reorg based on REORGCHK_IX_STATS reorg column, based on valid table sizes"
- echo " -l: list tables/indexes that would be reorged"
- echo ""
- echo " -ittx: ignore tables over a specific threshold size in MBs, default is 20000 MB ie 20 GB"
- echo " -ittn: ignore tables under a specific threshold size in MBs, default is 10 MB"
- echo " -mar: maximum asynchronous reorgs allowed, default is 3"
- echo " -log: don't kick off a reorg if transaction log usage is over a certain percentage, default is 90%"
- echo " -window: stop reorg tables/indexes/runstats after a set maintenance timeout window, default is 240 minutes"
- echo " -twa: timeout window action: default=2 for online, 1 for offline"
- echo " 1=allow current reorg(s) to continue"
- echo " 2=stop current reorg(s)"
-# echo " 3=stop current reorg(s) if < 80% complete and continue script"
- echo " -ignore: ignore specific tables from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1 "
- echo " eg \"$IGNORE_TABLES_EX\""
- echo " -reorg: table F1 F2 F3 filter reorg, default is *"
- echo " -sleep: SLEEP_INTERVAL_TIME, default is 60 seconds"
- echo ""
- echo " -tr: execute inplace table/index reorg"
- echo ""
- echo " -trsi: Retrieve table reorganization snapshot information from snap_get_tab_reorg and db2pd -reorgs index"
- echo ""
- echo "Examples:"
- echo " 1. ${0} -h"
- echo " 2. ${0} -db dbname -s omdb -ls"
- echo " 3. ${0} -s OMDB -t \"YFS_ITEM YFS_TASK_Q YFS_SHIPMENT\" -tb_stats -tr "
- echo " 4. ${0} -s OMDB -ti \"OMDB.YFS_SNAPSHOT.OMDB.YFS_SNAPSHOT_I1 OMDB.YFS_ITEM.OMDB.YFS_ITEM_PK\" -ix_stats -tr"
- echo " 5. ${0} -s OMDB -t \"YFS_ITEM YFS_SNAPSHOT YFS_IMPORT YFS_EXPORT\" -if_stats -tr"
- echo " 6. ${0} -s OMDB -tb_stats -mar 5 -window 10 -log 95 -ittx 30000 -tr"
- echo " 7. ${0} -s OMDB -tb_stats -mar 5 -window 10 -log 95 -ignore \"$IGNORE_TABLES_EX\" -reorg \"***\" -tr"
- echo " 8. ${0} -s OMDB -tb_stats -if_stats -ittx 100 -ittn 20 -tr"
- echo " 9. ${0} -trsi"
-
- echo ""
-
-}
-
-##
-## function to check if a string is numeric
-##
-isNumeric()
-{
- echo $1 | grep -E '^[0-9]+$' > /dev/null
-
- return $?
-
-}
-
-
-TRSI()
-{
- db2 -v "select varchar(tabschema,9) as tabschema, varchar(tabname,32) as tabname,
- REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER,
--- varchar( varchar_format(REORG_START, 'YYYY-MM-DD HH24:MI:SS'),19) as REORG_START,
--- varchar( varchar_format(REORG_END, 'YYYY-MM-DD HH24:MI:SS'),19) as REORG_END,
- REORG_START, REORG_END,
- REORG_INDEX_ID, REORG_TBSPC_ID
- from table(snap_get_tab_reorg(''))
- order by REORG_START asc
- with ur"
-
- db2pd -db $DBNAME -reorgs index | sed -n "/Index Reorg Stats:/,//p"
-
-
-}
-
-log()
-{
- TYPE=$1
- MSG="$2"
-
- DATE=$( date '+%d-%m-%Y %H:%M:%S' );
-
- # TYPE:
- # 0 = Critical
- # 1 = Warn
- # 3 = Info
- # 5 = Debug'
- if [ ${TYPE} -eq 0 ]; then
- TYPEMSG="Error"
- elif [ ${TYPE} -eq 1 ]; then
- TYPEMSG="Warning"
- elif [ ${TYPE} -eq 3 ]; then
- TYPEMSG="Info"
- elif [ ${TYPE} -eq 5 ]; then
- TYPEMSG="Debug"
- else
- TYPEMSG="Other"
- fi
-
- echo -e "${DATE} ${TYPEMSG}: ${MSG}" | tee -a $REORG_TABLE_INDEX_LOG
-
- return 0
-}
-
-initTABLE_IN_USE_ARRAY()
-{
-
- local NUM_ITEMS=$1
- local jj;
-
- ##
- ## initialise the db2 TABLE_IN_USE_ARRAY
- ##
- for((jj=0; jj<$NUM_ITEMS; jj++))
- do
- TABLE_IN_USE_ARRAY[$jj]=""
- done
-
- return 0
-
-}
-
-existTABLE_TABLE_IN_USE_ARRAY()
-{
-
- local TABLE=$1
- local jj;
- ##
- ## check if table is in use
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
- return 0;
- fi
- done
-
- return 1;
-
-}
-
-addTABLE_TABLE_IN_USE_ARRAY()
-{
-
- local TABLE=$1
- local jj;
-
- ##
- ## add table in empty slot
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "" ]; then
- TABLE_IN_USE_ARRAY[$jj]=$TABLE;
- return 0;
- fi
- done
-
- return 1;
-}
-
-removeTABLE_TABLE_IN_USE_ARRAY()
-{
-
- local TABLE=$1
- local jj;
- ##
- ## remove entry
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
- TABLE_IN_USE_ARRAY[$jj]="";
- return 0;
- fi
- done
-
- return 1;
-
-}
-
-
-listTABLE_IN_USE_ARRAY()
-{
-
- local jj;
- ##
- ## list table entries
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- log 5 "TABLE_IN_USE_ARRAY $jj ${TABLE_IN_USE_ARRAY[$jj]}";
- done
-
- return 0;
-
-}
-
-getValidTablesToReorg()
-{
-
- getValidTableSizes
-
- VALID_TABLES_TO_REORG=""
- VALID_TABLES_TO_REORG_RAW=""
- NUM_VALID_TABLES_TO_REORG=0
- for TABNAME in $VALID_TABLES
- do
-
- RAW=$( db2 -x "call REORGCHK_TB_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
- RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 12) print $0 }' | sed 's/ \+/ /g' | grep $REORG )
- rc=$?
- if [ $rc -eq 0 ]; then
- TABNAME=$( echo "$RAW" | awk '{print $2}' );
- [ "$VALID_TABLES_TO_REORG_RAW_DATA" == "" ] && VALID_TABLES_TO_REORG_RAW_DATA="$RAW" || VALID_TABLES_TO_REORG_RAW_DATA="$VALID_TABLES_TO_REORG_RAW_DATA\n$RAW"
- fi
-
- done
-
- ## sort the tables based on REORG column
- VALID_TABLES_TO_REORG_RAW_DATA=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | sort -k12 -r);
- VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | awk '{print $2}' );
- NUM_VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG" | wc -l );
-
- return 0
-
-}
-
-getValidIndexesToReorg()
-{
-
- getValidTableSizes
-
- VALID_INDEXES_TO_REORG=""
- VALID_INDEXES_TO_REORG_RAW=""
- NUM_VALID_INDEXES_TO_REORG=0
- for TABNAME in $VALID_TABLES
- do
-
- RAW=$( db2 -x "call REORGCHK_IX_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
- ## this can return multiple indexes for same TABNAME
- RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 21) print $0 }' | sed 's/ \+/ /g' | grep $REORG );
- rc=$?
- if [ $rc -eq 0 ]; then
- INDNAME=$( echo "$RAW" | awk '{print $1"."$2"."$3"."$4}' );
- [ "$VALID_INDEXES_TO_REORG_RAW_DATA" == "" ] && VALID_INDEXES_TO_REORG_RAW_DATA=$RAW || VALID_INDEXES_TO_REORG_RAW_DATA="$VALID_INDEXES_TO_REORG_RAW_DATA\n$RAW"
- fi
-
- done
-
- ## sort the indexes based on REORG column
- VALID_INDEXES_TO_REORG_RAW_DATA=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | sort -k21 -r);
- VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | awk '{print $1"."$2"."$3"."$4}' );
- NUM_VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG" | wc -l );
-
- return 0
-
-}
-
-getValidFragmentedIndexes()
-{
-
- ##
- ## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
- ##
-
- getValidTableSizes
-
- VALID_FRAGMENTED_INDEXES_RAW_DATA=$( db2 -x "select rtrim(tabschema)||' '||rtrim(tabname)||' '||rtrim(indschema)||' '||rtrim(indname)
- ||' '||indcard||' '||stats_time||' '||lastused||' '||nleaf||' '||sequential_pages
- from syscat.indexes where tabschema='$SCHEMANAME_IN'
- and not (nleaf = 1 and sequential_pages = 0)
- and not (nleaf = 0 and sequential_pages = 1)
- and (nleaf - sequential_pages > 10)
- and tabname in ( $VALID_TABLES_FORMATTED )
- order by tabname
- with ur"; );
-
- VALID_FRAGMENTED_INDEXES_RAW_DATA=$(echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' );
- VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' | cut -d' ' -f2 | uniq )
- NUM_VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES}" | wc -l )
-
-
-}
-
-getValidTableSizes()
-{
-
- VALID_TABLE_SIZES_RAW_DATA=$( db2 "select t0.tabname,
- ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB,
- cast ((INDEX_OBJECT_P_SIZE / 1024) as integer) as INDEX_SIZE_MB
- from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1
- where t0.tabschema='$SCHEMANAME_IN'
- and t0.tabschema=t1.tabschema
- and t0.tabname=t1.tabname
- $IGNORE_TABLES
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
- order by 2 desc
- with ur"; );
- rc=$?
- if [ $rc -eq 0 ]; then
- VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES_RAW_DATA" | sed '1,3d' | sed '$d' | sed '$d' );
- VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; printf "\n"; }');
- VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | awk '{print $1}' );
- NUM_VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | wc -l );
- # log 3 "NUM_VALID_TABLES=$NUM_VALID_TABLES"
-
- VALID_TABLES_FORMATTED=""
- for TABLE in $VALID_TABLES
- do
- VALID_TABLES_FORMATTED="$VALID_TABLES_FORMATTED'$TABLE',"
- done
- VALID_TABLES_FORMATTED=$( echo "$VALID_TABLES_FORMATTED" | sed 's/,$//g' )
- else
- VALID_TABLES_FORMATTED="'UNKNOWN_TABNAME'"
- fi
-
-}
-
-## is TABLE within size limits < IGNORE_TABLE_SIZE_THRESHOLD_MAX and > IGNORE_TABLE_SIZE_THRESHOLD_MIN
-isTableWithinSizeLimit()
-{
- local SCHEMANAME=$1
- local TABNAME=$2
- local RC=""
- local rc=0
-
- RC=$( db2 -x "select tabname,
- ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB
- from SYSIBMADM.ADMINTABINFO
- where tabschema='$SCHEMANAME'
- and tabname = '$TABNAME'
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
- order by 2 desc
- with ur" );
-
- rc=$?
- return $rc
-
-}
-
-## create an list/array of table objects to reorg based on tabnames
-createTableOBJECT_ARRAY()
-{
- local TABNAMES="$1"
- local OBJECT_REORG_TABLE_TYPE=$2
-
- ##
- ## make the OBJECT_ARRAY for tables and indexes
- ##
- if [ -z "$OBJECT_ARRAY" ]; then
- local let index=0;
- else
- local let index=${#OBJECT_ARRAY[@]};
- fi
- local TID=0 ## Table ID - always 0 for online table reorg
- local INDSCHEMA=NULL;
- local INDNAME=NULL;
- local LOCK_COUNT=0
-
- for TABNAME in $TABNAMES
- do
- ## we need TABLEID, TBSPACEID for IF_STATS as the full TableName: may not be dispalyed in the db2pd output
- local RC=$( db2 -x "select TABLEID, TBSPACEID from syscat.tables where tabname='$TABNAME' and tabschema='$SCHEMANAME_IN'" )
- local rc=$?
- if [ $rc -eq 0 ]; then
- local TABLEID=$( echo $RC | awk '{print $1}' );
- local TBSPACEID=$( echo $RC | awk '{print $2}' );
- OBJECT_ARRAY[$index]="$SCHEMANAME_IN#$TABNAME#$INDSCHEMA#$INDNAME#$TID#NOTSTARTED#2019-01-01-00.00.00#2019-01-01-00.00.00#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- let index+=1
- fi
- done
-
-}
-
-## create an list/array of table objects to reorg based on indnames
-createIndexOBJECT_ARRAY()
-{
-
- local INDNAMES="$1"
- local OBJECT_REORG_TABLE_TYPE=$2
- local let index=0
- local TABLEID=9999;
- local TBSPACEID=9999;
- local LOCK_COUNT=0;
-
- for INDEX in $INDNAMES
- do
- local TABSCHEMA=$( echo $INDEX | cut -d. -f1);
- local TABNAME=$( echo $INDEX | cut -d. -f2);
- local INDSCHEMA=$( echo $INDEX | cut -d. -f3);
- local INDNAME=$( echo $INDEX | cut -d. -f4);
- local RC=$( db2 -x "select IID from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
- local rc=$?
- if [ $rc -eq 0 ]; then
- local IID=$( echo $RC | cut -d' ' -f1);
- OBJECT_ARRAY[$index]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#NOTSTARTED#2019-01-01-00.00.00#2019-01-01-00.00.00#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- let index+=1
- fi
- done
-
-}
-
-##
-## list out the objects and state
-## this can be used for debugging
-##
-listOBJECT_ARRAY()
-{
-
- local ii;
- log 3 "The following is for debug purposes, Num objects=${#OBJECT_ARRAY[@]}, $OBJECT_NUM_TB_STATS:$OBJECT_NUM_IX_STATS:$OBJECT_NUM_IF_STATS"
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- echo "${OBJECT_ARRAY[$ii]}" | tee -a $REORG_TABLE_INDEX_DEBUG
- done
-
-}
-
-## get the number tb_stats, ix_stats and if_stats objects
-getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY()
-{
-
- local rc=0;
- local ii;
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- if [ $( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 ) -eq $1 ]; then
- let rc+=1;
- fi
- done
-
- return $rc;
-
-}
-
-##
-## the main event
-##
-reorgTables()
-{
-
- ## variables that need to be reset on each run of the function
- NUM_REORGS_IN_PROGRESS=0;
- NUM_REORGS_KICKED_OFF=0;
- NUM_REORGS_COMPLETED=0;
- NUM_REORGS_STOPPED=0;
- NUM_REORGS_ABORTED=0;
-
- while true
- do
-
- ## check reorg window maintenance time
- MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
- DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
-
- ## safety valve - if for some reason the logic can't stop the reorgs
- if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + REORG_TIMEOUT_OVERFLOW_VALVE )) ]; then
- log 1 "REORG_TIMEOUT_OVERFLOW_VALVE detected";
- log 1 "Aborting reorgs"
- break;
- fi
-
- if [ $DIFF -ge $REORG_TIMEOUT_WINDOW_SECONDS ]; then
-
- REORG_TIMEOUT_WINDOW_COMPLETED=1;
-
- ## -twa: timeout window action: default=3
- ## 1=allow current reorg(s) to continue
- ## 2=stop current reorg(s)
- ## 3=stop current reorg(s) if < 80% complete
- if [ $REORG_TIMEOUT_WINDOW_ACTION -eq 1 ]; then
-
- log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
- break
-
- elif [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ]; then
-
- ## use of the REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER
- ## 0 = ABORT those not started and issue a STOP to those STARTED
- ## 1 = loop again and see if script exits as all reorgs are COMPLETED and STOPPED and ABORTED
- ## 2 = break out
- if [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 0 ]; then
- let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
- log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
- log 3 "Aborting reorgs NOTSTARTED and issuing a STOP to those that are STARTED"
- elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
- let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
- log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
- elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 2 ]; then
- log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
- log 3 "breaking out of reorg loop"
- break;
- fi
-
- fi
-
- fi
-
- ## loop for all OBJECTS - extract relevant data from OBJECT array
- ## if we have NOTSTARTED in the OBJECT_ARRAY[N] - then kick off a reorg
- ## then check tables reorg status
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- ## get table related info
- TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
- TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
- INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
- INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
- IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
- OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
- OBJECT_REORG_START=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f7 );
- OBJECT_REORG_END=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f8 );
- TABLEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f9 );
- TBSPACEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f10 );
- LOCK_COUNT=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f11 );
- OBJECT_REORG_TABLE_TYPE=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 );
- isTable=0;
- isIndex=0;
- if [ "$INDSCHEMA" == "NULL" -a "$INDNAME" == "NULL" ]; then
- isTable=1;
- else
- isIndex=1;
- fi
-
- if [ $OBJECT_REORG_TABLE_TYPE -ne $REORG_TABLE_TYPE ]; then
- continue;
- fi
-
- # log 5 "${OBJECT_ARRAY[$ii]}"
-
- ##
- ## has OBJECT COMPLETED - no need to continue here
- ##
- if [ "$OBJECT_REORG_STATUS" == "COMPLETED" -o "$OBJECT_REORG_STATUS" == "STOPPED" -o "$OBJECT_REORG_STATUS" == "ABORTED" ]; then
- continue;
- fi
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- ##
- ## query db2 for REORG_STATUS etc - there may not be an entry so carry on
- ##
- RC_SNAP=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER, REORG_START, REORG_END, REORG_INDEX_ID, REORG_TBSPC_ID from table(snap_get_tab_reorg('')) where tabschema='$TABSCHEMA' and tabname='$TABNAME' and REORG_START > TIMESTAMP('$WINDOW_START_TIME_DB2') and REORG_INDEX_ID=$IID");
- rc=$?
- if [ $rc -ge 2 ]; then
- log 0 "Possible error running select query against db2\nrc=$rc\nRC=$RC"
- continue;
- fi
-
- if [ $rc -eq 0 ]; then
- RC=$( echo "$RC_SNAP" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; }')
- REORG_STATUS=$( echo "$RC_SNAP" | awk '{print $1}' );
- REORG_COMPLETION=$( echo "$RC_SNAP" | awk '{print $2}' );
- REORG_CURRENT_COUNTER=$( echo "$RC_SNAP" | awk '{print $4}' );
- REORG_MAX_COUNTER=$( echo "$RC_SNAP" | awk '{print $5}' );
- REORG_START=$( echo "$RC_SNAP" | awk '{print $6}' );
- REORG_END=$( echo "$RC_SNAP" | awk '{print $7}' );
- REORG_INDEX_ID=$( echo "$RC_SNAP" | awk '{print $8}' );
-
- REORG_PERCENT_COMPLETE=0
- if [ ! -z "$REORG_CURRENT_COUNTER" -a $REORG_CURRENT_COUNTER -gt 0 ]; then
- if [ ! -z "$REORG_MAX_COUNTER" -a $REORG_MAX_COUNTER -gt 0 ]; then
- if [ $REORG_MAX_COUNTER -ge $REORG_CURRENT_COUNTER ]; then
- REORG_PERCENT_COMPLETE=$( echo $REORG_CURRENT_COUNTER $REORG_MAX_COUNTER | awk '{ print int (($1/$2)*100) }' );
- fi
- fi
- fi
- fi
-
- # log 5 "RC_SNAP=$RC_SNAP"
-
- elif [ $IF_STATS -eq 3 ]; then
-
- DB2PD_REORG_INDEX_RECORD=$( db2pd -db $DBNAME -reorgs index | grep -B1 -A11 -w "^TbspaceID: $TBSPACEID" | grep -B1 -A11 -w "TableID: $TABLEID" );
- rc=$?
- if [ $rc -eq 0 ]; then
- REORG_START=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | awk '{ print $3,$4}' );
- REORG_START_SECONDS=$(date --d="$REORG_START" '+%s');
-
- if [ $REORG_START_SECONDS -ge $IF_STATS_WINDOW_START_TIME_DB2 ]; then
- REORG_STATUS=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Status:' | awk '{ $1=""; print $0}' | sed 's/^[ \t]*//;s/[ \t]*$//' );
- ## some differences between snap_get_tab_reorg and db2pd -reogrs index output
- if [ "$REORG_STATUS" == "In Progress" ]; then
- REORG_STATUS="STARTED";
- elif [ "$REORG_STATUS" == "Completed" ]; then
- REORG_STATUS="COMPLETED";
- elif [ "$REORG_STATUS" == "Stopped" ]; then
- REORG_STATUS="STOPPED";
- fi
-
- REORG_END=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | grep 'End Time:' | awk '{ print $7,$8}' );
- fi
-
- fi
-
-
- fi
-
-
- ##
- ## has OBJECT been KICKED_OFF or STARTED
- ## if it has check to see if is STARTED or COMPLETED
- ## update OBJECT_ARRAY
- ## update COMPLETION/STOPPED stats
- ##
- if [ "$OBJECT_REORG_STATUS" == "KICKED_OFF" ] || [ "$OBJECT_REORG_STATUS" == "STARTED" ]; then
- if [ ! -z "$REORG_STATUS" ]; then
- if [ "$REORG_STATUS" == "STARTED" -o "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$REORG_START#$REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- fi
-
- if [ "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
-
- removeTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- if [ $rc -eq 1 ]; then
- log 1 "Failed to remove table $TABSCHEMA.$TABNAME from TABLE_IN_USE_ARRAY";
- fi
-
- if [ "$REORG_STATUS" == "COMPLETED" ]; then
- let NUM_REORGS_COMPLETED+=1
- elif [ "$REORG_STATUS" == "STOPPED" ]; then
- let NUM_REORGS_STOPPED+=1
- fi
-
- let NUM_REORGS_IN_PROGRESS-=1
- fi
-
- fi
-
- ##
- ## OBJECT is NOSTARTED so KICK_OFF a reorg
- ##
- elif [ "$OBJECT_REORG_STATUS" == "NOTSTARTED" ]; then
-
- ## dont kick off any reorgs if window timeout passed and TWA=2
- ## OBJECTS become ABORTED - UPDATE OBJECT_ARRAY
- if [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
- REORG_STATUS=ABORTED;
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- let NUM_REORGS_ABORTED+=1;
- continue;
-
- fi
-
- ## is the TABLE already being used -if it is goto next OBJECT
- existTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- [ $rc -eq 0 ] && continue;
-
- ## we only want to kick off so many reorgs at any one time
- if [ $NUM_REORGS_IN_PROGRESS -eq $MAX_ASYNC_REORGS_ALLOWED ]; then
- continue;
- fi
-
- ##
- ## The table could already be locked - if it is then by-pass it
- ## and ABORT if locked more than 10 times
- ##
- TABLE_LOCKED=$( db2 "select APPLICATION_HANDLE, LOCK_OBJECT_TYPE, LOCK_MODE, LOCK_CURRENT_MODE, LOCK_STATUS, LOCK_COUNT, LOCK_HOLD_COUNT, TBSP_ID, TAB_FILE_ID from TABLE (MON_GET_LOCKS(NULL, -2)) where TBSP_ID=$TBSPACEID and TAB_FILE_ID=$TABLEID and LOCK_OBJECT_TYPE='TABLE' and LOCK_MODE='IX' with ur"; );
- rc=$?
- if [ $rc -eq 0 ]; then
- let LOCK_COUNT+=1;
- log 1 "Appears table $TABSCHEMA.$TABNAME is already locked by another application(s), LOCK_COUNT=$LOCK_COUNT";
- log 1 "$TABLE_LOCKED";
- if [ $LOCK_COUNT -gt 10 ]; then
- OBJECT_REORG_STATUS=ABORTED;
- let NUM_REORGS_ABORTED+=1;
- log 1 "Aborting table $TABSCHEMA.$TABNAME , LOCK_COUNT=$LOCK_COUNT";
- fi
-OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$OBJECT_REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- continue;
- fi
-
- ##
- ## do a check to see where we are on transaction log space - this could be improved!!!!
- ##
- LOG_USED=$( db2 "select cast(LOG_UTILIZATION_PERCENT as decimal(5,2)) as PCTUSED, cast((TOTAL_LOG_USED_KB/1024) as Integer) as TOTUSEDMB, cast((TOTAL_LOG_AVAILABLE_KB/1024) as Integer) as TOTAVAILMB, cast((TOTAL_LOG_USED_TOP_KB/1024) as Integer) as TOTUSEDTOPMB FROM SYSIBMADM.LOG_UTILIZATION ");
- if [ ! -z "$LOG_USED" ]; then
- PCTUSED=$( echo "$LOG_USED" | awk '{ if(NF==4 && $2 ~/^[0-9]+$/) print int($1)}' );
- if [ ! -z "$PCTUSED" ]; then
- if [ $PCTUSED -gt $TRANSACTION_LOG_THRESHOLD_PCT ]; then
- log 1 "Will not kick off another reorg due to logfile PCTUSED above threshold of $LOG_THRESHOLD\n$LOG_USED"
- continue
- else
- log 3 "$LOG_USED"
- fi
- fi
- fi
-
- ##
- ## kick off another reorg
- ## if rc=0 then ok, else we ABORT the OBJECT and don't try again
- ##
- log 3 ""
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- if [ $isTable -eq 1 ]; then
-
- db2 -v "reorg table $TABSCHEMA.$TABNAME inplace allow write access"
- rc=$?
-
- elif [ $isIndex -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace allow write access"
- rc=$?
- fi
-
- elif [ $IF_STATS -eq 3 ]; then
-
- ## for offline we throw a job at db2 and wait a few seconds and check the output
- ## output could be "reorg indexes all for table ...",
- ## or SQL error
- ## or 'DB20000I The REORG command completed successfully.'
- ## not sure if there is a better way to do this
- TMPLOG="/tmp/$TABSCHEMA.$TABNAME.tmp";
- db2 -v "reorg indexes all for table $TABSCHEMA.$TABNAME allow write access" > $TMPLOG 2>&1 &
- sleep 5;
- cat $TMPLOG;
- RC=$( grep '^SQL' $TMPLOG);
- rc=$?
- if [ $rc -eq 0 ]; then
- log 1 "Failed to kick off reorg\n$RC";
- rc=1;
- else
- ## reorg could have finished then no need for the big sleep
- RC=$( grep 'DB20000I The REORG command completed successfully.' $TMPLOG);
- if [ $? -eq 0 ]; then
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=1;
- fi
- rc=0;
-
- fi
- rm -f $TMPLOG;
-
- fi
-
- if [ $rc -eq 0 ]; then
- REORG_STATUS=KICKED_OFF;
- else
- REORG_STATUS=ABORTED;
- fi
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- if [ $rc -ne 0 ]; then
- let NUM_REORGS_ABORTED+=1;
- continue
- fi
-
- ## add the table to the TABLE_IN_USE_ARRAY
- addTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- if [ $rc -eq 1 ]; then
- log 1 "Failed to add table $TABSCHEMA.$TABNAME to TABLE_IN_USE_ARRAY";
- fi
- let NUM_REORGS_KICKED_OFF+=1;
- let NUM_REORGS_IN_PROGRESS+=1;
-
- continue;
-
- fi
-
- ##
- ## ouput STATUS
- ##
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
- log 3 "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $RC : $REORG_PERCENT_COMPLETE %" | tee -a $REORG_TABLE_INDEX_DEBUG
- elif [ $IF_STATS -eq 3 ]; then
- log 3 "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME \n$DB2PD_REORG_INDEX_RECORD "| tee -a $REORG_TABLE_INDEX_DEBUG
-
- fi
-
- ##
- ## if reorg timeout then issue a stop to current reorgs that are STARTED
- ## no error checking for stopping a reorg
- ## no need to update OBJECT array as it will be updated on next loop
- ##
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- if [ "$REORG_STATUS" == "STARTED" ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
-
-
- if [ $isTable -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME inplace stop"
- rc=$?
- elif [ $isIndex -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace stop"
- rc=$?
- fi
-
- fi
-
- fi
-
- done ## for OBJECT_ARRAY[@]
-
- ## check if we are done with all OBJECTS
- if [ $((NUM_REORGS_COMPLETED + NUM_REORGS_STOPPED + NUM_REORGS_ABORTED)) -ge $NUM_REORG_OBJECTS ]; then
- log 3 "All reorgs are completed, stopped or aborted, $NUM_REORGS_COMPLETED:$NUM_REORGS_STOPPED:$NUM_REORGS_ABORTED:$NUM_REORG_OBJECTS"
- break
- fi
-
- ## wait some time
- if [ $IF_STATS -eq 3 ] && [ $IF_STATS_BYPASS_SLEEP_INTERVAL_TIME -eq 1 ]; then
- sleep 1;
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
- else
- sleep $SLEEP_INTERVAL_TIME
- fi
-
- done ## while true
-
-}
-
-
-## init
-if [ -f ${HOME}/sqllib/db2profile ]; then
- . ${HOME}/sqllib/db2profile
-fi
-
-## script already running ?
-if [ $( ps -ef | grep $0 | grep -v grep | wc -l ) -gt 2 ]; then
- echo "Warning: appears $0 already running"
- echo "$( ps -ef | grep $0 | grep -v grep )";
- exit 1
-fi
-
-SCRIPT=$(basename $0)
-SCRIPT_DIR=$(dirname $0)
-WHOAMI=$(whoami)
-HOSTNAME=$(hostname)
-
-## setup some temp work files
-LOGDATE=$(date '+%Y%m%d');
-REORG_TABLE_INDEX_LOG=/tmp/${SCRIPT}.tmp.123.log
-rm -f $REORG_TABLE_INDEX_LOG
-REORG_TABLE_INDEX_DEBUG=/tmp/${SCRIPT}.debug
-rm -f $REORG_TABLE_INDEX_DEBUG
-
-## control variables
-LIST_ONLY=0
-LIST_FRAGMENTED_INDEXES=0
-LIST_VALID_TABLE_SIZES=0
-LIST_REORGCHK_TB_STATS_TABLES=0
-LIST_REORGCHK_IX_STATS_TABLES=0
-EXECUTE_TABLE_REORG=0
-IGNORE_TABLE_SIZE_THRESHOLD_MAX=20000;
-IGNORE_TABLE_SIZE_THRESHOLD_MIN=10;
-MAINTENANCE_TIMEOUT_WINDOW_MINUTES=240;
-REORG_TIMEOUT_WINDOW_ACTION=2;
-MAX_ASYNC_REORGS_ALLOWED=3;
-TRANSACTION_LOG_THRESHOLD_PCT=90;
-TB_STATS=0;
-IF_STATS=0;
-IX_STATS=0;
-TRSI=0
-IGNORE_TABLES_EX=" and t0.tabname not like '%\_H' escape '\' and t1.volatile != 'C' "
-IGNORE_TABLES="";
-REORG="*";
-SLEEP_INTERVAL_TIME=60;
-REORGCHK_TB_IF_STATS_OPTION="";
-REORGCHK_TB_STATS=1;
-REORGCHK_IF_STATS=3;
-
-## user check
-if [ $WHOAMI == "root" ]; then
- log 0 " This script should be not run as '$WHOAMI', but as instance owner."
- exit 1
-fi
-
-##
-## command line arguments
-##
-while [ $# -gt 0 ]
-do
- case $1 in
- -h|-H|-help|--help) UsageHelp; exit 1 ;;
-
- -db) shift; [ ! -z $1 ] && DB=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -s) shift; [ ! -z $1 ] && SCHEMANAME_IN=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -t) shift; [ ! -z "$1" ] && TABLE_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -tb_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_TB_STATS; TB_STATS=1 ;;
- -ti) shift; [ ! -z "$1" ] && INDEX_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -ix_stats) IX_STATS=2 ;;
- -if_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_IF_STATS; IF_STATS=3 ;;
- -ittx) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MAX=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -ittn) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MIN=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -l) LIST_ONLY=1 ;;
- -lf) LIST_FRAGMENTED_INDEXES=1 ;;
- -ls) LIST_VALID_TABLE_SIZES=1 ;;
- -lt) LIST_REORGCHK_TB_STATS_TABLES=1 ;;
- -li) LIST_REORGCHK_IX_STATS_TABLES=1 ;;
-
- -window) shift; isNumeric $1 && { MAINTENANCE_TIMEOUT_WINDOW_MINUTES=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -twa) shift; isNumeric $1 && { REORG_TIMEOUT_WINDOW_ACTION=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -mar) shift; isNumeric $1 && { MAX_ASYNC_REORGS_ALLOWED=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -log) shift; isNumeric $1 && { TRANSACTION_LOG_THRESHOLD_PCT=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -tr) EXECUTE_TABLE_REORG=1 ;;
-
- -trsi) TRSI=1 ;;
- -reorg) shift; [ ! -z "$1" ] && REORG=$( echo "$1" ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -ignore) shift; [ ! -z "$1" ] && { IGNORE_TABLES="$1"; } || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -sleep) shift; isNumeric $1 && { SLEEP_INTERVAL_TIME=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
-
- (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
- (*) break;;
- esac
-
- shift
-
-done
-
-##
-## some verification
-##
-if [ -z "$SCHEMANAME_IN" ]; then
- log 0 "must enter a schemaname"
- exit 1
-fi
-
-CHECK=1
-if [ $CHECK -eq 0 ]; then
- rc=0
- if [ $TB_STATS -eq 1 ] && [ $IX_STATS -eq 2 -o $IF_STATS -eq 3 ]; then
- rc=1;
- elif [ $IX_STATS -eq 2 ] && [ $TB_STATS -eq 1 -o $IF_STATS -eq 3 ]; then
- rc=1;
- elif [ $IF_STATS -eq 3 ] && [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
- rc=1;
- fi
- if [ $rc -eq 1 ]; then
- log 0 "can't define more than one of -tb_stats, -ix_stats or -if_stats"
- exit 1
- fi
-
-fi ## CHECK
-
-if [ $TB_STATS -eq 1 ] && [ ! -z "$INDEX_IN" ]; then
- log 0 "can't define -ti with -tb_stats"
- exit 1
-elif [ $IX_STATS -eq 2 ] && [ ! -z "$TABLE_IN" ]; then
- log 0 "can't define -t with -ix_stats"
- exit 1
-elif [ $IF_STATS -eq 3 ] && [ ! -z "$INDEX_IN" ]; then
- log 0 "can't define -ti with -if_stats"
- exit 1
-fi
-
-if [ $TRANSACTION_LOG_THRESHOLD_PCT -gt 99 ]; then
- log 0 "-log option should be less than 100, TRANSACTION_LOG_THRESHOLD_PCT=$TRANSACTION_LOG_THRESHOLD_PCT"
- exit 1
-fi
-if [ $IGNORE_TABLE_SIZE_THRESHOLD_MIN -ge $IGNORE_TABLE_SIZE_THRESHOLD_MAX ]; then
- log 0 "option -ittx should be greater than option -ittn"
- exit 1
-fi
-
-## override some defaults for offline reorgs
-#if [ $IF_STATS -eq 3 ]; then
-# MAX_ASYNC_REORGS_ALLOWED=1;
-# REORG_TIMEOUT_WINDOW_ACTION=1;
-# ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
-# SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
-#fi
-
-## fixup REORG filter string for grep
-REORG=$( echo "$REORG" | sed 's/*/\\*/g' | sed 's/-/\\-/g');
-
-## need to transform to seconds - easier to work with
-## 3/4 time is for reorgs , 1/4 for runstats
-MAINTENANCE_TIMEOUT_WINDOW_SECONDS=$(( 60 * MAINTENANCE_TIMEOUT_WINDOW_MINUTES ))
-REORG_TIMEOUT_WINDOW_SECONDS=$( echo $MAINTENANCE_TIMEOUT_WINDOW_SECONDS | awk '{ print int(0.75*$1) }');
-RUNSTATS_TIMEOUT_WINDOW_SECONDS=$( echo $MAINTENANCE_TIMEOUT_WINDOW_SECONDS | awk '{ print int(0.25*$1) }');
-
-# echo "$MAINTENANCE_TIMEOUT_WINDOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS"
-
-##
-## main
-##
-log 3 "Starting $0 at $(date) on $HOSTNAME"
-
-DBNAMES=$( db2 list db directory | grep -E "alias|Indirect" | grep -B 1 Indirect | grep alias | awk '{print $4}' | sort )
-
-##
-## loops for all dbs
-##
-for DBNAME in $DBNAMES
-do
-
- ## just process the one db
- if [ ! -z "$DB" ] && [ "$DB" != "$DBNAME" ] ; then
- continue
- fi
-
- ## can't run script on a STANDBY db
- ROLE=$(db2 "get db cfg for $DBNAME" | grep 'HADR database role' | cut -d '=' -f2 | sed 's/ *//g')
- if [ -z "$ROLE" ] || [ "$ROLE" == "" ]; then
- log 1 " Can't determine hadr database role from 'db2 get db cfg for $DBNAME'"
- continue
- elif [ "$ROLE" == "STANDBY" ]; then
- log 1 " Can't run script '${0}' for $DBNAME with hadr database role '$ROLE'"
- continue
- fi
-
- log 3 "DB=$DBNAME ..."
-
- db2 connect to $DBNAME >> /dev/null 2>&1
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 " can't connect to $DBNAME"
- continue
- fi
-
- if [ $TRSI -eq 1 ]; then
- TRSI
- continue
-
- elif [ $LIST_VALID_TABLE_SIZES -eq 1 ]; then
- getValidTableSizes
- log 3 "The following $NUM_VALID_TABLES are valid table sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$VALID_TABLE_SIZES_RAW_DATA"
- continue
-
- elif [ $LIST_FRAGMENTED_INDEXES -eq 1 ]; then
- getValidFragmentedIndexes
- VALID_FRAMENTED_INDEXES_HEADER="TABSCHEMA TABNAME INDSCHEMA INDNAME INDCARD STATS_TIME LAST_USED NLEAF SEQUENTIAL_PAGES";
- log 3 "The following $NUM_VALID_FRAGMENTED_INDEXES are fragmenated indexes based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$VALID_FRAMENTED_INDEXES_HEADER\n$VALID_FRAGMENTED_INDEXES_RAW_DATA"
- continue;
- elif [ $LIST_REORGCHK_TB_STATS_TABLES -eq 1 ]; then
- getValidTablesToReorg
- REORGCHK_TB_STATS_HEADER="TABLE_SCHEMA TABLE_NAME CARD OVERFLOW NPAGES FPAGES ACTIVE_BLOCKS TSIZE F1 F2 F3 REORG";
- log 3 "The following $NUM_VALID_TABLES_TO_REORG are results from REORGCHK_TB_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$REORGCHK_TB_STATS_HEADER\n$VALID_TABLES_TO_REORG_RAW_DATA"
- continue;
-
- elif [ $LIST_REORGCHK_IX_STATS_TABLES -eq 1 ]; then
- getValidIndexesToReorg
- REORGCHK_IX_STAT_HEADER="TABLE_SCHEMA TABLE_NAME INDEX_SCHEMA INDEX_NAME INDCARD NLEAF NUM_EMPTY_LEAFS NLEVELS NUMRIDS_DELETED FULLKEYCARD LEAF_RECSIZE NONLEAF_RECSIZE LEAF_PAGE_OVERHEAD NONLEAF_PAGE_OVERHEAD PCT_PAGES_SAVED F4 F5 F6 F7 F8 REORG";
- log 3 "The following $NUM_VALID_INDEXES_TO_REORG are results from REORGCHK_IX_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$REORGCHK_IX_STAT_HEADER\n$VALID_INDEXES_TO_REORG_RAW_DATA"
- continue;
-
-
- fi
-
-
- INPLACE=1
- if [ $INPLACE -eq 1 ]; then
-
- log 3 " SCHEMA: $SCHEMANAME_IN"
- log 3 " TABLES: $TABLE_IN"
- log 3 "INDEXES: $INDEX_IN"
-
- ##
- ## input table(s) verification
- ## verify input table exist
- ## and table is within size limits
- ## create the OBJECT_ARRAY that holds the relevant table information
- ##
- if [ ! -z "$TABLE_IN" ]; then
-
- TABLE_IN=$( echo "$TABLE_IN" | tr ' ' '\n' );
- for TABNAME in $TABLE_IN
- do
-
- ## make sure table exists
- RC=$( db2 -x "select tabname from syscat.tables where tabname = '$TABNAME' and tabschema = '$SCHEMANAME_IN' and type = 'T'");
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "input command line table '$TABNAME' does not exist or is invalid"
- exit 1
- fi
-
- isTableWithinSizeLimit $SCHEMANAME_IN $TABNAME
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
- exit 1
- fi
-
- done
-
- if [ $TB_STATS -eq 1 ]; then
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ $IF_STATS -eq 3 ]; then
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
-
- elif [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
- for REORG_TYPE in 0 1
- do
- if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
- getValidTablesToReorg
- TABLE_IN="$VALID_TABLES_TO_REORG";
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
- getValidFragmentedIndexes
- TABLE_IN="$VALID_FRAGMENTED_INDEXES"
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
- done
-
- elif [ $TB_STATS -eq 1 ]; then
- getValidTablesToReorg
- TABLE_IN="$VALID_TABLES_TO_REORG";
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ $IF_STATS -eq 3 ]; then
- getValidFragmentedIndexes
- TABLE_IN="$VALID_FRAGMENTED_INDEXES"
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
-
- ##
- ## input indexes verification
- ## verify input indexes exist
- ##
- if [ ! -z "$INDEX_IN" ]; then
- INDEX_IN=$( echo "$INDEX_IN" | tr ' ' '\n' );
- for INDEX in $INDEX_IN
- do
- ## make sure index exists, especially those input on command line
- TABSCHEMA=$( echo $INDEX | cut -d. -f1);
- TABNAME=$( echo $INDEX | cut -d. -f2);
- INDSCHEMA=$( echo $INDEX | cut -d. -f3);
- INDNAME=$( echo $INDEX | cut -d. -f4);
- RC=$( db2 -x "select indname from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 " input command line index '$INDEX' does not exist"
- exit 1
- fi
-
- isTableWithinSizeLimit $TABSCHEMA $TABNAME
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
- exit 1
- fi
-
- done
-
- createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
- ##
- ##
- elif [ $IX_STATS -eq 2 ]; then
- getValidIndexesToReorg
- INDEX_IN="$VALID_INDEXES_TO_REORG"
- createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
- fi
-
- ## get the NUMBER of tables per reorg table type
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $TB_STATS; OBJECT_NUM_TB_STATS=$?;
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IX_STATS; OBJECT_NUM_IX_STATS=$?;
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IF_STATS; OBJECT_NUM_IF_STATS=$?;
-
- ## just list out the OBJECT_ARRAY and exit
- if [ $LIST_ONLY -eq 1 ]; then
-
- listOBJECT_ARRAY;
- exit 1
- fi
-
-
- if [ $EXECUTE_TABLE_REORG -eq 1 ]; then
-
-
- ##
- ## this is the main list of what we are going to reorg
- ##
- echo ""
-
- listOBJECT_ARRAY;
-
-# exit 1
-
- ##
- ## setup some control variables for the main loop
- ##
- ## REORG_STATUS COMPLETED PAUSED STARTED STOPPED TRUNCATE
- ##
- MAINTENANCE_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
- REORG_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
- WINDOW_START_TIME_DB2=$( date '+%Y-%m-%d-%H.%M.%S' );
- IF_STATS_WINDOW_START_TIME_DB2=$( date '+%s' );
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
- NUM_REORG_OBJECTS="${#OBJECT_ARRAY[@]}";
-# NUM_REORGS_IN_PROGRESS=0;
-# NUM_REORGS_KICKED_OFF=0;
-# NUM_REORGS_COMPLETED=0;
-# NUM_REORGS_STOPPED=0;
-# NUM_REORGS_ABORTED=0;
- REORG_TIMEOUT_OVERFLOW_VALVE=300;
- REORG_TIMEOUT_WINDOW_COMPLETED=0;
- REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=0;
- initTABLE_IN_USE_ARRAY $MAX_ASYNC_REORGS_ALLOWED
-
- ## multi table reorg option
- ## online table reorg and offline index reorgs have different options
- MAX_ASYNC_REORGS_ALLOWED_ORG=$MAX_ASYNC_REORGS_ALLOWED;
- REORG_TIMEOUT_WINDOW_ACTION_ORG=$REORG_TIMEOUT_WINDOW_ACTION;
- SLEEP_INTERVAL_TIME_ORG=$SLEEP_INTERVAL_TIME;
-
- ## override some defaults for offline reorgs
- #if [ $IF_STATS -eq 3 ]; then
- # MAX_ASYNC_REORGS_ALLOWED=1;
- # REORG_TIMEOUT_WINDOW_ACTION=1;
- # ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
- # SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
- #fi
-
- echo ""
- log 3 "Starting reorg of ..."
-
- if [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
- for REORG_TYPE in 0 1
- do
-
- if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
- TB_STATS=1;
- IF_STATS=0;
- NUM_REORG_OBJECTS=$OBJECT_NUM_TB_STATS;
- REORG_TABLE_TYPE=$TB_STATS;
- MAX_ASYNC_REORGS_ALLOWED=$MAX_ASYNC_REORGS_ALLOWED_ORG;
- REORG_TIMEOUT_WINDOW_ACTION=$REORG_TIMEOUT_WINDOW_ACTION_ORG;
- SLEEP_INTERVAL_TIME=$SLEEP_INTERVAL_TIME_ORG;
-
- elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
- TB_STATS=0;
- IF_STATS=3;
- NUM_REORG_OBJECTS=$OBJECT_NUM_IF_STATS;
- REORG_TABLE_TYPE=$IF_STATS;
- MAX_ASYNC_REORGS_ALLOWED=1;
- REORG_TIMEOUT_WINDOW_ACTION=1;
- SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME_ORG | awk '{ print $1/3 }');
- fi
-
- reorgTables
- done
- else
- if [ $TB_STATS -eq 1 ]; then
- REORG_TABLE_TYPE=$TB_STATS;
- elif [ $IX_STATS -eq 2 ]; then
- REORG_TABLE_TYPE=$IX_STATS;
- elif [ $IF_STATS -eq 3 ]; then
- REORG_TABLE_TYPE=$IF_STATS;
- fi
- reorgTables
- fi
-
- ## list current state of OBJECT_ARRAY
- listOBJECT_ARRAY;
-
- ##
- ## now do runstats
- ##
- log 3 "Starting runstats of ..."
- RUNSTATS_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
-
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
-
- ## check runstats window maintenance time
- MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
- DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
- if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + RUNSTATS_TIMEOUT_WINDOW_SECONDS)) ]; then
- log 3 "$REORG_TIMEOUT_WINDOW_START_TIME_SECONDS
-$MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS $DIFF"
- log 3 "Runstats window ending, runstats window time exceeded"
- break
- fi
-
- ## get table info
- TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
- TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
- INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
- INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
- IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
- OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
-
- ## only do a runstats if table/index has completed
- ## verify stats time so we dont kick off another runstats on the same table
- if [ "$OBJECT_REORG_STATUS" == "COMPLETED" ]; then
- STATS_TIME=$( db2 -x "select stats_time from syscat.tables where tabschema='$TABSCHEMA' and tabname='$TABNAME' and stats_time < TIMESTAMP('$WINDOW_START_TIME_DB2') " );
- rc=$?
- if [ $rc -eq 0 ]; then
- log 3 "Starting runstats on $TABSCHEMA.$TABNAME"
- # db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON ALL COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS";
- db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON KEY COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS UTIL_IMPACT_PRIORITY 50";
- log 3 "Finished runstats on $TABSCHEMA.$TABNAME"
- fi
- fi
-
- done
-
- fi ## EXECUTE_TABLE_REORG
-
-
- fi ## INPLACE
-
-
-done ## DBNAMES
-
-##
-## cleanup
-##
-
-log 3 "Completed $0 at $(date)"
-
-exit 0
\ No newline at end of file
diff --git a/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2_maintenance.sh b/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2_maintenance.sh
index 94e16231e..28a993c4e 100755
--- a/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2_maintenance.sh
+++ b/instance-applications/120-ibm-db2u-database/files/reorgTablesIndexesInplace2_maintenance.sh
@@ -5,66 +5,71 @@
## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/
## see Identifying fragmented indexes from statistics
## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
-##
+##0 23 * * 5 (. ~/sqllib/db2profile; ~/maintenance/bin/misc/reorgTablesIndexesInplace.sh -db dbname -s MAXIMO -tb_stats -if_stats -window 120 -tr >> ~/maintenance/logs/reorgTablesIndexesInplace.sh.log 2>&1 )
## script to reorg tables online and indexes offline based on different criteria
## we need to be able to perform an online table reorg and an offline indexes all reorg in the same run of the script
##
+#
+# -- Modifications/Updates on 01/May/26 by Prudhviraj Patrata
+# -- Increased the default tablesize from 20GB to 100GB
+# -- Updated to use single database at a time
+# -- Improved the readability of output of logs
+#
UsageHelp()
{
-
- echo "Script to perform reorg tables, indexes online (inplace) "
- echo " also to REORG INDEXES ALL FOR TABLE offline"
- echo " db2 performs the online reorgs asynchronously"
- echo ""
- echo "Usage: ${0} [options]"
- echo " where [options] is one of the following:"
- echo " -h: displays this usage screen"
- echo " -db: dbname, default is all cataloged databases"
- echo ""
- echo " -s: table schemaname"
- echo " -t: table(s) to reorg"
- echo "-tb_stats: reorg tables reported by REORGCHK_TB_STATS"
- echo " -ti: reorg table index(s), format must be TABSCHEMA.TABNAME.INDSCHEMA.INDNAME"
- echo "-ix_stats: reorg table index(s) reported by REORGCHK_IX_STATS"
- echo "-if_stats: reorg indexes all for table(s) offline as reported by index fragmentation NLEAF/SEQUENTIAL_PAGES columns"
- echo ""
- echo " -ls: list valid table sizes for a particular schema"
- echo " -lf: list all fragmented index details for a particular schema, based on valid table sizes"
- echo " -lt: list all tables to reorg based on REORGCHK_TB_STATS reorg column, based on valid table sizes"
- echo " -li: list all indexes to reorg based on REORGCHK_IX_STATS reorg column, based on valid table sizes"
- echo " -l: list tables/indexes that would be reorged"
- echo ""
- echo " -ittx: ignore tables over a specific threshold size in MBs, default is 20000 MB ie 20 GB"
- echo " -ittn: ignore tables under a specific threshold size in MBs, default is 10 MB"
- echo " -mar: maximum asynchronous reorgs allowed, default is 3"
- echo " -log: don't kick off a reorg if transaction log usage is over a certain percentage, default is 90%"
- echo " -window: stop reorg tables/indexes/runstats after a set maintenance timeout window, default is 240 minutes"
- echo " -twa: timeout window action: default=2 for online, 1 for offline"
- echo " 1=allow current reorg(s) to continue"
- echo " 2=stop current reorg(s)"
-# echo " 3=stop current reorg(s) if < 80% complete and continue script"
- echo " -ignore: ignore specific tables from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1 "
- echo " eg \"$IGNORE_TABLES_EX\""
- echo " -reorg: table F1 F2 F3 filter reorg, default is *"
- echo " -sleep: SLEEP_INTERVAL_TIME, default is 60 seconds"
- echo ""
- echo " -tr: execute inplace table/index reorg"
- echo ""
- echo " -trsi: Retrieve table reorganization snapshot information from snap_get_tab_reorg and db2pd -reorgs index"
- echo ""
- echo "Examples:"
- echo " 1. ${0} -h"
- echo " 2. ${0} -db dbname -s BLUDB -ls"
- echo " 3. ${0} -s MAXIMO -t \"YFS_ITEM YFS_TASK_Q YFS_SHIPMENT\" -tb_stats -tr "
- echo " 4. ${0} -s MAXIMO -ti \"MAXIMO.YFS_SNAPSHOT.MAXIMO.YFS_SNAPSHOT_I1 MAXIMO.YFS_ITEM.MAXIMO.YFS_ITEM_PK\" -ix_stats -tr"
- echo " 5. ${0} -s MAXIMO -t \"YFS_ITEM YFS_SNAPSHOT YFS_IMPORT YFS_EXPORT\" -if_stats -tr"
- echo " 6. ${0} -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ittx 30000 -tr"
- echo " 7. ${0} -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ignore \"$IGNORE_TABLES_EX\" -reorg \"***\" -tr"
- echo " 8. ${0} -s MAXIMO -tb_stats -if_stats -ittx 100 -ittn 20 -tr"
- echo " 9. ${0} -trsi"
-
- echo ""
+ echo "Script to perform reorg tables, indexes online (inplace) "
+ echo " also to REORG INDEXES ALL FOR TABLE offline"
+ echo " db2 performs the online reorgs asynchronously"
+ echo ""
+ echo "Usage: ${0} [options]"
+ echo " where [options] is one of the following:"
+ echo " -h: displays this usage screen"
+ echo " -db: dbname, default is all cataloged databases"
+ echo ""
+ echo " -s: table schemaname"
+ echo " -t: table(s) to reorg"
+ echo "-tb_stats: reorg tables reported by REORGCHK_TB_STATS"
+ echo " -ti: reorg table index(s), format must be TABSCHEMA.TABNAME.INDSCHEMA.INDNAME"
+ echo "-ix_stats: reorg table index(s) reported by REORGCHK_IX_STATS"
+ echo "-if_stats: reorg indexes all for table(s) offline as reported by index fragmentation NLEAF/SEQUENTIAL_PAGES columns"
+ echo ""
+ echo " -ls: list valid table sizes for a particular schema"
+ echo " -lf: list all fragmented index details for a particular schema, based on valid table sizes"
+ echo " -lt: list all tables to reorg based on REORGCHK_TB_STATS reorg column, based on valid table sizes"
+ echo " -li: list all indexes to reorg based on REORGCHK_IX_STATS reorg column, based on valid table sizes"
+ echo " -l: list tables/indexes that would be reorged"
+ echo ""
+ echo " -ittx: ignore tables over a specific threshold size in MBs, default is 100000 MB ie 100 GB"
+ echo " -ittn: ignore tables under a specific threshold size in MBs, default is 10 MB"
+ echo " -mar: maximum asynchronous reorgs allowed, default is 3"
+ echo " -log: don't kick off a reorg if transaction log usage is over a certain percentage, default is 90%"
+ echo " -window: stop reorg tables/indexes/runstats after a set maintenance timeout window, default is 240 minutes"
+ echo " -twa: timeout window action: default=2 for online, 1 for offline"
+ echo " 1=allow current reorg(s) to continue"
+ echo " 2=stop current reorg(s)"
+# echo " 3=stop current reorg(s) if < 80% complete and continue script"
+ echo " -ignore: ignore specific tables from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1 "
+ echo " eg \"$IGNORE_TABLES_EX\""
+ echo " -reorg: table F1 F2 F3 filter reorg, default is *"
+ echo " -sleep: SLEEP_INTERVAL_TIME, default is 60 seconds"
+ echo ""
+ echo " -tr: execute inplace table/index reorg"
+ echo ""
+ echo " -trsi: Retrieve table reorganization snapshot information from snap_get_tab_reorg and db2pd -reorgs index"
+ echo ""
+ echo "Examples :"
+ echo " 1. ${0} -h"
+ echo " 2. ${0} -db dbname -s MAXIMO -ls"
+ echo " 3. ${0} -db dbname -s MAXIMO -t \"YFS_ITEM YFS_TASK_Q YFS_SHIPMENT\" -tb_stats -tr "
+ echo " 4. ${0} -db dbname -s MAXIMO -ti \"MAXIMO.YFS_SNAPSHOT.MAXIMO.YFS_SNAPSHOT_I1 MAXIMO.YFS_ITEM.MAXIMO.YFS_ITEM_PK\" -ix_stats -tr"
+ echo " 5. ${0} -db dbname -s MAXIMO -t \"YFS_ITEM YFS_SNAPSHOT YFS_IMPORT YFS_EXPORT\" -if_stats -tr"
+ echo " 6. ${0} -db dbname -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ittx 30000 -tr"
+ echo " 7. ${0} -db dbname -s MAXIMO -tb_stats -mar 5 -window 10 -log 95 -ignore \"$IGNORE_TABLES_EX\" -reorg \"***\" -tr"
+ echo " 8. ${0} -db dbname -s MAXIMO -tb_stats -if_stats -ittx 100 -ittn 20 -tr"
+ echo " 9. ${0} -trsi"
+
+ echo ""
}
@@ -73,133 +78,131 @@ UsageHelp()
##
isNumeric()
{
- echo $1 | grep -E '^[0-9]+$' > /dev/null
-
- return $?
+ echo $1 | grep -E '^[0-9]+$' > /dev/null
+ return $?
}
TRSI()
{
- db2 -v "select varchar(tabschema,9) as tabschema, varchar(tabname,32) as tabname,
- REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER,
--- varchar( varchar_format(REORG_START, 'YYYY-MM-DD HH24:MI:SS'),19) as REORG_START,
--- varchar( varchar_format(REORG_END, 'YYYY-MM-DD HH24:MI:SS'),19) as REORG_END,
- REORG_START, REORG_END,
- REORG_INDEX_ID, REORG_TBSPC_ID
- from table(snap_get_tab_reorg(''))
- order by REORG_START asc
- with ur"
-
- db2pd -db $DBNAME -reorgs index | sed -n "/Index Reorg Stats:/,//p"
-
+ db2 -v "select varchar(tabschema,9) as tabschema, varchar(tabname,32) as tabname,
+ REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER,
+ VARCHAR_FORMAT(REORG_START, 'YYYY-MM-DD-HH24:MI:SS') as REORG_START,
+ VARCHAR_FORMAT(REORG_END, 'YYYY-MM-DD-HH24:MI:SS') as REORG_END,
+-- REORG_START, REORG_END,
+ REORG_INDEX_ID, REORG_TBSPC_ID
+ from table(snap_get_tab_reorg(''))
+ order by REORG_START asc
+ with ur"
+
+ db2pd -db $DBNAME -reorgs index | sed -n "/Index Reorg Stats:/,//p" > /dev/null 2>&1
}
log()
{
- TYPE=$1
- MSG="$2"
-
- DATE=$( date '+%d-%m-%Y %H:%M:%S' );
-
- # TYPE:
- # 0 = Critical
- # 1 = Warn
- # 3 = Info
- # 5 = Debug'
- if [ ${TYPE} -eq 0 ]; then
- TYPEMSG="Error"
- elif [ ${TYPE} -eq 1 ]; then
- TYPEMSG="Warning"
- elif [ ${TYPE} -eq 3 ]; then
- TYPEMSG="Info"
- elif [ ${TYPE} -eq 5 ]; then
- TYPEMSG="Debug"
- else
- TYPEMSG="Other"
- fi
-
- echo -e "${DATE} ${TYPEMSG}: ${MSG}" | tee -a $REORG_TABLE_INDEX_LOG
-
- return 0
+ TYPE=$1
+ MSG="$2"
+
+ DATE=$( date '+%d-%m-%Y %H:%M:%S' );
+
+ # TYPE:
+ # 0 = Critical
+ # 1 = Warn
+ # 3 = Info
+ # 5 = Debug'
+ if [ ${TYPE} -eq 0 ]; then
+ TYPEMSG="Error"
+ elif [ ${TYPE} -eq 1 ]; then
+ TYPEMSG="Warning"
+ elif [ ${TYPE} -eq 3 ]; then
+ TYPEMSG="Info"
+ elif [ ${TYPE} -eq 5 ]; then
+ TYPEMSG="Debug"
+ else
+ TYPEMSG="Other"
+ fi
+
+ echo -e "${DATE} ${TYPEMSG} : ${MSG}" | tee -a $REORG_TABLE_INDEX_LOG
+
+ return 0
}
initTABLE_IN_USE_ARRAY()
{
- local NUM_ITEMS=$1
- local jj;
+ local NUM_ITEMS=$1
+ local jj;
- ##
- ## initialise the db2 TABLE_IN_USE_ARRAY
- ##
- for((jj=0; jj<$NUM_ITEMS; jj++))
- do
- TABLE_IN_USE_ARRAY[$jj]=""
- done
+ ##
+ ## initialise the db2 TABLE_IN_USE_ARRAY
+ ##
+ for((jj=0; jj<$NUM_ITEMS; jj++))
+ do
+ TABLE_IN_USE_ARRAY[$jj]=""
+ done
- return 0
+ return 0
}
existTABLE_TABLE_IN_USE_ARRAY()
{
- local TABLE=$1
- local jj;
- ##
- ## check if table is in use
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
- return 0;
- fi
- done
+ local TABLE=$1
+ local jj;
+ ##
+ ## check if table is in use
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
+ return 0;
+ fi
+ done
- return 1;
+ return 1;
}
addTABLE_TABLE_IN_USE_ARRAY()
{
- local TABLE=$1
- local jj;
-
- ##
- ## add table in empty slot
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "" ]; then
- TABLE_IN_USE_ARRAY[$jj]=$TABLE;
- return 0;
- fi
- done
-
- return 1;
+ local TABLE=$1
+ local jj;
+
+ ##
+ ## add table in empty slot
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "" ]; then
+ TABLE_IN_USE_ARRAY[$jj]=$TABLE;
+ return 0;
+ fi
+ done
+
+ return 1;
}
removeTABLE_TABLE_IN_USE_ARRAY()
{
- local TABLE=$1
- local jj;
- ##
- ## remove entry
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
- TABLE_IN_USE_ARRAY[$jj]="";
- return 0;
- fi
- done
-
- return 1;
+ local TABLE=$1
+ local jj;
+ ##
+ ## remove entry
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ if [ "${TABLE_IN_USE_ARRAY[$jj]}" == "$TABLE" ]; then
+ TABLE_IN_USE_ARRAY[$jj]="";
+ return 0;
+ fi
+ done
+
+ return 1;
}
@@ -207,195 +210,193 @@ removeTABLE_TABLE_IN_USE_ARRAY()
listTABLE_IN_USE_ARRAY()
{
- local jj;
- ##
- ## list table entries
- ##
- for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
- do
- log 5 "TABLE_IN_USE_ARRAY $jj ${TABLE_IN_USE_ARRAY[$jj]}";
- done
+ local jj;
+ ##
+ ## list table entries
+ ##
+ for((jj=0; jj<${#TABLE_IN_USE_ARRAY[@]}; jj++))
+ do
+ log 5 "TABLE_IN_USE_ARRAY $jj ${TABLE_IN_USE_ARRAY[$jj]}";
+ done
- return 0;
+ return 0;
}
getValidTablesToReorg()
{
- getValidTableSizes
-
- VALID_TABLES_TO_REORG=""
- VALID_TABLES_TO_REORG_RAW=""
- NUM_VALID_TABLES_TO_REORG=0
- for TABNAME in $VALID_TABLES
- do
-
- RAW=$( db2 -x "call REORGCHK_TB_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
- RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 12) print $0 }' | sed 's/ \+/ /g' | grep $REORG )
- rc=$?
- if [ $rc -eq 0 ]; then
- TABNAME=$( echo "$RAW" | awk '{print $2}' );
- [ "$VALID_TABLES_TO_REORG_RAW_DATA" == "" ] && VALID_TABLES_TO_REORG_RAW_DATA="$RAW" || VALID_TABLES_TO_REORG_RAW_DATA="$VALID_TABLES_TO_REORG_RAW_DATA\n$RAW"
- fi
-
- done
-
- ## sort the tables based on REORG column
- VALID_TABLES_TO_REORG_RAW_DATA=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | sort -k12 -r);
- VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | awk '{print $2}' );
- NUM_VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG" | wc -l );
-
- return 0
-
+ getValidTableSizes
+
+ VALID_TABLES_TO_REORG=""
+ VALID_TABLES_TO_REORG_RAW=""
+ NUM_VALID_TABLES_TO_REORG=0
+ for TABNAME in $VALID_TABLES
+ do
+
+ RAW=$( db2 -x "call REORGCHK_TB_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
+ RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 12) print $0 }' | sed 's/ \+/ /g' | grep $REORG )
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ TABNAME=$( echo "$RAW" | awk '{print $2}' );
+ [ "$VALID_TABLES_TO_REORG_RAW_DATA" == "" ] && VALID_TABLES_TO_REORG_RAW_DATA="$RAW" || VALID_TABLES_TO_REORG_RAW_DATA="$VALID_TABLES_TO_REORG_RAW_DATA\n$RAW"
+ fi
+
+ done
+
+ ## sort the tables based on REORG column
+ VALID_TABLES_TO_REORG_RAW_DATA=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | sort -k12 -r);
+ VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG_RAW_DATA" | awk '{print $2}' );
+ NUM_VALID_TABLES_TO_REORG=$( echo -e "$VALID_TABLES_TO_REORG" | wc -l );
+
+ return 0
+
}
getValidIndexesToReorg()
{
- getValidTableSizes
-
- VALID_INDEXES_TO_REORG=""
- VALID_INDEXES_TO_REORG_RAW=""
- NUM_VALID_INDEXES_TO_REORG=0
- for TABNAME in $VALID_TABLES
- do
-
- RAW=$( db2 -x "call REORGCHK_IX_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
- ## this can return multiple indexes for same TABNAME
- RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 21) print $0 }' | sed 's/ \+/ /g' | grep $REORG );
- rc=$?
- if [ $rc -eq 0 ]; then
- INDNAME=$( echo "$RAW" | awk '{print $1"."$2"."$3"."$4}' );
- [ "$VALID_INDEXES_TO_REORG_RAW_DATA" == "" ] && VALID_INDEXES_TO_REORG_RAW_DATA=$RAW || VALID_INDEXES_TO_REORG_RAW_DATA="$VALID_INDEXES_TO_REORG_RAW_DATA\n$RAW"
- fi
-
- done
-
- ## sort the indexes based on REORG column
- VALID_INDEXES_TO_REORG_RAW_DATA=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | sort -k21 -r);
- VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | awk '{print $1"."$2"."$3"."$4}' );
- NUM_VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG" | wc -l );
-
- return 0
-
+ getValidTableSizes
+
+ VALID_INDEXES_TO_REORG=""
+ VALID_INDEXES_TO_REORG_RAW=""
+ NUM_VALID_INDEXES_TO_REORG=0
+ for TABNAME in $VALID_TABLES
+ do
+
+ RAW=$( db2 -x "call REORGCHK_IX_STATS('T','$SCHEMANAME_IN.$TABNAME')" );
+ ## this can return multiple indexes for same TABNAME
+ RAW=$( echo "$RAW" | grep $SCHEMANAME_IN | grep $TABNAME | awk '{ if (NF == 21) print $0 }' | sed 's/ \+/ /g' | grep $REORG );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ INDNAME=$( echo "$RAW" | awk '{print $1"."$2"."$3"."$4}' );
+ [ "$VALID_INDEXES_TO_REORG_RAW_DATA" == "" ] && VALID_INDEXES_TO_REORG_RAW_DATA=$RAW || VALID_INDEXES_TO_REORG_RAW_DATA="$VALID_INDEXES_TO_REORG_RAW_DATA\n$RAW"
+ fi
+
+ done
+
+ ## sort the indexes based on REORG column
+ VALID_INDEXES_TO_REORG_RAW_DATA=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | sort -k21 -r);
+ VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG_RAW_DATA" | awk '{print $1"."$2"."$3"."$4}' );
+ NUM_VALID_INDEXES_TO_REORG=$( echo -e "$VALID_INDEXES_TO_REORG" | wc -l );
+
+ return 0
+
}
getValidFragmentedIndexes()
{
- ##
- ## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
- ##
-
- getValidTableSizes
-
- VALID_FRAGMENTED_INDEXES_RAW_DATA=$( db2 -x "select rtrim(tabschema)||' '||rtrim(tabname)||' '||rtrim(indschema)||' '||rtrim(indname)
- ||' '||indcard||' '||stats_time||' '||lastused||' '||nleaf||' '||sequential_pages
- from syscat.indexes where tabschema='$SCHEMANAME_IN'
- and not (nleaf = 1 and sequential_pages = 0)
- and not (nleaf = 0 and sequential_pages = 1)
- and (nleaf - sequential_pages > 10)
- and tabname in ( $VALID_TABLES_FORMATTED )
- order by tabname
- with ur"; );
-
- VALID_FRAGMENTED_INDEXES_RAW_DATA=$(echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' );
- VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' | cut -d' ' -f2 | uniq )
- NUM_VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES}" | wc -l )
-
-
+ ##
+ ## http://www.ibm.com/developerworks/data/library/techarticle/dm-1307optimizerunstats/#Listing%207
+ ##
+
+ getValidTableSizes
+
+ VALID_FRAGMENTED_INDEXES_RAW_DATA=$( db2 -x "select rtrim(tabschema)||' '||rtrim(tabname)||' '||rtrim(indschema)||' '||rtrim(indname)
+ ||' '||indcard||' '||stats_time||' '||lastused||' '||nleaf||' '||sequential_pages
+ from syscat.indexes where tabschema='$SCHEMANAME_IN'
+ and not (nleaf = 1 and sequential_pages = 0)
+ and not (nleaf = 0 and sequential_pages = 1)
+ and (nleaf - sequential_pages > 10)
+ and tabname in ( $VALID_TABLES_FORMATTED )
+ order by tabname
+ with ur"; );
+
+ VALID_FRAGMENTED_INDEXES_RAW_DATA=$(echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' );
+ VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES_RAW_DATA}" | sed 's/ *$//g' | cut -d' ' -f2 | uniq )
+ NUM_VALID_FRAGMENTED_INDEXES=$( echo "${VALID_FRAGMENTED_INDEXES}" | wc -l )
}
getValidTableSizes()
{
- VALID_TABLE_SIZES_RAW_DATA=$( db2 "select t0.tabname,
- ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB,
- cast ((INDEX_OBJECT_P_SIZE / 1024) as integer) as INDEX_SIZE_MB
- from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1
- where t0.tabschema='$SCHEMANAME_IN'
- and t0.tabschema=t1.tabschema
- and t0.tabname=t1.tabname
- $IGNORE_TABLES
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
- order by 2 desc
- with ur"; );
- rc=$?
- if [ $rc -eq 0 ]; then
- VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES_RAW_DATA" | sed '1,3d' | sed '$d' | sed '$d' );
- VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; printf "\n"; }');
- VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | awk '{print $1}' );
- NUM_VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | wc -l );
- # log 3 "NUM_VALID_TABLES=$NUM_VALID_TABLES"
-
- VALID_TABLES_FORMATTED=""
- for TABLE in $VALID_TABLES
- do
- VALID_TABLES_FORMATTED="$VALID_TABLES_FORMATTED'$TABLE',"
- done
- VALID_TABLES_FORMATTED=$( echo "$VALID_TABLES_FORMATTED" | sed 's/,$//g' )
- else
- VALID_TABLES_FORMATTED="'UNKNOWN_TABNAME'"
- fi
+ VALID_TABLE_SIZES_RAW_DATA=$( db2 "select t0.tabname,
+ ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB,
+ cast ((INDEX_OBJECT_P_SIZE / 1024 ) as integer) as INDEX_SIZE_MB
+ from SYSIBMADM.ADMINTABINFO t0, SYSCAT.TABLES t1
+ where t0.tabschema='$SCHEMANAME_IN'
+ and t0.tabschema=t1.tabschema
+ and t0.tabname=t1.tabname
+ $IGNORE_TABLES
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
+ order by 2 desc
+ with ur"; );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES_RAW_DATA" | sed '1,3d' | sed '$d' | sed '$d' );
+ VALID_TABLE_SIZES=$( echo "$VALID_TABLE_SIZES" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; printf "\n"; }');
+ VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | awk '{print $1}' );
+ NUM_VALID_TABLES=$( echo "$VALID_TABLE_SIZES" | wc -l );
+ # log 3 "NUM_VALID_TABLES=$NUM_VALID_TABLES"
+
+ VALID_TABLES_FORMATTED=""
+ for TABLE in $VALID_TABLES
+ do
+ VALID_TABLES_FORMATTED="$VALID_TABLES_FORMATTED'$TABLE',"
+ done
+ VALID_TABLES_FORMATTED=$( echo "$VALID_TABLES_FORMATTED" | sed 's/,$//g' )
+ else
+ VALID_TABLES_FORMATTED="'UNKNOWN_TABNAME'"
+ fi
}
## is TABLE within size limits < IGNORE_TABLE_SIZE_THRESHOLD_MAX and > IGNORE_TABLE_SIZE_THRESHOLD_MIN
isTableWithinSizeLimit()
{
- local SCHEMANAME=$1
- local TABNAME=$2
- local RC=""
- local rc=0
-
- RC=$( db2 -x "select tabname,
- ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB
- from SYSIBMADM.ADMINTABINFO
- where tabschema='$SCHEMANAME'
- and tabname = '$TABNAME'
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
- and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
- order by 2 desc
- with ur" );
-
- rc=$?
- return $rc
+ local SCHEMANAME=$1
+ local TABNAME=$2
+ local RC=""
+ local rc=0
+
+ RC=$( db2 -x "select tabname,
+ ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) as TOTAL_TABLE_MB
+ from SYSIBMADM.ADMINTABINFO
+ where tabschema='$SCHEMANAME'
+ and tabname = '$TABNAME'
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) < $IGNORE_TABLE_SIZE_THRESHOLD_MAX
+ and ( ( DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE ) / 1024 ) > $IGNORE_TABLE_SIZE_THRESHOLD_MIN
+ order by 2 desc
+ with ur" );
+
+ rc=$?
+ return $rc
}
## create an list/array of table objects to reorg based on tabnames
createTableOBJECT_ARRAY()
{
- local TABNAMES="$1"
- local OBJECT_REORG_TABLE_TYPE=$2
-
- ##
- ## make the OBJECT_ARRAY for tables and indexes
- ##
- if [ -z "$OBJECT_ARRAY" ]; then
- local let index=0;
- else
- local let index=${#OBJECT_ARRAY[@]};
- fi
- local TID=0 ## Table ID - always 0 for online table reorg
- local INDSCHEMA=NULL;
- local INDNAME=NULL;
- local LOCK_COUNT=0
-
- for TABNAME in $TABNAMES
- do
- ## we need TABLEID, TBSPACEID for IF_STATS as the full TableName: may not be dispalyed in the db2pd output
- local RC=$( db2 -x "select TABLEID, TBSPACEID from syscat.tables where tabname='$TABNAME' and tabschema='$SCHEMANAME_IN'" )
- local rc=$?
- if [ $rc -eq 0 ]; then
- local TABLEID=$( echo $RC | awk '{print $1}' );
- local TBSPACEID=$( echo $RC | awk '{print $2}' );
- OBJECT_ARRAY[$index]="$SCHEMANAME_IN#$TABNAME#$INDSCHEMA#$INDNAME#$TID#NOTSTARTED#2019-01-01-00.00.00#2019-01-01-00.00.00#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- let index+=1
- fi
- done
+ local TABNAMES="$1"
+ local OBJECT_REORG_TABLE_TYPE=$2
+
+ ##
+ ## make the OBJECT_ARRAY for tables and indexes
+ ##
+ if [ -z "$OBJECT_ARRAY" ]; then
+ local let index=0;
+ else
+ local let index=${#OBJECT_ARRAY[@]};
+ fi
+ local TID=0 ## Table ID - always 0 for online table reorg
+ local INDSCHEMA=NULL;
+ local INDNAME=NULL;
+ local LOCK_COUNT=0
+
+ for TABNAME in $TABNAMES
+ do
+ ## we need TABLEID, TBSPACEID for IF_STATS as the full TableName: may not be dispalyed in the db2pd output
+ local RC=$( db2 -x "select TABLEID, TBSPACEID from syscat.tables where tabname='$TABNAME' and tabschema='$SCHEMANAME_IN'" )
+ local rc=$?
+ if [ $rc -eq 0 ]; then
+ local TABLEID=$( echo $RC | awk '{print $1}' );
+ local TBSPACEID=$( echo $RC | awk '{print $2}' );
+ OBJECT_ARRAY[$index]="$SCHEMANAME_IN#$TABNAME#$INDSCHEMA#$INDNAME#$TID#NOTSTARTED#-#-#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ let index+=1
+ fi
+ done
}
@@ -403,60 +404,66 @@ createTableOBJECT_ARRAY()
createIndexOBJECT_ARRAY()
{
- local INDNAMES="$1"
- local OBJECT_REORG_TABLE_TYPE=$2
- local let index=0
- local TABLEID=9999;
- local TBSPACEID=9999;
- local LOCK_COUNT=0;
-
- for INDEX in $INDNAMES
- do
- local TABSCHEMA=$( echo $INDEX | cut -d. -f1);
- local TABNAME=$( echo $INDEX | cut -d. -f2);
- local INDSCHEMA=$( echo $INDEX | cut -d. -f3);
- local INDNAME=$( echo $INDEX | cut -d. -f4);
- local RC=$( db2 -x "select IID from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
- local rc=$?
- if [ $rc -eq 0 ]; then
- local IID=$( echo $RC | cut -d' ' -f1);
- OBJECT_ARRAY[$index]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#NOTSTARTED#2019-01-01-00.00.00#2019-01-01-00.00.00#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- let index+=1
- fi
- done
+ local INDNAMES="$1"
+ local OBJECT_REORG_TABLE_TYPE=$2
+ local let index=0
+ local TABLEID=9999;
+ local TBSPACEID=9999;
+ local LOCK_COUNT=0;
+
+ for INDEX in $INDNAMES
+ do
+ local TABSCHEMA=$( echo $INDEX | cut -d. -f1);
+ local TABNAME=$( echo $INDEX | cut -d. -f2);
+ local INDSCHEMA=$( echo $INDEX | cut -d. -f3);
+ local INDNAME=$( echo $INDEX | cut -d. -f4);
+ local RC=$( db2 -x "select IID from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
+ local rc=$?
+ if [ $rc -eq 0 ]; then
+ local IID=$( echo $RC | cut -d' ' -f1);
+ OBJECT_ARRAY[$index]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#NOTSTARTED#-#-#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ let index+=1
+ fi
+ done
}
-
##
## list out the objects and state
## this can be used for debugging
##
listOBJECT_ARRAY()
{
-
- local ii;
- log 3 "The following is for debug purposes, Num objects=${#OBJECT_ARRAY[@]}, $OBJECT_NUM_TB_STATS:$OBJECT_NUM_IX_STATS:$OBJECT_NUM_IF_STATS"
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- echo "${OBJECT_ARRAY[$ii]}" | tee -a $REORG_TABLE_INDEX_DEBUG
- done
-
+
+ local ii;
+ log 3 "The following is for debug purposes, Num objects=${#OBJECT_ARRAY[@]}, $OBJECT_NUM_TB_STATS:$OBJECT_NUM_IX_STATS:$OBJECT_NUM_IF_STATS"
+ printf "%-15s %-40s %-15s %-40s %-14s %-20s %-20s %-8s \n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "REORG_STATUS" "REORG_START" "REORG_END" "LOCK_COUNT"
+ : ' for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ echo "${OBJECT_ARRAY[$ii]}" | /usr/bin/column -t -s "#" | tee -a $REORG_TABLE_INDEX_DEBUG
+ done
+ '
+ for ((ii=0; ii<${#OBJECT_ARRAY[@]}; ii++))
+ do
+ IFS="#" read -r TABSCHEMA TABNAME INDSCHEMA INDNAME IID REORG_STATUS OBJECT_REORG_START OBJECT_REORG_END TABLEID TBSPACEID LOCK_COUNT <<< "${OBJECT_ARRAY[$ii]}"
+
+ printf "%-15s %-40s %-15s %-40s %-14s %-20s %-20s %-8s \n" "$TABSCHEMA" "$TABNAME" "$INDSCHEMA" "$INDNAME" "$REORG_STATUS" "$OBJECT_REORG_START" "$OBJECT_REORG_END" "$LOCK_COUNT"
+ done
}
## get the number tb_stats, ix_stats and if_stats objects
getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY()
{
- local rc=0;
- local ii;
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- if [ $( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 ) -eq $1 ]; then
- let rc+=1;
- fi
- done
+ local rc=0;
+ local ii;
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ if [ $( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 ) -eq $1 ]; then
+ let rc+=1;
+ fi
+ done
- return $rc;
+ return $rc;
}
@@ -466,379 +473,382 @@ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY()
reorgTables()
{
- ## variables that need to be reset on each run of the function
- NUM_REORGS_IN_PROGRESS=0;
- NUM_REORGS_KICKED_OFF=0;
- NUM_REORGS_COMPLETED=0;
- NUM_REORGS_STOPPED=0;
- NUM_REORGS_ABORTED=0;
-
- while true
- do
-
- ## check reorg window maintenance time
- MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
- DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
-
- ## safety valve - if for some reason the logic can't stop the reorgs
- if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + REORG_TIMEOUT_OVERFLOW_VALVE )) ]; then
- log 1 "REORG_TIMEOUT_OVERFLOW_VALVE detected";
- log 1 "Aborting reorgs"
- break;
- fi
-
- if [ $DIFF -ge $REORG_TIMEOUT_WINDOW_SECONDS ]; then
-
- REORG_TIMEOUT_WINDOW_COMPLETED=1;
-
- ## -twa: timeout window action: default=3
- ## 1=allow current reorg(s) to continue
- ## 2=stop current reorg(s)
- ## 3=stop current reorg(s) if < 80% complete
- if [ $REORG_TIMEOUT_WINDOW_ACTION -eq 1 ]; then
-
- log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
- break
-
- elif [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ]; then
-
- ## use of the REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER
- ## 0 = ABORT those not started and issue a STOP to those STARTED
- ## 1 = loop again and see if script exits as all reorgs are COMPLETED and STOPPED and ABORTED
- ## 2 = break out
- if [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 0 ]; then
- let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
- log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
- log 3 "Aborting reorgs NOTSTARTED and issuing a STOP to those that are STARTED"
- elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
- let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
- log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
- elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 2 ]; then
- log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
- log 3 "breaking out of reorg loop"
- break;
- fi
-
- fi
-
- fi
-
- ## loop for all OBJECTS - extract relevant data from OBJECT array
- ## if we have NOTSTARTED in the OBJECT_ARRAY[N] - then kick off a reorg
- ## then check tables reorg status
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
- ## get table related info
- TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
- TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
- INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
- INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
- IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
- OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
- OBJECT_REORG_START=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f7 );
- OBJECT_REORG_END=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f8 );
- TABLEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f9 );
- TBSPACEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f10 );
- LOCK_COUNT=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f11 );
- OBJECT_REORG_TABLE_TYPE=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 );
- isTable=0;
- isIndex=0;
- if [ "$INDSCHEMA" == "NULL" -a "$INDNAME" == "NULL" ]; then
- isTable=1;
- else
- isIndex=1;
- fi
-
- if [ $OBJECT_REORG_TABLE_TYPE -ne $REORG_TABLE_TYPE ]; then
- continue;
- fi
-
- # log 5 "${OBJECT_ARRAY[$ii]}"
-
- ##
- ## has OBJECT COMPLETED - no need to continue here
- ##
- if [ "$OBJECT_REORG_STATUS" == "COMPLETED" -o "$OBJECT_REORG_STATUS" == "STOPPED" -o "$OBJECT_REORG_STATUS" == "ABORTED" ]; then
- continue;
- fi
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- ##
- ## query db2 for REORG_STATUS etc - there may not be an entry so carry on
- ##
- RC_SNAP=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER, REORG_START, REORG_END, REORG_INDEX_ID, REORG_TBSPC_ID from table(snap_get_tab_reorg('')) where tabschema='$TABSCHEMA' and tabname='$TABNAME' and REORG_START > TIMESTAMP('$WINDOW_START_TIME_DB2') and REORG_INDEX_ID=$IID");
- rc=$?
- if [ $rc -ge 2 ]; then
- log 0 "Possible error running select query against db2\nrc=$rc\nRC=$RC"
- continue;
- fi
-
- if [ $rc -eq 0 ]; then
- RC=$( echo "$RC_SNAP" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; }')
- REORG_STATUS=$( echo "$RC_SNAP" | awk '{print $1}' );
- REORG_COMPLETION=$( echo "$RC_SNAP" | awk '{print $2}' );
- REORG_CURRENT_COUNTER=$( echo "$RC_SNAP" | awk '{print $4}' );
- REORG_MAX_COUNTER=$( echo "$RC_SNAP" | awk '{print $5}' );
- REORG_START=$( echo "$RC_SNAP" | awk '{print $6}' );
- REORG_END=$( echo "$RC_SNAP" | awk '{print $7}' );
- REORG_INDEX_ID=$( echo "$RC_SNAP" | awk '{print $8}' );
-
- REORG_PERCENT_COMPLETE=0
- if [ ! -z "$REORG_CURRENT_COUNTER" -a $REORG_CURRENT_COUNTER -gt 0 ]; then
- if [ ! -z "$REORG_MAX_COUNTER" -a $REORG_MAX_COUNTER -gt 0 ]; then
- if [ $REORG_MAX_COUNTER -ge $REORG_CURRENT_COUNTER ]; then
- REORG_PERCENT_COMPLETE=$( echo $REORG_CURRENT_COUNTER $REORG_MAX_COUNTER | awk '{ print int (($1/$2)*100) }' );
- fi
- fi
- fi
- fi
-
- # log 5 "RC_SNAP=$RC_SNAP"
-
- elif [ $IF_STATS -eq 3 ]; then
-
- DB2PD_REORG_INDEX_RECORD=$( db2pd -db $DBNAME -reorgs index | grep -B1 -A11 -w "^TbspaceID: $TBSPACEID" | grep -B1 -A11 -w "TableID: $TABLEID" );
- rc=$?
- if [ $rc -eq 0 ]; then
- REORG_START=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | awk '{ print $3,$4}' );
- REORG_START_SECONDS=$(date --d="$REORG_START" '+%s');
-
- if [ $REORG_START_SECONDS -ge $IF_STATS_WINDOW_START_TIME_DB2 ]; then
- REORG_STATUS=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Status:' | awk '{ $1=""; print $0}' | sed 's/^[ \t]*//;s/[ \t]*$//' );
- ## some differences between snap_get_tab_reorg and db2pd -reogrs index output
- if [ "$REORG_STATUS" == "In Progress" ]; then
- REORG_STATUS="STARTED";
- elif [ "$REORG_STATUS" == "Completed" ]; then
- REORG_STATUS="COMPLETED";
- elif [ "$REORG_STATUS" == "Stopped" ]; then
- REORG_STATUS="STOPPED";
- fi
-
- REORG_END=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | grep 'End Time:' | awk '{ print $7,$8}' );
- fi
-
- fi
-
-
- fi
-
-
- ##
- ## has OBJECT been KICKED_OFF or STARTED
- ## if it has check to see if is STARTED or COMPLETED
- ## update OBJECT_ARRAY
- ## update COMPLETION/STOPPED stats
- ##
- if [ "$OBJECT_REORG_STATUS" == "KICKED_OFF" ] || [ "$OBJECT_REORG_STATUS" == "STARTED" ]; then
- if [ ! -z "$REORG_STATUS" ]; then
- if [ "$REORG_STATUS" == "STARTED" -o "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$REORG_START#$REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
- fi
-
- if [ "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
-
- removeTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- if [ $rc -eq 1 ]; then
- log 1 "Failed to remove table $TABSCHEMA.$TABNAME from TABLE_IN_USE_ARRAY";
- fi
-
- if [ "$REORG_STATUS" == "COMPLETED" ]; then
- let NUM_REORGS_COMPLETED+=1
- elif [ "$REORG_STATUS" == "STOPPED" ]; then
- let NUM_REORGS_STOPPED+=1
- fi
-
- let NUM_REORGS_IN_PROGRESS-=1
- fi
-
- fi
-
- ##
- ## OBJECT is NOSTARTED so KICK_OFF a reorg
- ##
- elif [ "$OBJECT_REORG_STATUS" == "NOTSTARTED" ]; then
-
- ## dont kick off any reorgs if window timeout passed and TWA=2
- ## OBJECTS become ABORTED - UPDATE OBJECT_ARRAY
- if [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
- REORG_STATUS=ABORTED;
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- let NUM_REORGS_ABORTED+=1;
- continue;
-
- fi
-
- ## is the TABLE already being used -if it is goto next OBJECT
- existTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- [ $rc -eq 0 ] && continue;
-
- ## we only want to kick off so many reorgs at any one time
- if [ $NUM_REORGS_IN_PROGRESS -eq $MAX_ASYNC_REORGS_ALLOWED ]; then
- continue;
- fi
-
- ##
- ## The table could already be locked - if it is then by-pass it
- ## and ABORT if locked more than 10 times
- ##
- TABLE_LOCKED=$( db2 "select APPLICATION_HANDLE, LOCK_OBJECT_TYPE, LOCK_MODE, LOCK_CURRENT_MODE, LOCK_STATUS, LOCK_COUNT, LOCK_HOLD_COUNT, TBSP_ID, TAB_FILE_ID from TABLE (MON_GET_LOCKS(NULL, -2)) where TBSP_ID=$TBSPACEID and TAB_FILE_ID=$TABLEID and LOCK_OBJECT_TYPE='TABLE' and LOCK_MODE='IX' with ur"; );
- rc=$?
- if [ $rc -eq 0 ]; then
- let LOCK_COUNT+=1;
- log 1 "Appears table $TABSCHEMA.$TABNAME is already locked by another application(s), LOCK_COUNT=$LOCK_COUNT";
- log 1 "$TABLE_LOCKED";
- if [ $LOCK_COUNT -gt 10 ]; then
- OBJECT_REORG_STATUS=ABORTED;
- let NUM_REORGS_ABORTED+=1;
- log 1 "Aborting table $TABSCHEMA.$TABNAME , LOCK_COUNT=$LOCK_COUNT";
- fi
-OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$OBJECT_REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- continue;
- fi
-
- ##
- ## do a check to see where we are on transaction log space - this could be improved!!!!
- ##
- LOG_USED=$( db2 "select cast(LOG_UTILIZATION_PERCENT as decimal(5,2)) as PCTUSED, cast((TOTAL_LOG_USED_KB/1024) as Integer) as TOTUSEDMB, cast((TOTAL_LOG_AVAILABLE_KB/1024) as Integer) as TOTAVAILMB, cast((TOTAL_LOG_USED_TOP_KB/1024) as Integer) as TOTUSEDTOPMB FROM SYSIBMADM.LOG_UTILIZATION ");
- if [ ! -z "$LOG_USED" ]; then
- PCTUSED=$( echo "$LOG_USED" | awk '{ if(NF==4 && $2 ~/^[0-9]+$/) print int($1)}' );
- if [ ! -z "$PCTUSED" ]; then
- if [ $PCTUSED -gt $TRANSACTION_LOG_THRESHOLD_PCT ]; then
- log 1 "Will not kick off another reorg due to logfile PCTUSED above threshold of $LOG_THRESHOLD\n$LOG_USED"
- continue
- else
- log 3 "$LOG_USED"
- fi
- fi
- fi
-
- ##
- ## kick off another reorg
- ## if rc=0 then ok, else we ABORT the OBJECT and don't try again
- ##
- log 3 ""
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- if [ $isTable -eq 1 ]; then
-
- db2 -v "reorg table $TABSCHEMA.$TABNAME inplace allow write access"
- rc=$?
-
- elif [ $isIndex -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace allow write access"
- rc=$?
- fi
-
- elif [ $IF_STATS -eq 3 ]; then
-
- ## for offline we throw a job at db2 and wait a few seconds and check the output
- ## output could be "reorg indexes all for table ...",
- ## or SQL error
- ## or 'DB20000I The REORG command completed successfully.'
- ## not sure if there is a better way to do this
- TMPLOG="/tmp/$TABSCHEMA.$TABNAME.tmp";
- db2 -v "reorg indexes all for table $TABSCHEMA.$TABNAME allow write access" > $TMPLOG 2>&1 &
- sleep 5;
- cat $TMPLOG;
- RC=$( grep '^SQL' $TMPLOG);
- rc=$?
- if [ $rc -eq 0 ]; then
- log 1 "Failed to kick off reorg\n$RC";
- rc=1;
- else
- ## reorg could have finished then no need for the big sleep
- RC=$( grep 'DB20000I The REORG command completed successfully.' $TMPLOG);
- if [ $? -eq 0 ]; then
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=1;
- fi
- rc=0;
-
- fi
- rm -f $TMPLOG;
-
- fi
-
- if [ $rc -eq 0 ]; then
- REORG_STATUS=KICKED_OFF;
- else
- REORG_STATUS=ABORTED;
- fi
- OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
- if [ $rc -ne 0 ]; then
- let NUM_REORGS_ABORTED+=1;
- continue
- fi
-
- ## add the table to the TABLE_IN_USE_ARRAY
- addTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
- rc=$?
- if [ $rc -eq 1 ]; then
- log 1 "Failed to add table $TABSCHEMA.$TABNAME to TABLE_IN_USE_ARRAY";
- fi
- let NUM_REORGS_KICKED_OFF+=1;
- let NUM_REORGS_IN_PROGRESS+=1;
-
- continue;
-
- fi
-
- ##
- ## ouput STATUS
- ##
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
- log 3 "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $RC : $REORG_PERCENT_COMPLETE %" | tee -a $REORG_TABLE_INDEX_DEBUG
- elif [ $IF_STATS -eq 3 ]; then
- log 3 "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME \n$DB2PD_REORG_INDEX_RECORD "| tee -a $REORG_TABLE_INDEX_DEBUG
-
- fi
-
- ##
- ## if reorg timeout then issue a stop to current reorgs that are STARTED
- ## no error checking for stopping a reorg
- ## no need to update OBJECT array as it will be updated on next loop
- ##
-
- if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
-
- if [ "$REORG_STATUS" == "STARTED" ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
-
-
- if [ $isTable -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME inplace stop"
- rc=$?
- elif [ $isIndex -eq 1 ]; then
- db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace stop"
- rc=$?
- fi
-
- fi
-
- fi
-
- done ## for OBJECT_ARRAY[@]
-
- ## check if we are done with all OBJECTS
- if [ $((NUM_REORGS_COMPLETED + NUM_REORGS_STOPPED + NUM_REORGS_ABORTED)) -ge $NUM_REORG_OBJECTS ]; then
- log 3 "All reorgs are completed, stopped or aborted, $NUM_REORGS_COMPLETED:$NUM_REORGS_STOPPED:$NUM_REORGS_ABORTED:$NUM_REORG_OBJECTS"
- break
- fi
-
- ## wait some time
- if [ $IF_STATS -eq 3 ] && [ $IF_STATS_BYPASS_SLEEP_INTERVAL_TIME -eq 1 ]; then
- sleep 1;
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
- else
- sleep $SLEEP_INTERVAL_TIME
- fi
-
- done ## while true
+ ## variables that need to be reset on each run of the function
+ NUM_REORGS_IN_PROGRESS=0;
+ NUM_REORGS_KICKED_OFF=0;
+ NUM_REORGS_COMPLETED=0;
+ NUM_REORGS_STOPPED=0;
+ NUM_REORGS_ABORTED=0;
+
+ while true
+ do
+
+ ## check reorg window maintenance time
+ MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
+ DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
+
+ ## safety valve - if for some reason the logic can't stop the reorgs
+ if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + REORG_TIMEOUT_OVERFLOW_VALVE )) ]; then
+ log 1 "REORG_TIMEOUT_OVERFLOW_VALVE detected";
+ log 1 "Aborting reorgs"
+ break;
+ fi
+
+ if [ $DIFF -ge $REORG_TIMEOUT_WINDOW_SECONDS ]; then
+
+ REORG_TIMEOUT_WINDOW_COMPLETED=1;
+
+ ## -twa: timeout window action: default=3
+ ## 1=allow current reorg(s) to continue
+ ## 2=stop current reorg(s)
+ ## 3=stop current reorg(s) if < 80% complete
+ if [ $REORG_TIMEOUT_WINDOW_ACTION -eq 1 ]; then
+
+ log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
+ break
+
+ elif [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ]; then
+
+ ## use of the REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER
+ ## 0 = ABORT those not started and issue a STOP to those STARTED
+ ## 1 = loop again and see if script exits as all reorgs are COMPLETED and STOPPED and ABORTED
+ ## 2 = break out
+ if [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 0 ]; then
+ let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
+ log 3 "Reorg window ending, reorg window time exceeded, twa=$REORG_TIMEOUT_WINDOW_ACTION"
+ log 3 "Aborting reorgs NOTSTARTED and issuing a STOP to those that are STARTED"
+ elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+ let REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER+=1
+ log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
+ elif [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 2 ]; then
+ log 3 "REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=$REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER"
+ log 3 "Breaking out of reorg loop"
+ break;
+ fi
+ fi
+ fi
+
+ ## loop for all OBJECTS - extract relevant data from OBJECT array
+ ## if we have NOTSTARTED in the OBJECT_ARRAY[N] - then kick off a reorg
+ ## then check tables reorg status
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+ ## get table related info
+ TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
+ TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
+ INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
+ INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
+ IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
+ OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
+ OBJECT_REORG_START=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f7 );
+ OBJECT_REORG_END=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f8 );
+ TABLEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f9 );
+ TBSPACEID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f10 );
+ LOCK_COUNT=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f11 );
+ OBJECT_REORG_TABLE_TYPE=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f12 );
+ isTable=0;
+ isIndex=0;
+ if [ "$INDSCHEMA" == "NULL" -a "$INDNAME" == "NULL" ]; then
+ isTable=1;
+ else
+ isIndex=1;
+ fi
+
+ if [ $OBJECT_REORG_TABLE_TYPE -ne $REORG_TABLE_TYPE ]; then
+ continue;
+ fi
+
+ # log 5 "${OBJECT_ARRAY[$ii]}"
+
+ ##
+ ## has OBJECT COMPLETED - no need to continue here
+ ##
+ if [[ "$OBJECT_REORG_STATUS" == "COMPLETED" || "$OBJECT_REORG_STATUS" == "STOPPED" || "$OBJECT_REORG_STATUS" == "ABORTED" ]]; then
+ continue;
+ fi
+
+ if [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
+
+ ##
+ ## query db2 for REORG_STATUS etc - there may not be an entry so carry on
+ ##
+ RC_SNAP=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER, VARCHAR_FORMAT(REORG_START, 'YYYY-MM-DD-HH24:MI:SS') as REORG_START, VARCHAR_FORMAT(REORG_END, 'YYYY-MM-DD-HH24:MI:SS') as REORG_END, REORG_INDEX_ID, REORG_TBSPC_ID from table(snap_get_tab_reorg('')) where tabschema='$TABSCHEMA' and tabname='$TABNAME' and REORG_START > TIMESTAMP('$WINDOW_START_TIME_DB2') and REORG_INDEX_ID=$IID");
+ rc=$?
+ if [ $rc -ge 2 ]; then
+ log 0 "Possible error running select query against db2\nrc=$rc\nRC=$RC"
+ continue;
+ fi
+
+ if [ $rc -eq 0 ]; then
+ RC=$( echo "$RC_SNAP" | awk 'BEGIN {ORS="\t"} { for(ii=1 ; ii<=NF ; ii++) print $ii; }')
+ REORG_STATUS=$( echo "$RC_SNAP" | awk '{print $1}' );
+ REORG_COMPLETION=$( echo "$RC_SNAP" | awk '{print $2}' );
+ REORG_CURRENT_COUNTER=$( echo "$RC_SNAP" | awk '{print $4}' );
+ REORG_MAX_COUNTER=$( echo "$RC_SNAP" | awk '{print $5}' );
+ REORG_START=$( echo "$RC_SNAP" | awk '{print $6}' );
+ REORG_END=$( echo "$RC_SNAP" | awk '{print $7}' );
+ REORG_INDEX_ID=$( echo "$RC_SNAP" | awk '{print $8}' );
+
+ declare -i REORG_PERCENT_COMPLETE=0
+ if [[ ! -z "$REORG_CURRENT_COUNTER" && $REORG_CURRENT_COUNTER -gt 0 ]]; then
+ if [[ ! -z "$REORG_MAX_COUNTER" && $REORG_MAX_COUNTER -gt 0 ]]; then
+ if [ $REORG_MAX_COUNTER -ge $REORG_CURRENT_COUNTER ]; then
+ REORG_PERCENT_COMPLETE=$(echo $REORG_CURRENT_COUNTER $REORG_MAX_COUNTER | awk '{ print int (($1/$2)*100) }' );
+ fi
+ fi
+ fi
+ fi
+
+ # log 5 "RC_SNAP=$RC_SNAP"
+
+ elif [ $IF_STATS -eq 3 ]; then
+
+ DB2PD_REORG_INDEX_RECORD=$( db2pd -db $DBNAME -reorgs index | grep -B1 -A11 -w "^TbspaceID: $TBSPACEID" | grep -B1 -A11 -w "TableID: $TABLEID" );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ REORG_START=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | awk '{ print $3,$4}' );
+ REORG_START_SECONDS=$(date --date="$REORG_START" '+%s');
+
+ if [ $REORG_START_SECONDS -ge $IF_STATS_WINDOW_START_TIME_DB2 ]; then
+ REORG_STATUS=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Status:' | awk '{ $1=""; print $0}' | sed 's/^[ \t]*//;s/[ \t]*$//' );
+ ## some differences between snap_get_tab_reorg and db2pd -reogrs index output
+ if [ "$REORG_STATUS" == "In Progress" ]; then
+ REORG_STATUS="STARTED";
+ elif [ "$REORG_STATUS" == "Completed" ]; then
+ REORG_STATUS="COMPLETED";
+ elif [ "$REORG_STATUS" == "Stopped" ]; then
+ REORG_STATUS="STOPPED";
+ fi
+
+ REORG_END=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep '^Start Time:' | grep 'End Time:' | awk '{ print $7,$8}' );
+ REORG_IND_CUR_STATUS=$( echo "$DB2PD_REORG_INDEX_RECORD" | grep "Status:" );
+ REORG_IND_CUR=$(echo "$DB2PD_REORG_INDEX_RECORD" | grep "Cur Index:" );
+ REORG_INDEX_STATUS=$(printf "%-25s %-10s" "$REORG_IND_CUR_STATUS" "$REORG_IND_CUR")
+ fi
+ fi
+ fi
+
+ ##
+ ## has OBJECT been KICKED_OFF or STARTED
+ ## if it has check to see if is STARTED or COMPLETED
+ ## update OBJECT_ARRAY
+ ## update COMPLETION/STOPPED stats
+ ##
+ if [ "$OBJECT_REORG_STATUS" == "KICKED_OFF" ] || [ "$OBJECT_REORG_STATUS" == "STARTED" ]; then
+ if [ ! -z "$REORG_STATUS" ]; then
+ if [ "$REORG_STATUS" == "STARTED" -o "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$REORG_START#$REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE"
+ fi
+
+ if [ "$REORG_STATUS" == "COMPLETED" -o "$REORG_STATUS" == "STOPPED" ]; then
+
+ removeTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ log 1 "Failed to remove table $TABSCHEMA.$TABNAME from TABLE_IN_USE_ARRAY";
+ fi
+
+ if [ "$REORG_STATUS" == "COMPLETED" ]; then
+ let NUM_REORGS_COMPLETED+=1
+ elif [ "$REORG_STATUS" == "STOPPED" ]; then
+ let NUM_REORGS_STOPPED+=1
+ fi
+
+ let NUM_REORGS_IN_PROGRESS-=1
+ fi
+
+ fi
+
+ ##
+ ## OBJECT is NOSTARTED so KICK_OFF a reorg
+ ##
+ elif [ "$OBJECT_REORG_STATUS" == "NOTSTARTED" ]; then
+
+ ## dont kick off any reorgs if window timeout passed and TWA=2
+ ## OBJECTS become ABORTED - UPDATE OBJECT_ARRAY
+ if [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+ REORG_STATUS=ABORTED;
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ let NUM_REORGS_ABORTED+=1;
+ continue;
+
+ fi
+
+ ## is the TABLE already being used -if it is goto next OBJECT
+ existTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ [ $rc -eq 0 ] && continue;
+
+ ## we only want to kick off so many reorgs at any one time
+ if [ $NUM_REORGS_IN_PROGRESS -eq $MAX_ASYNC_REORGS_ALLOWED ]; then
+ continue;
+ fi
+
+ ##
+ ## The table could already be locked - if it is then by-pass it
+ ## and ABORT if locked more than 10 times
+ ##
+ TABLE_LOCKED=$( db2 "select APPLICATION_HANDLE, LOCK_OBJECT_TYPE, LOCK_MODE, LOCK_CURRENT_MODE, LOCK_STATUS, LOCK_COUNT, LOCK_HOLD_COUNT, TBSP_ID, TAB_FILE_ID from TABLE (MON_GET_LOCKS(NULL, -2)) where TBSP_ID=$TBSPACEID and TAB_FILE_ID=$TABLEID and LOCK_OBJECT_TYPE='TABLE' and LOCK_MODE='IX' with ur"; );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ let LOCK_COUNT+=1;
+ log 1 "Appears table $TABSCHEMA.$TABNAME is already locked by another application(s), LOCK_COUNT=$LOCK_COUNT";
+ log 1 "$TABLE_LOCKED";
+ if [ $LOCK_COUNT -gt 10 ]; then
+ OBJECT_REORG_STATUS=ABORTED;
+ let NUM_REORGS_ABORTED+=1;
+ log 1 "Aborting table $TABSCHEMA.$TABNAME , LOCK_COUNT=$LOCK_COUNT";
+ fi
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$OBJECT_REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ continue;
+ fi
+
+ ##
+ ## do a check to see where we are on transaction log space - this could be improved!!!!
+ ##
+ #LOG_USED=$( db2 "select cast(LOG_UTILIZATION_PERCENT as decimal(5,2)) as PCTUSED, cast((TOTAL_LOG_USED_KB/1024) as Integer) as TOTUSEDMB, cast((TOTAL_LOG_AVAILABLE_KB/1024) as Integer) as TOTAVAILMB, cast((TOTAL_LOG_USED_TOP_KB/1024) as Integer) as TOTUSEDTOPMB FROM SYSIBMADM.LOG_UTILIZATION ");
+ LOG_USED=$( db2 -x "select LOG_UTILIZATION_PERCENT as PCTUSED FROM SYSIBMADM.MON_TRANSACTION_LOG_UTILIZATION " | tr -d ' ' )
+ if [ ! -z "$LOG_USED" ]; then
+ #PCTUSED=$( echo "$LOG_USED" | awk '{ if(NF==4 && $2 ~/^[0-9]+$/) print int($1)}' );
+ PCTUSED=$( echo $LOG_USED | awk '{print int($1)}')
+ if [ ! -z "$PCTUSED" ]; then
+ if [ $PCTUSED -gt $TRANSACTION_LOG_THRESHOLD_PCT ]; then
+ log 1 "Will not kick off another reorg due to logfile PCTUSED above threshold of $LOG_THRESHOLD% : $LOG_USED%"
+ continue
+ else
+ log 3 "Present LOG Utilization Percentage : $LOG_USED%"
+ fi
+ fi
+ fi
+
+ ##
+ ## kick off another reorg
+ ## if rc=0 then ok, else we ABORT the OBJECT and don't try again
+ ##
+
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+
+ if [ $isTable -eq 1 ]; then
+ log 3 "Processing reorg for table $TABSCHEMA.$TABNAME"
+ db2 "reorg table $TABSCHEMA.$TABNAME inplace allow write access" >> /dev/null 2>&1
+ rc=$?
+ #RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+
+ elif [ $isIndex -eq 1 ]; then
+ log 3 "Processing reorg for table $TABSCHEMA.$TABNAME"
+ db2 "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace allow write access" > /dev/null 2>&1
+ rc=$?
+ #RC=$( db2 "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE, REORG_CURRENT_COUNTER, REORG_MAX_COUNTER from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ RC=$( db2 -x "select REORG_STATUS, REORG_COMPLETION, REORG_PHASE from table(snap_get_tab_reorg('')) where tabname='$TABNAME' " )
+ fi
+
+ elif [ $IF_STATS -eq 3 ]; then
+
+ ## for offline we throw a job at db2 and wait a few seconds and check the output
+ ## output could be "reorg indexes all for table ...",
+ ## or SQL error
+ ## or 'DB20000I The REORG command completed successfully.'
+ ## not sure if there is a better way to do this
+ TMPLOG="/tmp/$TABSCHEMA.$TABNAME.tmp";
+ log 3 "Processing reorg on indexes for table $TABSCHEMA.$TABNAME"
+ db2 -v "reorg indexes all for table $TABSCHEMA.$TABNAME allow write access" > $TMPLOG > /dev/null 2>&1 &
+ sleep 5;
+ cat $TMPLOG;
+ RC=$( grep '^SQL' $TMPLOG);
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ log 1 "Failed to kick off reorg\n$RC";
+ rc=1;
+ else
+ ## reorg could have finished then no need for the big sleep
+ RC=$( grep 'DB20000I The REORG command completed successfully.' $TMPLOG);
+ if [ $? -eq 0 ]; then
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=1;
+ fi
+ rc=0;
+
+ fi
+ rm -f $TMPLOG;
+
+ fi
+
+ if [ $rc -eq 0 ]; then
+ REORG_STATUS=KICKED_OFF;
+ else
+ REORG_STATUS=ABORTED;
+ fi
+ OBJECT_ARRAY[$ii]="$TABSCHEMA#$TABNAME#$INDSCHEMA#$INDNAME#$IID#$REORG_STATUS#$OBJECT_REORG_START#$OBJECT_REORG_END#$TABLEID#$TBSPACEID#$LOCK_COUNT#$OBJECT_REORG_TABLE_TYPE";
+ if [ $rc -ne 0 ]; then
+ let NUM_REORGS_ABORTED+=1;
+ continue
+ fi
+
+ ## add the table to the TABLE_IN_USE_ARRAY
+ addTABLE_TABLE_IN_USE_ARRAY "$TABSCHEMA.$TABNAME"
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ log 1 "Failed to add table $TABSCHEMA.$TABNAME to TABLE_IN_USE_ARRAY";
+ fi
+ let NUM_REORGS_KICKED_OFF+=1;
+ let NUM_REORGS_IN_PROGRESS+=1;
+
+ continue;
+ fi
+
+ ##
+ ## ouput STATUS
+ ##
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+ #echo -e "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $RC \t: $REORG_PERCENT_COMPLETE %" | tee -a $REORG_TABLE_INDEX_DEBUG
+ printf "%-15s %-50s %-50s %-10s\n" "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS" "$TABSCHEMA.$TABNAME" "$RC" "COMPLETION: $REORG_PERCENT_COMPLETE %"| tee -a $REORG_TABLE_INDEX_DEBUG
+
+ elif [ $IF_STATS -eq 3 ]; then
+ #echo -e "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS $TABSCHEMA.$TABNAME : $REORG_INDEX_STATUS "| tee -a $REORG_TABLE_INDEX_DEBUG
+ printf "%-15s %-50s %-10s %15s\n" "$NUM_REORGS_IN_PROGRESS:$NUM_REORGS_KICKED_OFF:$NUM_REORGS_ABORTED:$NUM_REORGS_STOPPED:$NUM_REORGS_COMPLETED:$NUM_REORG_OBJECTS" "$TABSCHEMA.$TABNAME" "$REORG_INDEX_STATUS" | tee -a $REORG_TABLE_INDEX_DEBUG
+ fi
+
+ ##
+ ## if reorg timeout then issue a stop to current reorgs that are STARTED
+ ## no error checking for stopping a reorg
+ ## no need to update OBJECT array as it will be updated on next loop
+ ##
+
+ if [[ $TB_STATS -eq 1 || $IX_STATS -eq 2 ]]; then
+
+ if [ "$REORG_STATUS" == "STARTED" ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED -eq 1 ] && [ $REORG_TIMEOUT_WINDOW_ACTION -eq 2 ] && [ $REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER -eq 1 ]; then
+
+ if [ $isTable -eq 1 ]; then
+ db2 -v "reorg table $TABSCHEMA.$TABNAME inplace stop" > /dev/null 2>&1
+ rc=$?
+ elif [ $isIndex -eq 1 ]; then
+ db2 -v "reorg table $TABSCHEMA.$TABNAME index $INDSCHEMA.$INDNAME inplace stop" > /dev/null 2>&1
+ rc=$?
+ fi
+ fi
+ fi
+
+ done ## for OBJECT_ARRAY[@]
+
+ ## check if we are done with all OBJECTS
+ if [ $((NUM_REORGS_COMPLETED + NUM_REORGS_STOPPED + NUM_REORGS_ABORTED)) -ge $NUM_REORG_OBJECTS ]; then
+ log 3 "Reorgs Status :: Completed : $NUM_REORGS_COMPLETED , Stopped : $NUM_REORGS_STOPPED , Aborted : $NUM_REORGS_ABORTED , Total No of Objects : $NUM_REORG_OBJECTS"
+ break
+ fi
+
+ ## wait some time
+ if [ $IF_STATS -eq 3 ] && [ $IF_STATS_BYPASS_SLEEP_INTERVAL_TIME -eq 1 ]; then
+ sleep 1;
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
+ else
+ sleep $SLEEP_INTERVAL_TIME
+ fi
+
+ done ## while true
}
+# -- Main function starts here
## init
if [ -f ${HOME}/sqllib/db2profile ]; then
@@ -847,9 +857,9 @@ fi
## script already running ?
if [ $( ps -ef | grep $0 | grep -v grep | wc -l ) -gt 2 ]; then
- echo "Warning: appears $0 already running"
- echo "$( ps -ef | grep $0 | grep -v grep )";
- exit 1
+ echo "Warning: appears $0 already running"
+ echo "$( ps -ef | grep $0 | grep -v grep )";
+ exit 1
fi
SCRIPT=$(basename $0)
@@ -871,7 +881,7 @@ LIST_VALID_TABLE_SIZES=0
LIST_REORGCHK_TB_STATS_TABLES=0
LIST_REORGCHK_IX_STATS_TABLES=0
EXECUTE_TABLE_REORG=0
-IGNORE_TABLE_SIZE_THRESHOLD_MAX=20000;
+IGNORE_TABLE_SIZE_THRESHOLD_MAX=100000;
IGNORE_TABLE_SIZE_THRESHOLD_MIN=10;
MAINTENANCE_TIMEOUT_WINDOW_MINUTES=240;
REORG_TIMEOUT_WINDOW_ACTION=2;
@@ -891,8 +901,8 @@ REORGCHK_IF_STATS=3;
## user check
if [ $WHOAMI == "root" ]; then
- log 0 " This script should be not run as '$WHOAMI', but as instance owner."
- exit 1
+ log 0 " This script should be not run as '$WHOAMI', but as instance owner."
+ exit 1
fi
##
@@ -900,97 +910,99 @@ fi
##
while [ $# -gt 0 ]
do
- case $1 in
- -h|-H|-help|--help) UsageHelp; exit 1 ;;
-
- -db) shift; [ ! -z $1 ] && DB=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -s) shift; [ ! -z $1 ] && SCHEMANAME_IN=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -t) shift; [ ! -z "$1" ] && TABLE_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -tb_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_TB_STATS; TB_STATS=1 ;;
- -ti) shift; [ ! -z "$1" ] && INDEX_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
- -ix_stats) IX_STATS=2 ;;
- -if_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_IF_STATS; IF_STATS=3 ;;
- -ittx) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MAX=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -ittn) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MIN=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -l) LIST_ONLY=1 ;;
- -lf) LIST_FRAGMENTED_INDEXES=1 ;;
- -ls) LIST_VALID_TABLE_SIZES=1 ;;
- -lt) LIST_REORGCHK_TB_STATS_TABLES=1 ;;
- -li) LIST_REORGCHK_IX_STATS_TABLES=1 ;;
-
- -window) shift; isNumeric $1 && { MAINTENANCE_TIMEOUT_WINDOW_MINUTES=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -twa) shift; isNumeric $1 && { REORG_TIMEOUT_WINDOW_ACTION=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -mar) shift; isNumeric $1 && { MAX_ASYNC_REORGS_ALLOWED=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -log) shift; isNumeric $1 && { TRANSACTION_LOG_THRESHOLD_PCT=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
- -tr) EXECUTE_TABLE_REORG=1 ;;
-
- -trsi) TRSI=1 ;;
- -reorg) shift; [ ! -z "$1" ] && REORG=$( echo "$1" ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -ignore) shift; [ ! -z "$1" ] && { IGNORE_TABLES="$1"; } || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
-
- -sleep) shift; isNumeric $1 && { SLEEP_INTERVAL_TIME=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
-
- (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
- (*) break;;
- esac
-
+ case $1 in
+ -h|-H|-help|--help) UsageHelp; exit 1 ;;
+
+ -db|-d) shift; [ ! -z $1 ] && DBNAME=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -s) shift; [ ! -z $1 ] && SCHEMANAME_IN=$( echo $1 | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -t) shift; [ ! -z "$1" ] && TABLE_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -tb_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_TB_STATS; TB_STATS=1 ;;
+ -ti) shift; [ ! -z "$1" ] && INDEX_IN=$( echo "$1" | tr '[a-z]' '[A-Z]' ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ix_stats) IX_STATS=2 ;;
+ -if_stats) REORGCHK_TB_IF_STATS_OPTION+=$REORGCHK_IF_STATS; IF_STATS=3 ;;
+ -ittx) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MAX=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ittn) shift; isNumeric $1 && { IGNORE_TABLE_SIZE_THRESHOLD_MIN=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+
+ -l) LIST_ONLY=1 ;;
+ -lf) LIST_FRAGMENTED_INDEXES=1 ;;
+ -ls) LIST_VALID_TABLE_SIZES=1 ;;
+ -lt) LIST_REORGCHK_TB_STATS_TABLES=1 ;;
+ -li) LIST_REORGCHK_IX_STATS_TABLES=1 ;;
+
+ -window) shift; isNumeric $1 && { MAINTENANCE_TIMEOUT_WINDOW_MINUTES=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -twa) shift; isNumeric $1 && { REORG_TIMEOUT_WINDOW_ACTION=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -mar) shift; isNumeric $1 && { MAX_ASYNC_REORGS_ALLOWED=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -log) shift; isNumeric $1 && { TRANSACTION_LOG_THRESHOLD_PCT=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+ -tr) EXECUTE_TABLE_REORG=1 ;;
+
+ -trsi) TRSI=1 ;;
+ -reorg) shift; [ ! -z "$1" ] && REORG=$( echo "$1" ) || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -ignore) shift; [ ! -z "$1" ] && { IGNORE_TABLES="$1"; } || { echo "Error: Must enter an argument for this option"; UsageHelp; exit 1 ; } ;;
+ -sleep) shift; isNumeric $1 && { SLEEP_INTERVAL_TIME=$1; } || { echo "Error: Must enter an numeric argument for this option"; UsageHelp; exit 1 ; } ;;
+
+ (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
+ (*) break;;
+ esac
shift
-
done
##
## some verification
##
+if [[ -z "$DBNAME" && -z "$SCHEMANAME_IN" ]]; then
+ log 0 "Please provide Database Name and Schema Name "
+ exit 1
+
+fi
+: '
if [ -z "$SCHEMANAME_IN" ]; then
- log 0 "must enter a schemaname"
- exit 1
+ log 0 "must enter a schemaname"
+ exit 1
fi
-
+'
CHECK=1
if [ $CHECK -eq 0 ]; then
- rc=0
- if [ $TB_STATS -eq 1 ] && [ $IX_STATS -eq 2 -o $IF_STATS -eq 3 ]; then
- rc=1;
- elif [ $IX_STATS -eq 2 ] && [ $TB_STATS -eq 1 -o $IF_STATS -eq 3 ]; then
- rc=1;
- elif [ $IF_STATS -eq 3 ] && [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
- rc=1;
- fi
- if [ $rc -eq 1 ]; then
- log 0 "can't define more than one of -tb_stats, -ix_stats or -if_stats"
- exit 1
- fi
+ rc=0
+ if [ $TB_STATS -eq 1 ] && [ $IX_STATS -eq 2 -o $IF_STATS -eq 3 ]; then
+ rc=1;
+ elif [ $IX_STATS -eq 2 ] && [ $TB_STATS -eq 1 -o $IF_STATS -eq 3 ]; then
+ rc=1;
+ elif [ $IF_STATS -eq 3 ] && [ $TB_STATS -eq 1 -o $IX_STATS -eq 2 ]; then
+ rc=1;
+ fi
+ if [ $rc -eq 1 ]; then
+ log 0 "can't define more than one of -tb_stats, -ix_stats or -if_stats"
+ exit 1
+ fi
fi ## CHECK
if [ $TB_STATS -eq 1 ] && [ ! -z "$INDEX_IN" ]; then
- log 0 "can't define -ti with -tb_stats"
- exit 1
+ log 0 "can't define -ti with -tb_stats"
+ exit 1
elif [ $IX_STATS -eq 2 ] && [ ! -z "$TABLE_IN" ]; then
- log 0 "can't define -t with -ix_stats"
- exit 1
+ log 0 "can't define -t with -ix_stats"
+ exit 1
elif [ $IF_STATS -eq 3 ] && [ ! -z "$INDEX_IN" ]; then
- log 0 "can't define -ti with -if_stats"
- exit 1
+ log 0 "can't define -ti with -if_stats"
+ exit 1
fi
if [ $TRANSACTION_LOG_THRESHOLD_PCT -gt 99 ]; then
- log 0 "-log option should be less than 100, TRANSACTION_LOG_THRESHOLD_PCT=$TRANSACTION_LOG_THRESHOLD_PCT"
- exit 1
+ log 0 "-log option should be less than 100, TRANSACTION_LOG_THRESHOLD_PCT=$TRANSACTION_LOG_THRESHOLD_PCT"
+ exit 1
fi
if [ $IGNORE_TABLE_SIZE_THRESHOLD_MIN -ge $IGNORE_TABLE_SIZE_THRESHOLD_MAX ]; then
- log 0 "option -ittx should be greater than option -ittn"
- exit 1
+ log 0 "option -ittx should be greater than option -ittn"
+ exit 1
fi
## override some defaults for offline reorgs
#if [ $IF_STATS -eq 3 ]; then
-# MAX_ASYNC_REORGS_ALLOWED=1;
-# REORG_TIMEOUT_WINDOW_ACTION=1;
-# ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
-# SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
+# MAX_ASYNC_REORGS_ALLOWED=1;
+# REORG_TIMEOUT_WINDOW_ACTION=1;
+# ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
+# SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
#fi
## fixup REORG filter string for grep
@@ -1009,328 +1021,328 @@ RUNSTATS_TIMEOUT_WINDOW_SECONDS=$( echo $MAINTENANCE_TIMEOUT_WINDOW_SECONDS | aw
##
log 3 "Starting $0 at $(date) on $HOSTNAME"
-DBNAMES=$( db2 list db directory | grep -E "alias|Indirect" | grep -B 1 Indirect | grep alias | awk '{print $4}' | sort )
+#DBNAMES=$( db2 list db directory | grep -E "alias|Indirect" | grep -B 1 Indirect | grep alias | awk '{print $4}' | sort )
##
## loops for all dbs
##
-for DBNAME in $DBNAMES
-do
-
- ## just process the one db
- if [ ! -z "$DB" ] && [ "$DB" != "$DBNAME" ] ; then
- continue
- fi
-
- ## can't run script on a STANDBY db
- ROLE=$(db2 "get db cfg for $DBNAME" | grep 'HADR database role' | cut -d '=' -f2 | sed 's/ *//g')
- if [ -z "$ROLE" ] || [ "$ROLE" == "" ]; then
- log 1 " Can't determine hadr database role from 'db2 get db cfg for $DBNAME'"
- continue
- elif [ "$ROLE" == "STANDBY" ]; then
- log 1 " Can't run script '${0}' for $DBNAME with hadr database role '$ROLE'"
- continue
- fi
-
- log 3 "DB=$DBNAME ..."
-
- db2 connect to $DBNAME >> /dev/null 2>&1
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 " can't connect to $DBNAME"
- continue
- fi
-
- if [ $TRSI -eq 1 ]; then
- TRSI
- continue
-
- elif [ $LIST_VALID_TABLE_SIZES -eq 1 ]; then
- getValidTableSizes
- log 3 "The following $NUM_VALID_TABLES are valid table sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$VALID_TABLE_SIZES_RAW_DATA"
- continue
-
- elif [ $LIST_FRAGMENTED_INDEXES -eq 1 ]; then
- getValidFragmentedIndexes
- VALID_FRAMENTED_INDEXES_HEADER="TABSCHEMA TABNAME INDSCHEMA INDNAME INDCARD STATS_TIME LAST_USED NLEAF SEQUENTIAL_PAGES";
- log 3 "The following $NUM_VALID_FRAGMENTED_INDEXES are fragmenated indexes based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$VALID_FRAMENTED_INDEXES_HEADER\n$VALID_FRAGMENTED_INDEXES_RAW_DATA"
- continue;
- elif [ $LIST_REORGCHK_TB_STATS_TABLES -eq 1 ]; then
- getValidTablesToReorg
- REORGCHK_TB_STATS_HEADER="TABLE_SCHEMA TABLE_NAME CARD OVERFLOW NPAGES FPAGES ACTIVE_BLOCKS TSIZE F1 F2 F3 REORG";
- log 3 "The following $NUM_VALID_TABLES_TO_REORG are results from REORGCHK_TB_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$REORGCHK_TB_STATS_HEADER\n$VALID_TABLES_TO_REORG_RAW_DATA"
- continue;
-
- elif [ $LIST_REORGCHK_IX_STATS_TABLES -eq 1 ]; then
- getValidIndexesToReorg
- REORGCHK_IX_STAT_HEADER="TABLE_SCHEMA TABLE_NAME INDEX_SCHEMA INDEX_NAME INDCARD NLEAF NUM_EMPTY_LEAFS NLEVELS NUMRIDS_DELETED FULLKEYCARD LEAF_RECSIZE NONLEAF_RECSIZE LEAF_PAGE_OVERHEAD NONLEAF_PAGE_OVERHEAD PCT_PAGES_SAVED F4 F5 F6 F7 F8 REORG";
- log 3 "The following $NUM_VALID_INDEXES_TO_REORG are results from REORGCHK_IX_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB\n$REORGCHK_IX_STAT_HEADER\n$VALID_INDEXES_TO_REORG_RAW_DATA"
- continue;
-
-
- fi
-
-
- INPLACE=1
- if [ $INPLACE -eq 1 ]; then
-
- log 3 " SCHEMA: $SCHEMANAME_IN"
- log 3 " TABLES: $TABLE_IN"
- log 3 "INDEXES: $INDEX_IN"
-
- ##
- ## input table(s) verification
- ## verify input table exist
- ## and table is within size limits
- ## create the OBJECT_ARRAY that holds the relevant table information
- ##
- if [ ! -z "$TABLE_IN" ]; then
-
- TABLE_IN=$( echo "$TABLE_IN" | tr ' ' '\n' );
- for TABNAME in $TABLE_IN
- do
-
- ## make sure table exists
- RC=$( db2 -x "select tabname from syscat.tables where tabname = '$TABNAME' and tabschema = '$SCHEMANAME_IN' and type = 'T'");
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "input command line table '$TABNAME' does not exist or is invalid"
- exit 1
- fi
-
- isTableWithinSizeLimit $SCHEMANAME_IN $TABNAME
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
- exit 1
- fi
-
- done
-
- if [ $TB_STATS -eq 1 ]; then
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ $IF_STATS -eq 3 ]; then
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
-
- elif [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
- for REORG_TYPE in 0 1
- do
- if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
- getValidTablesToReorg
- TABLE_IN="$VALID_TABLES_TO_REORG";
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
- getValidFragmentedIndexes
- TABLE_IN="$VALID_FRAGMENTED_INDEXES"
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
- done
-
- elif [ $TB_STATS -eq 1 ]; then
- getValidTablesToReorg
- TABLE_IN="$VALID_TABLES_TO_REORG";
- createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
- elif [ $IF_STATS -eq 3 ]; then
- getValidFragmentedIndexes
- TABLE_IN="$VALID_FRAGMENTED_INDEXES"
- createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
- fi
-
- ##
- ## input indexes verification
- ## verify input indexes exist
- ##
- if [ ! -z "$INDEX_IN" ]; then
- INDEX_IN=$( echo "$INDEX_IN" | tr ' ' '\n' );
- for INDEX in $INDEX_IN
- do
- ## make sure index exists, especially those input on command line
- TABSCHEMA=$( echo $INDEX | cut -d. -f1);
- TABNAME=$( echo $INDEX | cut -d. -f2);
- INDSCHEMA=$( echo $INDEX | cut -d. -f3);
- INDNAME=$( echo $INDEX | cut -d. -f4);
- RC=$( db2 -x "select indname from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 " input command line index '$INDEX' does not exist"
- exit 1
- fi
-
- isTableWithinSizeLimit $TABSCHEMA $TABNAME
- rc=$?
- if [ $rc -ne 0 ]; then
- log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
- exit 1
- fi
-
- done
-
- createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
- ##
- ##
- elif [ $IX_STATS -eq 2 ]; then
- getValidIndexesToReorg
- INDEX_IN="$VALID_INDEXES_TO_REORG"
- createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
- fi
-
- ## get the NUMBER of tables per reorg table type
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $TB_STATS; OBJECT_NUM_TB_STATS=$?;
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IX_STATS; OBJECT_NUM_IX_STATS=$?;
- getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IF_STATS; OBJECT_NUM_IF_STATS=$?;
-
- ## just list out the OBJECT_ARRAY and exit
- if [ $LIST_ONLY -eq 1 ]; then
-
- listOBJECT_ARRAY;
- exit 1
- fi
-
-
- if [ $EXECUTE_TABLE_REORG -eq 1 ]; then
-
-
- ##
- ## this is the main list of what we are going to reorg
- ##
- echo ""
-
- listOBJECT_ARRAY;
-
-# exit 1
-
- ##
- ## setup some control variables for the main loop
- ##
- ## REORG_STATUS COMPLETED PAUSED STARTED STOPPED TRUNCATE
- ##
- MAINTENANCE_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
- REORG_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
- WINDOW_START_TIME_DB2=$( date '+%Y-%m-%d-%H.%M.%S' );
- IF_STATS_WINDOW_START_TIME_DB2=$( date '+%s' );
- IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
- NUM_REORG_OBJECTS="${#OBJECT_ARRAY[@]}";
-# NUM_REORGS_IN_PROGRESS=0;
-# NUM_REORGS_KICKED_OFF=0;
-# NUM_REORGS_COMPLETED=0;
-# NUM_REORGS_STOPPED=0;
-# NUM_REORGS_ABORTED=0;
- REORG_TIMEOUT_OVERFLOW_VALVE=300;
- REORG_TIMEOUT_WINDOW_COMPLETED=0;
- REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=0;
- initTABLE_IN_USE_ARRAY $MAX_ASYNC_REORGS_ALLOWED
-
- ## multi table reorg option
- ## online table reorg and offline index reorgs have different options
- MAX_ASYNC_REORGS_ALLOWED_ORG=$MAX_ASYNC_REORGS_ALLOWED;
- REORG_TIMEOUT_WINDOW_ACTION_ORG=$REORG_TIMEOUT_WINDOW_ACTION;
- SLEEP_INTERVAL_TIME_ORG=$SLEEP_INTERVAL_TIME;
-
- ## override some defaults for offline reorgs
- #if [ $IF_STATS -eq 3 ]; then
- # MAX_ASYNC_REORGS_ALLOWED=1;
- # REORG_TIMEOUT_WINDOW_ACTION=1;
- # ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
- # SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
- #fi
-
- echo ""
- log 3 "Starting reorg of ..."
-
- if [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
- for REORG_TYPE in 0 1
- do
-
- if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
- TB_STATS=1;
- IF_STATS=0;
- NUM_REORG_OBJECTS=$OBJECT_NUM_TB_STATS;
- REORG_TABLE_TYPE=$TB_STATS;
- MAX_ASYNC_REORGS_ALLOWED=$MAX_ASYNC_REORGS_ALLOWED_ORG;
- REORG_TIMEOUT_WINDOW_ACTION=$REORG_TIMEOUT_WINDOW_ACTION_ORG;
- SLEEP_INTERVAL_TIME=$SLEEP_INTERVAL_TIME_ORG;
-
- elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
- TB_STATS=0;
- IF_STATS=3;
- NUM_REORG_OBJECTS=$OBJECT_NUM_IF_STATS;
- REORG_TABLE_TYPE=$IF_STATS;
- MAX_ASYNC_REORGS_ALLOWED=1;
- REORG_TIMEOUT_WINDOW_ACTION=1;
- SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME_ORG | awk '{ print $1/3 }');
- fi
-
- reorgTables
- done
- else
- if [ $TB_STATS -eq 1 ]; then
- REORG_TABLE_TYPE=$TB_STATS;
- elif [ $IX_STATS -eq 2 ]; then
- REORG_TABLE_TYPE=$IX_STATS;
- elif [ $IF_STATS -eq 3 ]; then
- REORG_TABLE_TYPE=$IF_STATS;
- fi
- reorgTables
- fi
-
- ## list current state of OBJECT_ARRAY
- listOBJECT_ARRAY;
-
- ##
- ## now do runstats
- ##
- log 3 "Starting runstats of ..."
- RUNSTATS_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
-
- for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
- do
-
- ## check runstats window maintenance time
- MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
- DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
- if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + RUNSTATS_TIMEOUT_WINDOW_SECONDS)) ]; then
- log 3 "$REORG_TIMEOUT_WINDOW_START_TIME_SECONDS
-$MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS $DIFF"
- log 3 "Runstats window ending, runstats window time exceeded"
- break
- fi
-
- ## get table info
- TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
- TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
- INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
- INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
- IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
- OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
-
- ## only do a runstats if table/index has completed
- ## verify stats time so we dont kick off another runstats on the same table
- if [ "$OBJECT_REORG_STATUS" == "COMPLETED" ]; then
- STATS_TIME=$( db2 -x "select stats_time from syscat.tables where tabschema='$TABSCHEMA' and tabname='$TABNAME' and stats_time < TIMESTAMP('$WINDOW_START_TIME_DB2') " );
- rc=$?
- if [ $rc -eq 0 ]; then
- log 3 "Starting runstats on $TABSCHEMA.$TABNAME"
- # db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON ALL COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS";
- db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON KEY COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS UTIL_IMPACT_PRIORITY 50";
- log 3 "Finished runstats on $TABSCHEMA.$TABNAME"
- fi
- fi
-
- done
-
- fi ## EXECUTE_TABLE_REORG
-
-
- fi ## INPLACE
-
-
-done ## DBNAMES
+#for DBNAME in $DBNAMES
+#do
+
+ ## just process the one db
+# if [ ! -z "$DB" ] && [ "$DB" != "$DBNAME" ] ; then
+# continue
+# fi
+# DBNAME=${DB}
+ ## can't run script on a STANDBY db
+ ROLE=$(db2 "get db cfg for $DBNAME" | grep 'HADR database role' | cut -d '=' -f2 | sed 's/ *//g')
+ if [ -z "$ROLE" ] || [ "$ROLE" == "" ]; then
+ log 1 " Can't determine hadr database role from 'db2 get db cfg for $DBNAME'"
+ continue
+ elif [ "$ROLE" == "STANDBY" ]; then
+ log 1 " Can't run script '${0}' for $DBNAME with hadr database role '$ROLE'"
+ continue
+ fi
+
+ log 3 "DBNAME :: $DBNAME"
+
+ db2 connect to $DBNAME >> /dev/null 2>&1
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 " can't connect to $DBNAME"
+ continue
+ fi
+
+ if [ $TRSI -eq 1 ]; then
+ TRSI
+ continue
+
+ elif [ $LIST_VALID_TABLE_SIZES -eq 1 ]; then
+ getValidTableSizes
+ log 3 "The following $NUM_VALID_TABLES are valid table sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$VALID_TABLE_SIZES_RAW_DATA"
+ continue
+
+ elif [ $LIST_FRAGMENTED_INDEXES -eq 1 ]; then
+ getValidFragmentedIndexes
+ VALID_FRAMENTED_INDEXES_HEADER="TABSCHEMA TABNAME INDSCHEMA INDNAME INDCARD STATS_TIME LAST_USED NLEAF SEQUENTIAL_PAGES";
+ log 3 "The following $NUM_VALID_FRAGMENTED_INDEXES are fragmenated indexes based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$VALID_FRAMENTED_INDEXES_HEADER\n$VALID_FRAGMENTED_INDEXES_RAW_DATA"
+ continue;
+ elif [ $LIST_REORGCHK_TB_STATS_TABLES -eq 1 ]; then
+ getValidTablesToReorg
+ REORGCHK_TB_STATS_HEADER="TABLE_SCHEMA TABLE_NAME CARD OVERFLOW NPAGES FPAGES ACTIVE_BLOCKS TSIZE F1 F2 F3 REORG";
+ log 3 "The following $NUM_VALID_TABLES_TO_REORG are results from REORGCHK_TB_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$REORGCHK_TB_STATS_HEADER\n$VALID_TABLES_TO_REORG_RAW_DATA"
+ continue;
+
+ elif [ $LIST_REORGCHK_IX_STATS_TABLES -eq 1 ]; then
+ getValidIndexesToReorg
+ REORGCHK_IX_STAT_HEADER="TABLE_SCHEMA TABLE_NAME INDEX_SCHEMA INDEX_NAME INDCARD NLEAF NUM_EMPTY_LEAFS NLEVELS NUMRIDS_DELETED FULLKEYCARD LEAF_RECSIZE NONLEAF_RECSIZE LEAF_PAGE_OVERHEAD NONLEAF_PAGE_OVERHEAD PCT_PAGES_SAVED F4 F5 F6 F7 F8 REORG";
+ log 3 "The following $NUM_VALID_INDEXES_TO_REORG are results from REORGCHK_IX_STATS based on tables sizes within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX GB\n$REORGCHK_IX_STAT_HEADER\n$VALID_INDEXES_TO_REORG_RAW_DATA"
+ continue;
+
+ fi
+
+ INPLACE=1
+ if [ $INPLACE -eq 1 ]; then
+
+ log 3 "SCHEMA :: $SCHEMANAME_IN"
+ log 3 "TABLES :: $TABLE_IN"
+ log 3 "INDEXES :: $INDEX_IN"
+ log 3 "Looking for Qualified Tables or Indexes for $SCHEMANAME_IN in $DBNAME . . . "
+ echo ""
+
+ ##
+ ## input table(s) verification
+ ## verify input table exist
+ ## and table is within size limits
+ ## create the OBJECT_ARRAY that holds the relevant table information
+ ##
+ if [ ! -z "$TABLE_IN" ]; then
+
+ TABLE_IN=$( echo "$TABLE_IN" | tr ' ' '\n' );
+ for TABNAME in $TABLE_IN
+ do
+
+ ## make sure table exists
+ RC=$( db2 -x "select tabname from syscat.tables where tabname = '$TABNAME' and tabschema = '$SCHEMANAME_IN' and type = 'T'");
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "input command line table '$TABNAME' does not exist or is invalid"
+ exit 1
+ fi
+
+ isTableWithinSizeLimit $SCHEMANAME_IN $TABNAME
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
+ exit 1
+ fi
+
+ done
+
+ if [ $TB_STATS -eq 1 ]; then
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ $IF_STATS -eq 3 ]; then
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+
+ elif [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
+ for REORG_TYPE in 0 1
+ do
+ if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
+ getValidTablesToReorg
+ TABLE_IN="$VALID_TABLES_TO_REORG";
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
+ getValidFragmentedIndexes
+ TABLE_IN="$VALID_FRAGMENTED_INDEXES"
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+ done
+
+ elif [ $TB_STATS -eq 1 ]; then
+ getValidTablesToReorg
+ TABLE_IN="$VALID_TABLES_TO_REORG";
+ createTableOBJECT_ARRAY "$TABLE_IN" $TB_STATS
+ elif [ $IF_STATS -eq 3 ]; then
+ getValidFragmentedIndexes
+ TABLE_IN="$VALID_FRAGMENTED_INDEXES"
+ createTableOBJECT_ARRAY "$TABLE_IN" $IF_STATS
+ fi
+
+ ##
+ ## input indexes verification
+ ## verify input indexes exist
+ ##
+ if [ ! -z "$INDEX_IN" ]; then
+ INDEX_IN=$( echo "$INDEX_IN" | tr ' ' '\n' );
+ for INDEX in $INDEX_IN
+ do
+ ## make sure index exists, especially those input on command line
+ TABSCHEMA=$( echo $INDEX | cut -d. -f1);
+ TABNAME=$( echo $INDEX | cut -d. -f2);
+ INDSCHEMA=$( echo $INDEX | cut -d. -f3);
+ INDNAME=$( echo $INDEX | cut -d. -f4);
+ RC=$( db2 -x "select indname from syscat.indexes where tabschema = '$TABSCHEMA' and tabname = '$TABNAME' and indschema = '$INDSCHEMA' and indname = '$INDNAME'");
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 " input command line index '$INDEX' does not exist"
+ exit 1
+ fi
+
+ isTableWithinSizeLimit $TABSCHEMA $TABNAME
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ log 0 "Table $TABNAME is not within the range $IGNORE_TABLE_SIZE_THRESHOLD_MIN MB and $IGNORE_TABLE_SIZE_THRESHOLD_MAX MB"
+ exit 1
+ fi
+
+ done
+
+ createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
+ ##
+ ##
+ elif [ $IX_STATS -eq 2 ]; then
+ getValidIndexesToReorg
+ INDEX_IN="$VALID_INDEXES_TO_REORG"
+ createIndexOBJECT_ARRAY "$INDEX_IN" $IX_STATS;
+ fi
+
+ ## get the NUMBER of tables per reorg table type
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $TB_STATS; OBJECT_NUM_TB_STATS=$?;
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IX_STATS; OBJECT_NUM_IX_STATS=$?;
+ getNUM_OBJECT_REORG_TABLE_TYPE_OBJECT_ARRAY $IF_STATS; OBJECT_NUM_IF_STATS=$?;
+
+ ## just list out the OBJECT_ARRAY and exit
+ if [ $LIST_ONLY -eq 1 ]; then
+
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+ listOBJECT_ARRAY;
+ exit 1
+ fi
+
+
+ if [ $EXECUTE_TABLE_REORG -eq 1 ]; then
+
+
+ ##
+ ## this is the main list of what we are going to reorg
+ ##
+ #echo ""
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+
+ listOBJECT_ARRAY;
+
+# exit 1
+
+ ##
+ ## setup some control variables for the main loop
+ ##
+ ## REORG_STATUS COMPLETED PAUSED STARTED STOPPED TRUNCATE
+ ##
+ MAINTENANCE_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+ REORG_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+ WINDOW_START_TIME_DB2=$( date '+%Y-%m-%d-%H.%M.%S' );
+ IF_STATS_WINDOW_START_TIME_DB2=$( date '+%s' );
+ IF_STATS_BYPASS_SLEEP_INTERVAL_TIME=0;
+ NUM_REORG_OBJECTS="${#OBJECT_ARRAY[@]}";
+# NUM_REORGS_IN_PROGRESS=0;
+# NUM_REORGS_KICKED_OFF=0;
+# NUM_REORGS_COMPLETED=0;
+# NUM_REORGS_STOPPED=0;
+# NUM_REORGS_ABORTED=0;
+ REORG_TIMEOUT_OVERFLOW_VALVE=300;
+ REORG_TIMEOUT_WINDOW_COMPLETED=0;
+ REORG_TIMEOUT_WINDOW_COMPLETED_COUNTER=0;
+ initTABLE_IN_USE_ARRAY $MAX_ASYNC_REORGS_ALLOWED
+
+ ## multi table reorg option
+ ## online table reorg and offline index reorgs have different options
+ MAX_ASYNC_REORGS_ALLOWED_ORG=$MAX_ASYNC_REORGS_ALLOWED;
+ REORG_TIMEOUT_WINDOW_ACTION_ORG=$REORG_TIMEOUT_WINDOW_ACTION;
+ SLEEP_INTERVAL_TIME_ORG=$SLEEP_INTERVAL_TIME;
+
+ ## override some defaults for offline reorgs
+ #if [ $IF_STATS -eq 3 ]; then
+ # MAX_ASYNC_REORGS_ALLOWED=1;
+ # REORG_TIMEOUT_WINDOW_ACTION=1;
+ # ## make SLEEP_INTERVAL_TIME 1/3 for IF_STATS
+ # SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME | awk '{ print $1/3 }');
+ #fi
+
+ echo ""
+ log 3 "Starting reorg of ..."
+
+ if [ ${#REORGCHK_TB_IF_STATS_OPTION} -eq 2 ]; then
+ for REORG_TYPE in 0 1
+ do
+
+ if [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "1" ]; then
+ TB_STATS=1;
+ IF_STATS=0;
+ NUM_REORG_OBJECTS=$OBJECT_NUM_TB_STATS;
+ REORG_TABLE_TYPE=$TB_STATS;
+ MAX_ASYNC_REORGS_ALLOWED=$MAX_ASYNC_REORGS_ALLOWED_ORG;
+ REORG_TIMEOUT_WINDOW_ACTION=$REORG_TIMEOUT_WINDOW_ACTION_ORG;
+ SLEEP_INTERVAL_TIME=$SLEEP_INTERVAL_TIME_ORG;
+
+ elif [ "${REORGCHK_TB_IF_STATS_OPTION:$REORG_TYPE:1}" == "3" ]; then
+ TB_STATS=0;
+ IF_STATS=3;
+ NUM_REORG_OBJECTS=$OBJECT_NUM_IF_STATS;
+ REORG_TABLE_TYPE=$IF_STATS;
+ MAX_ASYNC_REORGS_ALLOWED=1;
+ REORG_TIMEOUT_WINDOW_ACTION=1;
+ SLEEP_INTERVAL_TIME=$( echo $SLEEP_INTERVAL_TIME_ORG | awk '{ print $1/3 }');
+ fi
+
+ reorgTables
+ done
+ else
+ if [ $TB_STATS -eq 1 ]; then
+ REORG_TABLE_TYPE=$TB_STATS;
+ elif [ $IX_STATS -eq 2 ]; then
+ REORG_TABLE_TYPE=$IX_STATS;
+ elif [ $IF_STATS -eq 3 ]; then
+ REORG_TABLE_TYPE=$IF_STATS;
+ fi
+ reorgTables
+ fi
+
+ ## list current state of OBJECT_ARRAY
+ #printf "%-15s %-30s %-15s %-30s %-5s %-10s %-25s %-25s %-10s %-10s %-10s %-15s\n" "TABSCHEMA" "TABNAME" "INDSCHEMA" "INDNAME" "IID" "REORG_STATUS" "REORG_START" "REORG_END" "TABLEID" "TBSPACEID" "LOCK_COUNT" "TABLE_TYPE"
+ listOBJECT_ARRAY;
+
+ ##
+ ## now do runstats
+ ##
+ log 3 "Starting runstats of ..."
+ RUNSTATS_TIMEOUT_WINDOW_START_TIME_SECONDS=$( date '+%s' );
+
+ for((ii=0; ii< ${#OBJECT_ARRAY[@]}; ii++))
+ do
+
+ ## check runstats window maintenance time
+ MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS=$( date '+%s' );
+ DIFF=$(( MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS - REORG_TIMEOUT_WINDOW_START_TIME_SECONDS ));
+ if [ $DIFF -ge $(( REORG_TIMEOUT_WINDOW_SECONDS + RUNSTATS_TIMEOUT_WINDOW_SECONDS)) ]; then
+ #log 3 "$REORG_TIMEOUT_WINDOW_START_TIME_SECONDS $MAINTENANCE_TIMEOUT_WINDOW_TIME_NOW_SECONDS $REORG_TIMEOUT_WINDOW_SECONDS $RUNSTATS_TIMEOUT_WINDOW_SECONDS $DIFF"
+ log 3 "Runstats window ending, runstats window time exceeded"
+ break
+ fi
+
+ ## get table info
+ TABSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f1 );
+ TABNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f2 );
+ INDSCHEMA=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f3 );
+ INDNAME=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f4 );
+ IID=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f5 );
+ OBJECT_REORG_STATUS=$( echo ${OBJECT_ARRAY[$ii]} | cut -d# -f6 );
+
+ ## only do a runstats if table/index has completed
+ ## verify stats time so we dont kick off another runstats on the same table
+ if [ "$OBJECT_REORG_STATUS" == "COMPLETED" ]; then
+ STATS_TIME=$( db2 -x "select stats_time from syscat.tables where tabschema='$TABSCHEMA' and tabname='$TABNAME' and stats_time < TIMESTAMP('$WINDOW_START_TIME_DB2') " );
+ rc=$?
+ if [ $rc -eq 0 ]; then
+ log 3 "Starting runstats on $TABSCHEMA.$TABNAME"
+ # db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON ALL COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS";
+ #db2 -v "runstats on table $TABSCHEMA.$TABNAME WITH DISTRIBUTION ON KEY COLUMNS AND SAMPLED DETAILED INDEXES ALL ALLOW WRITE ACCESS UTIL_IMPACT_PRIORITY 50" > /dev/null 2>&1
+ db2 -v "runstats on table $TABSCHEMA.$TABNAME ON ALL COLUMNS WITH DISTRIBUTION ON ALL COLUMNS AND DETAILED INDEXES ALL ALLOW WRITE ACCESS " > /dev/null 2>&1
+ log 3 "Finished runstats on $TABSCHEMA.$TABNAME"
+ fi
+ fi
+
+ done
+
+ fi ## EXECUTE_TABLE_REORG
+
+ fi ## INPLACE
+
+#done ## DBNAMES
##
## cleanup
##
log 3 "Completed $0 at $(date)"
-
exit 0
diff --git a/instance-applications/120-ibm-db2u-database/files/runstats_rebind.sh b/instance-applications/120-ibm-db2u-database/files/runstats_rebind.sh
index 7415d6b4a..dc97ace71 100755
--- a/instance-applications/120-ibm-db2u-database/files/runstats_rebind.sh
+++ b/instance-applications/120-ibm-db2u-database/files/runstats_rebind.sh
@@ -1,41 +1,47 @@
#!/bin/bash
# ***************************************************************************
-# Author: Fu Le Qing (Roking)
-# Email: leqingfu@cn.ibm.com
-# Date: 10-31-2018
+# Author: Fu Le Qing (Roking)
+# Email: leqingfu@cn.ibm.com
+# Date: 10-31-2018
#
-# Description: This script updates statistics of tables,
-# associated indexes in the database, and sends an email
-# to a specified email list.
+# Description: This script updates statistics of tables,
+# associated indexes in the database, and sends an email
+# to a specified email list.
#
# ******** THIS NEEDS TO BE RUN AS INSTANCE OWNER. **************
#
-# Revision history:
-# 10-31-2018 Fu Le Qing (Roking)
-# Original version
-# 11-16-2018 Fu Le Qing (Roking)
-# Skip the tables which are ongoing with reorg
-# 09-08-2023 Fu Le Qing (Roking)
-# Update for MAS
+# Revision history:
+# 10-31-2018 Fu Le Qing (Roking)
+# Original version
+# 11-16-2018 Fu Le Qing (Roking)
+# Skip the tables which are ongoing with reorg
+# 09-08-2023 Fu Le Qing (Roking)
+# Update for MAS
#
# ***************************************************************************
#
# ***************************************************************************
+
+# -- Source the Props file
if [ -f /mnt/backup/bin/.PROPS ]
then
. /mnt/backup/bin/.PROPS
- DOW=`date | awk '{print $1}'`
+ DOW=$(date | awk '{print $1}')
if [ ${DOW} != ${DAYOFFULL} ]
then
+ echo "Runstats runs only on Day of Full backup. . . !!! Exiting !"
exit 0
fi
fi
-instance=`whoami`
-instance_home=`/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${instance}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//'`
+# -- Standard Parameters
+INSTANCE=$(whoami)
+INSTANCE_HOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${INSTANCE}" | awk -F ',' '{print $5}'| sed 's/\/sqllib//')
+mkdir -p ${INSTANCE_HOME}/maintenance/logs
+DATESTAMP=$(date "+%Y-%m-%d-%H.%M.%S")
-pidfile="$instance_home/.`basename ${0}`.pid"
-if [ -e ${pidfile} ] && $kill -0 `cat ${pidfile}` 2>/dev/null
+pidfile="${INSTANCE_HOME}/.$(basename ${0}).pid"
+if [ -e ${pidfile} ] && $kill -0 $(cat ${pidfile}) 2>/dev/null
then
exit 0
fi
@@ -43,48 +49,61 @@ fi
echo $$ > ${pidfile}
trap "rm -f ${pidfile}; exit" SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM EXIT
-if [ ! -f "$instance_home/sqllib/db2profile" ]
+if [ ! -f "${INSTANCE_HOME}/sqllib/db2profile" ]
then
- echo "ERROR - $instance_home/sqllib/db2profile not found"
+ echo "ERROR - ${INSTANCE_HOME}/sqllib/db2profile not found"
exit 1
else
- . $instance_home/sqllib/db2profile
+ . ${INSTANCE_HOME}/sqllib/db2profile
fi
-RUNSTATS_TMP_FILE="$instance_home/.runstats.sql"
-REBIND_TMP_FILE="$instance_home/.rebind.sql"
+# -- Debug Mode
+# set -x; # Uncomment to debug this shell script
+# set -n; # Uncomment to check your syntax, without execution.
-mkdir -p $instance_home/maintenance/logs
-DATESTAMP=`date "+%Y-%m-%d-%H.%M.%S"`
+RUNSTATS_TMP_FILE="${INSTANCE_HOME}/bin/.runstats.sql"
+REBIND_TMP_FILE="${INSTANCE_HOME}/bin/.rebind.sql"
-for db in `db2 list db directory | grep -B 5 Indirect | grep "Database name" | cut -d= -f2`
+for DB in $(db2 list db directory | grep -B 5 Indirect | grep "Database name" | cut -d= -f2)
do
- role=`db2 get db cfg for ${db} | grep "HADR database role" | cut -d= -f2 |sed 's/ //g'`
- if [ "$role" != "STANDBY" ]; then
- if [ -f $RUNSTATS_TMP_FILE ]
- then
- rm $RUNSTATS_TMP_FILE
- fi
- if [ -f $REBIND_TMP_FILE ]
- then
- rm $REBIND_TMP_FILE
- fi
- db2 connect to ${db} | tee $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- if [ $? -eq 0 ]; then
- db2 -x "select 'RUNSTATS ON TABLE \"' ||rtrim(tab.tabschema)||'\".\"'|| tab.tabname ||'\" WITH DISTRIBUTION ON KEY COLUMNS AND DETAILED INDEXES ALL ALLOW WRITE ACCESS;'
- from syscat.tables tab left join sysibmadm.SNAPTAB_REORG reg on tab.tabschema=reg.TABSCHEMA and tab.tabname=reg.TABNAME and reg.REORG_STATUS not in ('COMPLETED','STOPPED')
- where tab.type='T' and reg.tabname is null" > $RUNSTATS_TMP_FILE
- #db2 -x "select 'rebind package \"' ||rtrim(PKGSCHEMA)||'\".\"'|| PKGNAME ||'\";' from syscat.packages where PKGSCHEMA not in ('NULLID','NULLIDR1','NULLIDRA','SYSIBMADM','SYSIBMINTERNAL') and PKGSCHEMA not like 'NULL%' " > $REBIND_TMP_FILE
- echo "Begin processing of runstats @ $DATESTAMP ..." | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- db2 -txvf $RUNSTATS_TMP_FILE | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- echo "End processing of runstats @ $DATESTAMP" | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
+ RUNSTATS_REBIND_LOG="${INSTANCE_HOME}/maintenance/logs/runstats_rebind_${DB}_${DATESTAMP}.log"
+
+ role=$(db2 get db cfg for ${DB} | grep "HADR database role" | cut -d= -f2 |sed 's/ //g')
+ if [ "$role" != "STANDBY" ]; then
+ if [[ -f ${RUNSTATS_TMP_FILE} ]]; then
+ rm ${RUNSTATS_TMP_FILE}
+ fi
+ if [[ -f ${REBIND_TMP_FILE} ]]; then
+ rm ${REBIND_TMP_FILE}
+ fi
+
+ db2 connect to ${DB} | tee ${RUNSTATS_REBIND_LOG}
+ if [[ $? -eq 0 ]]; then
+ # -- Runstats of the tables
+ db2 -x "select 'RUNSTATS ON TABLE \"' ||rtrim(tab.tabschema)||'\".\"'|| tab.tabname ||'\" ON ALL COLUMNS WITH DISTRIBUTION ON ALL COLUMNS AND DETAILED INDEXES ALL ALLOW WRITE ACCESS;' \
+ from syscat.tables tab left join sysibmadm.SNAPTAB_REORG reg on tab.tabschema=reg.TABSCHEMA and tab.tabname=reg.TABNAME \
+ and reg.REORG_STATUS not in ('COMPLETED','STOPPED') where tab.type='T' and reg.tabname is null" > ${RUNSTATS_TMP_FILE}
+
+ # -- Execution of runstats
+ echo -e "Begin processing of runstats @ ${DATESTAMP} ...\n" | tee -a ${RUNSTATS_REBIND_LOG}
+ db2 -txvf ${RUNSTATS_TMP_FILE} | tee -a ${RUNSTATS_REBIND_LOG}
+ echo -e "\nEnd processing of runstats @ ${DATESTAMP}" | tee -a ${RUNSTATS_REBIND_LOG}
+ rm ${RUNSTATS_TMP_FILE}
- #echo "Begin processing of rebind @ $DATESTAMP ..." | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- #db2 -txvf $REBIND_TMP_FILE | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- #echo "End processing of rebind @ $DATESTAMP" | tee -a $instance_home/maintenance/logs/runstats_${db}_${DATESTAMP}
- rm $RUNSTATS_TMP_FILE
- #rm $REBIND_TMP_FILE
- db2 terminate
- fi
- fi
+ # -- Rebind of the packages
+ db2 -x "select 'rebind package \"' ||rtrim(PKGSCHEMA)||'\".\"'|| PKGNAME ||'\";' from syscat.packages
+ where PKGSCHEMA not like 'SYSIBM%' and PKGSCHEMA not like 'NULL%' " > ${REBIND_TMP_FILE}
+
+ # -- Execution of Rebind
+ echo -e "\n ----------------------------------------------- " | tee -a ${RUNSTATS_REBIND_LOG}
+ echo -e "Begin processing of rebind @ ${DATESTAMP} ...\n" | tee -a ${RUNSTATS_REBIND_LOG}
+ db2 -txvf ${REBIND_TMP_FILE} | tee -a ${RUNSTATS_REBIND_LOG}
+ echo -e "\nEnd processing of rebind @ ${DATESTAMP}" | tee -a ${RUNSTATS_REBIND_LOG}
+
+ rm ${REBIND_TMP_FILE}
+ db2 terminate
+ fi
+ fi
done
+
+# -- End of the Script
\ No newline at end of file