Merge "Fix MariaDB Single Database Restore"
This commit is contained in:
commit
b21fdfabad
@ -14,18 +14,35 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
log_error() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${MARIADB_POD_NAMESPACE}/mariadb/archive
|
||||
RESTORE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${MARIADB_POD_NAMESPACE}/mariadb/restore
|
||||
ARGS=("$@")
|
||||
LIST_OPTIONS=(list_archives list_databases)
|
||||
RESTORE_USER='restoreuser'
|
||||
RESTORE_PW=$(pwgen 16 1)
|
||||
RESTORE_LOG='/tmp/restore_error.log'
|
||||
rm -f $RESTORE_LOG
|
||||
|
||||
#Create Restore Directory
|
||||
mkdir -p $RESTORE_DIR
|
||||
|
||||
# This is for commands which require admin access
|
||||
MYSQL="mysql \
|
||||
--defaults-file=/etc/mysql/admin_user.cnf \
|
||||
--host=$MARIADB_SERVER_SERVICE_HOST \
|
||||
--connect-timeout 10"
|
||||
--defaults-file=/etc/mysql/admin_user.cnf \
|
||||
--host=$MARIADB_SERVER_SERVICE_HOST \
|
||||
--connect-timeout 10"
|
||||
|
||||
# This is for commands which we want the temporary "restore" user
|
||||
# to execute
|
||||
RESTORE_CMD="mysql \
|
||||
--user=${RESTORE_USER} \
|
||||
--password=${RESTORE_PW} \
|
||||
--host=$MARIADB_SERVER_SERVICE_HOST \
|
||||
--connect-timeout 10"
|
||||
|
||||
#Delete file
|
||||
delete_files() {
|
||||
@ -50,10 +67,8 @@ list_archives() {
|
||||
do
|
||||
echo $archive | cut -d '/' -f 8
|
||||
done
|
||||
exit 0
|
||||
else
|
||||
echo "Archive directory is not available."
|
||||
exit 1
|
||||
log_error "Archive directory is not available."
|
||||
fi
|
||||
}
|
||||
|
||||
@ -91,7 +106,45 @@ list_databases() {
|
||||
echo $db
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Create temporary user for restoring specific databases.
|
||||
create_restore_user() {
|
||||
restore_db=$1
|
||||
|
||||
# Ensure any old restore user is removed first, if it exists.
|
||||
# If it doesn't exist it may return error, so do not exit the
|
||||
# script if that's the case.
|
||||
delete_restore_user "dont_exit_on_error"
|
||||
|
||||
$MYSQL --execute="GRANT SELECT ON *.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
$MYSQL --execute="GRANT ALL ON ${restore_db}.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
cat $RESTORE_LOG
|
||||
log_error "Failed to grant restore user ALL permissions on database ${restore_db}"
|
||||
fi
|
||||
else
|
||||
cat $RESTORE_LOG
|
||||
log_error "Failed to grant restore user select permissions on all databases"
|
||||
fi
|
||||
}
|
||||
|
||||
# Delete temporary restore user
|
||||
delete_restore_user() {
|
||||
error_handling=$1
|
||||
|
||||
$MYSQL --execute="DROP USER ${RESTORE_USER}@'%';" 2>>$RESTORE_LOG
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
if [ "$error_handling" == "exit_on_error" ]
|
||||
then
|
||||
cat $RESTORE_LOG
|
||||
log_error "Failed to delete temporary restore user - needs attention to avoid a security hole"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#Restore a single database
|
||||
@ -99,8 +152,7 @@ restore_single_db() {
|
||||
single_db_name=$1
|
||||
if [ -z "$single_db_name" ]
|
||||
then
|
||||
usage
|
||||
exit 1
|
||||
log_error "Restore single DB called but with wrong parameter."
|
||||
fi
|
||||
if [ -f ${ARCHIVE_DIR}/${archive_file} ]
|
||||
then
|
||||
@ -109,30 +161,42 @@ restore_single_db() {
|
||||
tar zxvf ${ARCHIVE_DIR}/${archive_file} -C ${RESTORE_DIR} 1>/dev/null
|
||||
if [ -f ${RESTORE_DIR}/mariadb.all.sql ]
|
||||
then
|
||||
$MYSQL --one-database $single_db_name < ${RESTORE_DIR}/mariadb.all.sql
|
||||
# Restoring a single database requires us to create a temporary user
|
||||
# which has capability to only restore that ONE database. One gotcha
|
||||
# is that the mysql command to restore the database is going to throw
|
||||
# errors because of all the other databases that it cannot access. So
|
||||
# because of this reason, the --force option is used to prevent the
|
||||
# command from stopping on an error.
|
||||
create_restore_user $single_db_name
|
||||
$RESTORE_CMD --force < ${RESTORE_DIR}/mariadb.all.sql 2>>$RESTORE_LOG
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Database $single_db_name Restore successful."
|
||||
else
|
||||
echo "Database $single_db_name Restore failed."
|
||||
cat $RESTORE_LOG
|
||||
delete_restore_user "exit_on_error"
|
||||
log_error "Database $single_db_name Restore failed."
|
||||
fi
|
||||
delete_restore_user "exit_on_error"
|
||||
|
||||
if [ -f ${RESTORE_DIR}/${single_db_name}_grant.sql ]
|
||||
then
|
||||
$MYSQL < ${RESTORE_DIR}/${single_db_name}_grant.sql
|
||||
$MYSQL < ${RESTORE_DIR}/${single_db_name}_grant.sql 2>>$RESTORE_LOG
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Database $single_db_name Permission Restore successful."
|
||||
else
|
||||
echo "Database $single_db_name Permission Restore failed."
|
||||
cat $RESTORE_LOG
|
||||
log_error "Database $single_db_name Permission Restore failed."
|
||||
fi
|
||||
else
|
||||
echo "There is no permission file available for $single_db_name"
|
||||
log_error "There is no permission file available for $single_db_name"
|
||||
fi
|
||||
else
|
||||
echo "There is no database file available to restore from"
|
||||
log_error "There is no database file available to restore from"
|
||||
fi
|
||||
else
|
||||
echo "Archive does not exist"
|
||||
log_error "Archive does not exist"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -145,12 +209,13 @@ restore_all_dbs() {
|
||||
tar zxvf ${ARCHIVE_DIR}/${archive_file} -C ${RESTORE_DIR} 1>/dev/null
|
||||
if [ -f ${RESTORE_DIR}/mariadb.all.sql ]
|
||||
then
|
||||
$MYSQL < ${RESTORE_DIR}/mariadb.all.sql
|
||||
$MYSQL < ${RESTORE_DIR}/mariadb.all.sql 2>$RESTORE_LOG
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Databases $( echo $DBS | tr -d '\n') Restore successful."
|
||||
else
|
||||
echo "Databases $( echo $DBS | tr -d '\n') Restore failed."
|
||||
cat $RESTORE_LOG
|
||||
log_error "Databases $( echo $DBS | tr -d '\n') Restore failed."
|
||||
fi
|
||||
if [ -n "$DBS" ]
|
||||
then
|
||||
@ -158,34 +223,37 @@ restore_all_dbs() {
|
||||
do
|
||||
if [ -f ${RESTORE_DIR}/${db}_grant.sql ]
|
||||
then
|
||||
$MYSQL < ${RESTORE_DIR}/${db}_grant.sql
|
||||
$MYSQL < ${RESTORE_DIR}/${db}_grant.sql 2>>$RESTORE_LOG
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Database $db Permission Restore successful."
|
||||
else
|
||||
echo "Database $db Permission Restore failed."
|
||||
cat $RESTORE_LOG
|
||||
log_error "Database $db Permission Restore failed."
|
||||
fi
|
||||
else
|
||||
echo "There is no permission file available for $db"
|
||||
log_error "There is no permission file available for $db"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "There is no database file available to restore from"
|
||||
log_error "There is no database file available to restore from"
|
||||
fi
|
||||
else
|
||||
echo "Archive does not exist"
|
||||
log_error "Archive does not exist"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
ret_val=$1
|
||||
echo "Usage:"
|
||||
echo "$0 options"
|
||||
echo "Restore command options"
|
||||
echo "============================="
|
||||
echo "options: "
|
||||
echo "help"
|
||||
echo "list_archives"
|
||||
echo "list_databases archive_filename"
|
||||
echo "restore archive_filename [DB_NAME or ALL/all]"
|
||||
echo "list_databases <archive_filename>"
|
||||
echo "restore <archive_filename> [<db_name> | ALL]"
|
||||
exit $ret_val
|
||||
}
|
||||
|
||||
is_Option() {
|
||||
@ -205,57 +273,63 @@ is_Option() {
|
||||
#Main
|
||||
if [ ${#ARGS[@]} -gt 3 ]
|
||||
then
|
||||
usage
|
||||
exit
|
||||
usage 1
|
||||
elif [ ${#ARGS[@]} -eq 1 ]
|
||||
then
|
||||
if [ $(is_Option "$LIST_OPTIONS" ${ARGS[0]}) -eq 1 ]
|
||||
if [ "${ARGS[0]}" == "list_archives" ]
|
||||
then
|
||||
${ARGS[0]}
|
||||
exit
|
||||
list_archives
|
||||
elif [ "${ARGS[0]}" == "help" ]
|
||||
then
|
||||
usage 0
|
||||
else
|
||||
usage
|
||||
exit
|
||||
usage 1
|
||||
fi
|
||||
elif [ ${#ARGS[@]} -eq 2 ]
|
||||
then
|
||||
if [ "${ARGS[0]}" == "list_databases" ]
|
||||
then
|
||||
list_databases ${ARGS[1]}
|
||||
exit 0
|
||||
else
|
||||
usage
|
||||
exit
|
||||
usage 1
|
||||
fi
|
||||
elif [ ${#ARGS[@]} -eq 3 ]
|
||||
then
|
||||
if [ "${ARGS[0]}" != "restore" ]
|
||||
then
|
||||
usage
|
||||
exit 1
|
||||
usage 1
|
||||
else
|
||||
if [ -f ${ARCHIVE_DIR}/${ARGS[1]} ]
|
||||
then
|
||||
#Get all the databases in that archive
|
||||
get_databases ${ARGS[1]}
|
||||
|
||||
#check if the requested database is available in the archive
|
||||
if [ $(is_Option "$DBS" ${ARGS[2]}) -eq 1 ]
|
||||
then
|
||||
echo "Restoring Database ${ARGS[2]} And Grants"
|
||||
echo "Creating Database ${ARGS[2]} if it does not exist"
|
||||
$MYSQL -e "CREATE DATABASE IF NOT EXISTS \`${ARGS[2]}\`"
|
||||
echo "Creating database ${ARGS[2]} if it does not exist"
|
||||
$MYSQL -e "CREATE DATABASE IF NOT EXISTS \`${ARGS[2]}\`" 2>>$RESTORE_LOG
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
cat $RESTORE_LOG
|
||||
log_error "Database ${ARGS[2]} could not be created."
|
||||
fi
|
||||
echo "Restoring database ${ARGS[2]} and grants...this could take a few minutes."
|
||||
restore_single_db ${ARGS[2]}
|
||||
exit 0
|
||||
elif [ "$( echo ${ARGS[2]} | tr '[a-z]' '[A-Z]')" == "ALL" ]
|
||||
then
|
||||
echo "Restoring All The Database."
|
||||
echo "Creating Database if it does not exist"
|
||||
echo "Creating databases if they do not exist"
|
||||
for db in $DBS
|
||||
do
|
||||
$MYSQL -e "CREATE DATABASE IF NOT EXISTS \`$db\`"
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
cat $RESTORE_LOG
|
||||
log_error "Database ${db} could not be created."
|
||||
fi
|
||||
done
|
||||
echo "Restoring all databases and grants...this could take a few minutes."
|
||||
restore_all_dbs
|
||||
exit 0
|
||||
else
|
||||
echo "Database ${ARGS[2]} does not exist."
|
||||
fi
|
||||
@ -264,6 +338,7 @@ then
|
||||
fi
|
||||
fi
|
||||
else
|
||||
usage
|
||||
exit
|
||||
usage 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user