+# (By|Maintained by) Juan Riano
+# Script name: clean_definers
+# Usage: sudo $0 dbname.sql[.gz]
+# Usage: sudo $0 [-h|-help]
+# Takes a mysql db dump (even .gz) and updates all DEFINERs to be root
+###########################################################
+ echo "Usage: $0 [-h|-help]"
+ echo "Takes a mysql.sql or mysql.sql.gz database dump and updates all DEFINERs to be root"
+# Minimal parameters check
+if [[ "${1}" =~ ^(help|-help|h|-h)$ ]]; then
+###########################################################
+DBDIR=$( dirname "${DB}" )
+DBBASENAME=$( basename "${DB}" )
+DBNAME=$( echo "${DBBASENAME%.*}" ) # ecluding the .gz if existing
+DBTYPE=$( echo "${DBBASENAME##*.}" )
+if [ "${DBTYPE}" == "gz" ]; then
+ echo "Unzipping ${DB}..."
+ DB="${DBDIR}/${DBNAME}"
+ echo "Unzipped, new file: ${DB}"
+# Find definers other than root and admin, and replace them by root
+NEWDEFINER='DEFINER=`root`'
+DEFINERS=$( grep -oE "DEFINER=\`[a-zA-Z]+\`" "${DB}" | grep -viE "DEFINER=\`(root|admin)\`" | sort | uniq )
+if ! [ -z "${DEFINERS}" ]; then
+ DEFINERCOUNT=$( echo "${DEFINERS}" | wc -l )
+ # Put definers in a single line after trimming (sed breakes without trimming!)
+ DEFINERS=$( echo "${DEFINERS}" | awk 1 ORS=' ' | awk '{$1=$1}1' )
+if [[ "${DEFINERCOUNT}" = "0" ]]; then
+ echo "No definers to fix"
+echo "Cleaning definers, ${DEFINERCOUNT} found..."
+for d in "${DEFINERS}"; do
+ echo "Replacing ${d} -with- ${NEWDEFINER}"
+ sed -i.bak "s/${d}/${NEWDEFINER}/g" "$DB" # .bak is a hack to make it work in Mac
+# Remove temp file and finish