#!/bin/bash
##################################################################
# This script is a wrapper to mysql_count_querytype.sh so that
# slowlogs analysis runs on many CPU cores and not only one.
##################################################################

trap ctrl_c INT

ctrl_c () {
	errcho 'Caught INT signal.'
	cleanup
	errcho 'Exiting.'
	exit 130
}

errcho () {
	>&2 echo "$@"
}

cleanup () {
	rm -fr "${my_tmplog}" "${my_tmpres}"
}

usage () {
        errcho "Usage: ${0##*/} [-p] logfile"
        errcho '-p    if logfile has been preprocessed by mysql_convert_slowlog_to_oneline.sh'
        errcho 'logfile can be in gzip or plaintext format.'
        exit $1
}

# Processing commandline parameters
POSITIONAL=()

while [[ $# -gt 0 ]]
do
key="$1"

case $key in
        -p)
                OPTIONS='-p'
                shift
                ;;
        *)
                POSITIONAL+=("$1") # save it in an array for later
                shift
                ;;
esac
done

set -- "${POSITIONAL[@]}" # restore positional parameters

# Don't forget some basic error checking
[[ -f "$1" ]] || { errcho "File \"$1\" does not exist. Exiting." ; usage 1; }
[[ -x "$(pwd -P)/mysql_count_querytype.sh" ]] || { errcho "Needed script \"$(pwd -P)/mysql_count_querytype.sh\" does not exist or is not executable. Exiting." ; usage 1; }

my_tmplog="$(mktemp --directory --tmpdir="${1%/*}"/)" || { errcho 'Error when trying to create a temporary folder for split logs. Exiting.' ; exit 1 ; }
my_tmpres="$(mktemp --directory --tmpdir="${1%/*}"/)" || { errcho 'Error when trying to create a temporary folder for intermediary results. Exiting.' ; exit 1 ; }
my_log="$1"
declare -A my_array

merge_results () {
	while read LINE
	do
		if [ ${my_array[${LINE%* *}]+_} ]
		then
			my_array[${LINE%* *}]=$(( ${my_array[${LINE%* *}]} + ${LINE##* } ))
		else
			my_array[${LINE%* *}]=${LINE##* }
		fi
	done
}

# count how many CPU cores we have
my_cpucnt=$(grep -c '^processor' /proc/cpuinfo)

# split the file in many smaller units
[[ "$(file -bi "${my_log}")" =~ ^application/gzip ]] && { errcho -n "Uncompressing \"${my_log}\"... " ; gunzip -k "${my_log}"; my_log="${my_log%*.*}" && errcho 'done.'; }
split -n${my_cpucnt} "${my_log}" "${my_tmplog}/"

# Analyze each log chunk and put result into a common folder
errcho -n "Spawning ${my_cpucnt} processes for analyzing logs... "

for file in ${my_tmplog}/*
do
	("$(pwd -P)/mysql_count_querytype.sh" ${OPTIONS} "${file}" > "${my_tmpres}/${file##*/}") &
done

errcho 'done. Ready for some fan noise ? Now you can go make and drink some coffee, this may take some time.'
wait

# Beware ! Be sure to trim whitespaces in the input ! Every line must be of the form "key value" like this:
# DB1234567DELETE 58
# for merge_results to work. That's what the sed command does here, as result lines look like this:
# DB1234567    DELETE   58
merge_results < <(cat "${my_tmpres}/"* | sed -re 's: +:: ; s: +: :')

# Output results
for QUERYTYPE in ${!my_array[@]}
do
	echo "${QUERYTYPE} ${my_array[$QUERYTYPE]}" | sed -re 's:(DB[0-9]+):\1 :'
done | sort -nk3 | column -t

cleanup
exit $?

