Last active
September 26, 2016 10:25
-
-
Save Athorcis/c403a0a69732ec2bc2e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| declare -A options=( | |
| [save]=0 | |
| [sshpass]=1 | |
| [progress]=1 | |
| [remote_ssh_user]=root | |
| [remote_ssh_host]= | |
| [remote_ssh_port]=22 | |
| [remote_sql_username]=root | |
| [remote_sql_password]= | |
| [local_sql_username]=root | |
| [local_sql_password]= | |
| [max_allowed_packet]=33554432 | |
| ) | |
| if [ -z "$1" ] | |
| then | |
| databases=(<databases_list>) | |
| else | |
| databases=($*) | |
| fi | |
| if [ ${options[sshpass]} -eq 1 ] && [ -z "$(which sshpass)" ] | |
| then | |
| echo sshpass needs to be installed in order to ask ssh password just once. | |
| exit 1 | |
| fi | |
| if [ ${options[progress]} -eq 1 ] && [ -z "$(which pv)" ] | |
| then | |
| echo pv needs to be installed in order to show the progression of imports. | |
| fi | |
| base_dir=$(dirname "${BASH_SOURCE[0]}") | |
| options[cache_dir]=$base_dir/sync-database.d | |
| options[save_dir]=${options[cache_dir]}/save | |
| function execute_local_query { | |
| local query=$1 | |
| eval "declare -A options="${2#*=} | |
| mysql --host=127.0.0.1 --user=${options[local_sql_username]} --password="${options[local_sql_password]}" --silent --skip-column-names --execute="$query" | |
| return $? | |
| } | |
| function get_max_allowed_packet { | |
| eval "declare -A options="${1#*=} | |
| execute_local_query "SHOW VARIABLES WHERE VARIABLE_NAME = 'max_allowed_packet'" "$(declare -p options)" | awk '{ print $2 }' | |
| return $? | |
| } | |
| function set_max_allowed_packet { | |
| local max_allowed_packet=$1 | |
| eval "declare -A options="${2#*=} | |
| execute_local_query "SET GLOBAL max_allowed_packet = $max_allowed_packet" "$(declare -p options)" | |
| return $? | |
| } | |
| function increase_max_allowed_packet { | |
| eval "declare -A options="${1#*=} | |
| if ! original_max_allowed_packet=$(get_max_allowed_packet "$(declare -p options)") | |
| then | |
| echo UNABLE TO RETRIEVE max_allowed_packet | |
| return 1 | |
| fi | |
| if [ ${options[max_allowed_packet]} -gt $original_max_allowed_packet ] | |
| then | |
| echo INCREASE max_allowed_packet TO ${options[max_allowed_packet]} | |
| if ! set_max_allowed_packet ${options[max_allowed_packet]} "$(declare -p options)" | |
| then | |
| echo UNABLE TO INCREASE max_allowed_packet | |
| return 1 | |
| fi | |
| fi | |
| return 0 | |
| } | |
| function restore_max_allowed_packet { | |
| eval "declare -A options="${1#*=} | |
| if [ ${options[max_allowed_packet]} -gt $original_max_allowed_packet ] | |
| then | |
| echo RESTORE max_allowed_packet TO $original_max_allowed_packet | |
| if ! set_max_allowed_packet $original_max_allowed_packet "$(declare -p options)" | |
| then | |
| echo UNABLE TO RESTORE max_allowed_packet | |
| return 1 | |
| fi | |
| fi | |
| return 0 | |
| } | |
| function dump_local_database { | |
| local dump=$1 | |
| local database=$2 | |
| eval "declare -A options="${3#*=} | |
| mkdir --parents "$(dirname $dump)" | |
| mysqldump --host=127.0.0.1 --user=${options[local_sql_username]} --password="${options[local_sql_password]}" --databases --add-drop-database $database | gzip --to-stdout > "$dump" | |
| return $? | |
| } | |
| function ask_ssh_remote_password { | |
| eval "declare -A options="${1#*=} | |
| while true | |
| do | |
| echo -n "${options[remote_ssh_user]}@${options[remote_ssh_host]}'s password: " | |
| read -r -s remote_ssh_password | |
| echo | |
| execute_remote_command 'exit' "$(declare -p options)" | |
| local error=$? | |
| if [ $error -eq 6 ] | |
| then | |
| echo Host public key is unknown | |
| fi | |
| if [ $error -ne 5 ] | |
| then | |
| break | |
| fi | |
| done | |
| } | |
| function execute_remote_command { | |
| local command=$1 | |
| eval "declare -A options="${2#*=} | |
| if [ ${options[sshpass]} -eq 1 ] | |
| then | |
| if [ -z "$remote_ssh_password" ] | |
| then | |
| ask_ssh_remote_password "$(declare -p options)" 1>&2 | |
| fi | |
| sshpass -p "$remote_ssh_password" ssh -p ${options[remote_ssh_port]} ${options[remote_ssh_user]}@${options[remote_ssh_host]} "$command" | |
| else | |
| ssh -p ${options[remote_ssh_port]} ${options[remote_ssh_user]}@${options[remote_ssh_host]} "$command" | |
| fi | |
| return $? | |
| } | |
| function dump_remote_database { | |
| local dump=$1 | |
| local database=$2 | |
| eval "declare -A options="${3#*=} | |
| mkdir --parents "$(dirname $dump)" | |
| execute_remote_command "mysqldump --host=127.0.0.1 --user=${options[remote_sql_username]} --password=${options[remote_sql_password]} --databases --add-drop-database $database | gzip --to-stdout" "$(declare -p options)" > "$dump" | |
| return $? | |
| } | |
| function import_database { | |
| local dump=$1 | |
| local database=$2 | |
| eval "declare -A options="${3#*=} | |
| if [ ${options[progress]} -eq 1 ] | |
| then | |
| pv --cursor --name source "$dump" | gunzip --to-stdout | pv --cursor --name gunzip | mysql --host=127.0.0.1 --user=${options[local_sql_username]} --password=${options[local_sql_password]} $database | |
| else | |
| gunzip --to-stdout "$dump" | mysql --host=127.0.0.1 --user=${options[local_sql_username]} --password=${options[local_sql_password]} $database | |
| fi | |
| return $? | |
| } | |
| function save_database { | |
| local database=$1 | |
| eval "declare -A options="${2#*=} | |
| local dump=${options[save_dir]}/$database.sql.gz | |
| echo SAVE DATABASE $database | |
| dump_local_database "$dump" $database "$(declare -p options)" | |
| return $? | |
| } | |
| function save_databases { | |
| local databases=($1) | |
| eval "declare -A options="${2#*=} | |
| for database in ${databases[*]} | |
| do | |
| if ! save_database $database "$(declare -p options)" | |
| then | |
| echo UNABLE TO SAVE $database | |
| return 1 | |
| fi | |
| done | |
| return 0 | |
| } | |
| function restore_database { | |
| local database=$1 | |
| eval "declare -A options="${2#*=} | |
| local dump=${options[save_dir]}/$database.sql.gz | |
| echo RESTORE DATABASE $database | |
| import_database "$dump" $database "$(declare -p options)" | |
| return $? | |
| } | |
| function sync_database { | |
| local database=$1 | |
| eval "declare -A options="${2#*=} | |
| local dump=${options[cache_dir]}/$database.sql.gz | |
| if [ ! -f "$dump" ] | |
| then | |
| echo DUMP REMOTE $database | |
| if ! dump_remote_database "$dump" $database "$(declare -p options)" | |
| then | |
| echo DUMP REMOTE FAILED | |
| return 1 | |
| fi | |
| fi | |
| echo IMPORT DUMP $database | |
| if ! import_database "$dump" $database "$(declare -p options)" | |
| then | |
| return 1 | |
| fi | |
| return 0 | |
| } | |
| function sync_databases { | |
| local databases=($1) | |
| eval "declare -A options="${2#*=} | |
| if [ ${#databases[*]} -eq 0 ] | |
| then | |
| return 0 | |
| fi | |
| local database=${databases[0]} | |
| sync_database $database "$(declare -p options)" | |
| local error=$? | |
| if [ $error -eq 0 ] | |
| then | |
| unset 'databases[0]' | |
| sync_databases "${databases[*]}" "$(declare -p options)" | |
| error=$? | |
| fi | |
| if [ $error -ne 0 ] | |
| then | |
| echo UNABLE TO SYNC $database | |
| if [ ${options[save]} -ne 0 ] | |
| then | |
| if ! restore_database $database "$(declare -p options)" | |
| then | |
| echo UNABLE TO RESTORE $database | |
| fi | |
| fi | |
| return 1 | |
| fi | |
| return 0 | |
| } | |
| if ! increase_max_allowed_packet "$(declare -p options)" | |
| then | |
| exit 1 | |
| fi | |
| if [ ${options[save]} -ne 0 ] | |
| then | |
| save_databases "${databases[*]}" "$(declare -p options)" | |
| save_failed=$? | |
| else | |
| save_failed=0 | |
| fi | |
| if [ $save_failed -eq 0 ] | |
| then | |
| sync_databases "${databases[*]}" "$(declare -p options)" | |
| sync_failed=$? | |
| else | |
| sync_failed=$save_failed | |
| fi | |
| restore_max_allowed_packet "$(declare -p options)" | |
| exit $sync_failed |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bien joué :)