Script to find the datadiscrepancy across table partitions b/w mysql servers(Master/slave) . The can also be used(with slight modifications) to find the data discrepancy across 2 standalone servers..
Pre-req: Need to have maatkit checksum tool installed on the server.
create tables checksum and checksum_results
CREATE TABLE checksum (
db char(64) NOT NULL,
tbl char(64) NOT NULL,
chunk int NOT NULL,
boundaries char(100) NOT NULL,
this_crc char(40) NOT NULL,
this_cnt int NOT NULL,
master_crc char(40) NULL,
master_cnt int NULL,
ts timestamp NOT NULL,
PRIMARY KEY (db, tbl, chunk)
);
CREATE TABLE checksum_results (
db char(64) NOT NULL,
tbl char(64) NOT NULL,
chunk char(64) NOT NULL,
boundaries char(100) NOT NULL,
this_crc char(40) NOT NULL,
this_cnt int NOT NULL,
master_crc char(40) NULL,
master_cnt int NULL,
ts timestamp NOT NULL,
);
Usage : checksum_run.sh <MastHost> <SlaveHost> > checksum_run.log 2>checksum_run.err
#====================================================================================
##### Verify if mysql deamon is running #####
SRC=$1
TRG=$2
USER=’xxxxx’
PWD=’xxxx’
LogDir=/tmp
Log=${LogDir}/Checksum_test.log
MailList=”abc@xyz.com”
Hostname=`hostname`
> ${Log}
mysql_statuschk()
{
process=`ps -ef | egrep -iw ‘mysqld_safe’ | egrep -v egrep | wc -l`
myping=`mysqladmin -u$USER -p$PWD “ping”|egrep -iw ‘alive’|wc -l`
if [ $process -eq 0 ] || [ $myping -eq 0 ] ; then
echo “MySQL Process is Unavailable on ${Hostname}!” > ${Log}
echo “Verify if mysqld is running!” >> ${Log}
echo “Hostname:” $Hostname >> ${Log}
echo “Uptime:” `uptime` >> ${Log}
echo >> ${Log}
ps -ef|egrep -iw “mysql” >> ${Log}
##### Verify MYSQLADMIN Status #####
echo “MySQL Admin status:” >> ${Log}
echo “——————-” >> ${Log}
mysqladmin -u$USER -p$PWD “ping” >> ${Log}
mysqladmin -u$USER -p$PWD “status” >> ${Log}
echo “If mysqladmin status is not alive! then mysql seems to be down.” >> ${Log}
mailx -s “SEV1/${Hostname}/MySQL Process is Unavailable.” ${MailList} < ${Log}
return 1
else
## if mysql is up and running.
echo “MySQL is up and running.”
return 0
fi
}
maatkit_chksum()
{
###### MAATKIT RUNNING STATUS CHECK ######
Hostname=`hostname`
echo “Hostname:” $Hostname >> ${Log}
echo “Starting checksum for partitions at `date ‘+%m%d%Y %H:%M %Z’` ” >> ${Log}
MK_STAT=`ps -ef | grep “mk-table-checksum” | grep -v “grep” | wc -l`
seconds=`mysql -h$TRG -u$USER -p$PWD -e “show slave status\G”|egrep Seconds|awk {‘print $2′}`
if [ ${MK_STAT} -eq 0 ] || [ $seconds -eq 0 ]; then
####### MAATKIT CHECKSUM RUN #########
##make sure we truncate the table test.checksum before looping in for each partition.
mysql -u$USER -p$PWD -D test -e “truncate table test.checksum”
mysql -u$USER -p$PWD -D test -e “truncate table test.checksum_results”
## Now get the partition information to loop into.
PLIST=`mysql -u$USER -p$PWD –skip-column-names -e “select partition_name from information_schema.partitions where table_schema=’<dbname>’ and table_name=’<tblname> ‘ “|tr -d ‘p’`
for PART in $PLIST
do
### test for single partition without chunk
echo “Starting for partition — $PART”
echo
mk-table-checksum –replicate=test.checksum –databases=<dbname> –tables=<tblname> h=$SRC –where=”<colname> > date_format($PART,’%Y-%m-%d 00:00:00′) and <colname> < date_format($PART,’%Y-%m-%d 23:59:59′)”
##to insert partition cheksum result into new tables.
mysql -u$USER -p$PWD -D test -e “set @par=’p$PART’; insert into test.checksum_results (db, tbl, chunk, boundaries, this_cnt, this_crc,master_crc,master_cnt,ts) select db, tbl, @par, boundaries, this_cnt, this_crc,master_crc,master_cnt,ts from test.checksum where tbl=’<tblname>’”
done
echo “Completed checksum for table paritions at `date ‘+%m%d%Y %H:%M %Z’` ” >> ${Log}
######### done with individual partition checksum.Now proceed with reports..
PRC=`ps -ef|grep “mk-table-checksum”|egrep -v “grep”|wc -l`
seconds2=`mysql -h$TRG -u$USER -p$PWD -e “show slave status\G”|egrep Seconds|awk {‘print $2′}`
### To ensure that checksum is replicating to slave after finishing in master ###
sleep 5
### checking for mk-table-checksum running status ###
while [ $PRC -gt 0 ] || [ ${seconds2} -gt 0 ] ;do
echo “The checksum script is still running!”
echo “(OR)”
echo “The slave is still lagging behind the master/replicating the checksum to slave”
echo “Lets wait until the process gets completed.”
sleep ${seconds2} ## sleep 900
seconds2=`mysql -h$TRG -u$USER -p$PWD -e “show slave status\G”|egrep Seconds|awk {‘print $2′}`
PRC=`ps -ef|grep “mk-table-checksum”|egrep -v “grep”|wc -l`
echo `ps -ef|grep “mk-table-checksum”|egrep -v “grep”`
done
##verify checksum results on slave
DIFFER=`mysql -t -h$TRG -u$USER -p$PWD -e “SELECT db, tbl, chunk, this_cnt-master_cnt AS cnt_diff,this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc) AS crc_diff FROM test.checksum_results WHERE master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)”|wc -l`
if [ $DIFFER -gt 0 ];then
echo “data discrepancy found b/w master and slave.” >> ${Log}
mysql -t -h$TRG -u$USER -p$PWD -e “SELECT db, tbl, chunk, this_cnt-master_cnt AS cnt_diff,this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc) AS crc_diff FROM test.checksum_results WHERE master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)” >> ${Log}
echo “ ” >> ${Log}
echo “Checksum report” >> ${Log}
mysql -t -h$TRG -u$USER -p$PWD -e “select * from test.checksum_results” >> ${Log}
mailx -s “${Hostname}-Data discrepancy report b/w Master $SRC and slave $TRG.” ${MailList} < ${Log}
### NEW condition to report errors -Kris ##
else if [ $DIFFER -eq 0 ];then
echo “Data is consistent and in sync b/w master and slave.” >> ${Log}
mysql -t -h$TRG -u$USER -p$PWD -e “select * from test.checksum_results” >> ${Log}
mailx -s “${Hostname}-Data consistency report b/w Master $SRC and slave $TRG.” ${MailList} < ${Log}
else
echo “Some issues with the checksum run” >> ${Log}
echo “Please check the table test.checksum_results for details” >> ${Log}
ps -ef |grep “checksum” >> ${Log}
echo “Please invistigate the issues” >> ${Log}
mailx -s “${Hostname} – Error!! found with checksum run.Plz Invistigate” ${MailList} < ${Log}
fi ##closing the else condition
fi ## closing for checksum report.
else
echo “The mk-table-checsum is already running” >> ${Log}
echo “(OR)” >> ${Log}
echo “The slave is $TRG lagging behind the master $SRC ” >> ${Log}
mailx -s “${Hostname}-Table checksum is already running.” ${MailList} < ${Log}
exit 2
fi
}
### MAIN PROGRAM STARTS HERE ###
# If no parameters passed then display script usage message
if [ "$1" = '' ] || [ "$2" = '' ]; then
echo “Usage: $0 <MasterHost> <SlaveHost>”
exit 1
fi
mysql_statuschk
#if [ $? -nt 1 ]
if [ $? -eq 0 ]
then
maatkit_chksum
fi