#!/usr/bin/env bash script_name="$(basename $(realpath $0))" script_dir="$(dirname $(realpath $0))" conf_dir="${script_dir}/conf" tmp_err_msg=$(mktemp) log_dir=/root/sync_from_old_server_logs mkdir -p ${log_dir} # - Sync MySQL databases # - # - Note: # - Set to "ALL" if all databases from old server should be synced # - Leave empty if no databases should be synced. # - # - Example: # - To sync database 'shop19' aot source host to database 'shop19_dev' # - at destination host: # - sync_mysql_databases=" # - ... # - shop19:shop19_dev # - ... # - " # - sync_mysql_databases="ALL" # - mysql_source_credential_args # - mysql_target_credential_args # - # - Example # - mysql_credential_args="-u root -S /run/mysqld/mysqld.sock" # - mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" # - mysql_credential_args="--login-path=local" # - mysql_credential_args="-u -p''" # - mysql_source_credential_args="-u root -pbuz111 -S /run/mysqld/mysqld-5.7.sock" mysql_target_credential_args="-u root -S /run/mysqld/mysqld.sock" mysqldump_exe="/usr/local/mysql/bin/mysqldump" mysql_source_exe="/usr/local/mysql/bin/mysql" mysql_target_exe="/usr/bin/mysql" mysql_source_version="$(${mysql_source_exe} -V | awk '{print$5}')" mysql_target_version="$(${mysql_target_exe} -V | awk '{print$5}')" # Remove leading / trailling point sign ',' # mysql_source_version="${mysql_source_version%\,}" mysql_target_version="${mysql_target_version%\,}" # - mysqldump parameters/options # - mysql_max_allowed_packet="1024M" # ------------- # --- Some functions # ------------- echononl(){ echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n "$*\\c" 1>&2 else echo -e -n "$*" 1>&2 fi rm /tmp/shprompt$$ } fatal(){ echo "" if [[ -z "$*" ]] ; then echo -e "\t\033[31m\033[1mScript will be interrupted\033[m\033[m" else echo -e "\t[ \033[31m\033[1mFatal Error\033[m ]: $*" echo "" echo -e "\t\033[31m\033[1mScript will be interrupted\033[m\033[m" fi echo "" exit 1 } error(){ echo "" echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*" echo "" } warn (){ echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" } info (){ echo "" echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" echo "" } echo_done() { echo -e "\033[80G[ \033[32mdone\033[m ]" } echo_ok() { echo -e "\033[80G[ \033[32mok\033[m ]" } echo_ok() { echo -e "\033[80G[ \033[32mok\033[m ]" } echo_warning() { echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" } echo_failed(){ echo -e "\033[80G[ \033[1;31mfailed\033[m ]" } echo_skipped() { echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" } service_exists() { local n=$1 if [[ $(systemctl list-units --all -t service --full --no-legend "$n.service" | cut -f1 -d' ') == $n.service ]]; then return 0 else return 1 fi } # ---------- # - Is this a systemd system? # - if [[ "X$(which systemd)" = "X" ]]; then systemd_exists=false else systemd_exists=true fi echo "" # ========== # - Begin Main Script # ========== # ---------- # - Headline # ---------- clear if $terminal ; then echo "" echo -e "\033[1m----------\033[m" echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" echo -e "\033[1m----------\033[m" fi echo "" echo -e " \033[32mParameter Summary:\033[m" echo "" echo -e " MySQL source version..................: ${mysql_source_version}" echo -e " MySQL target version..................: ${mysql_target_version}" echo "" echo -e " MySQL client binary source version....: ${mysql_source_exe}" echo -e " MySQL client binary target version....: ${mysql_target_exe}" echo "" echo -e " MySQL credentials source versions.....: ${mysql_source_credential_args}" echo -e " MySQL credentials target versions.....: ${mysql_target_credential_args}" echo "" _error=false if [[ ! -x "${mysql_source_exe}" ]] ; then error "No mysql binary \033[1m${mysql_source_exe}\033[m found (VAR mysql_source_exe)." _error=true fi if [[ ! -x "${mysql_target_exe}" ]] ; then error "No mysql binary \033[1m${mysql_target_exe}\033[m found (VAR mysql_target_exe)." _error=true fi if $_error ; then fatal Wrong or Missing Parameter.. fi echo "" echononl " \033[33mContinue with this parameters? [\033[1myes/no\033[m]: " read OK while [[ "${OK,,}" != "yes" ]] && [[ "${OK,,}" != "no" ]] ; do echononl " \033[33mWrong entry!\033[m [\033[1myes/no\033[m]: " read OK done [[ "${OK,,}" = "yes" ]] || fatal "Canceled by user input." if $terminal ; then echo "" echo "" echo -e " \033[32m-----\033[m" echo -e " \033[1mSyncing MySQL Databases from Version '${mysql_source_version}' to Version '${mysql_target_version} ..\033[m" echo -e " \033[32m-----\033[m" fi echo "" _got_mysql_databases=false sync_mysql_databases="${sync_mysql_databases##*( )}" sync_mysql_databases="${sync_mysql_databases%%*( )}" if [[ -z "$sync_mysql_databases" ]]; then warn "No MySQL databases for syncing configured." elif [[ "$sync_mysql_databases" = "ALL" ]]; then echononl " Get MySQL databases from source Installation.." _mysql_databases_remote="$(${mysql_source_exe} ${mysql_source_credential_args} -N -s -e "show databases" 2> /dev/null)" if [[ $? -eq 0 ]];then echo_ok _got_mysql_databases=true else echo_failed fi else _mysql_databases_remote="$sync_mysql_databases" _got_mysql_databases=true fi if $_got_mysql_databases ; then log_file=${log_dir}/sync_mysql.log > $log_file mysqldump_flags="--protocol=SOCKET --max-allowed-packet=${mysql_max_allowed_packet} --skip-opt --add-drop-table --add-locks --create-options --quick --set-charset --disable-keys --lock-tables --routines" # - GET current (global) Autocommit value # - echononl " GET current (global) Autocommit value" CUR_AUTOCOMMIT="$(${mysql_target_exe} ${mysql_target_credential_args} -N -s -e "SHOW GLOBAL VARIABLES LIKE 'autocommit'" | awk '{print$2}')" >> $log_file 2> $tmp_err_msg if [[ $? -eq 0 ]];then echo_ok else echo_failed error "$(cat $tmp_err_msg)" fi # - Set Autocommit OFF # - echononl " Set Autocommit to OFF" ${mysql_target_exe} ${mysql_target_credential_args} -N -s -e "SET GLOBAL AUTOCOMMIT='OFF'" \ >> $log_file 2> $tmp_err_msg if [[ $? -eq 0 ]];then echo_ok else echo_failed error "$(cat $tmp_err_msg)" fi echo "" for _val in $_mysql_databases_remote ; do IFS=':' read -a _val_arr <<< "${_val}" _src_db="${_val_arr[0]}" if [[ -n "${_val_arr[1]}" ]] ; then _dst_db="${_val_arr[1]}" echononl " Sync Database '$_src_db' --> '$_dst_db'.. " else echononl " Sync Database '$_src_db'.. " _dst_db="$_src_db" fi if [[ "${_src_db}" = "information_schema" ]]; then echo_skipped continue fi if [[ "${_src_db}" = "performance_schema" ]]; then echo_skipped continue fi if [[ "${_src_db}" = "mysql" ]]; then echo_skipped continue fi if [[ "${_src_db}" = "sys" ]]; then echo_skipped continue fi if [[ "${_src_db}" = "test" ]] || [[ "${_src_db}" = "mysqltest" ]] ; then echo_skipped continue fi ${mysqldump_exe} ${mysql_source_credential_args} $_src_db 2> /dev/null \ | ${mysql_target_exe} ${mysql_target_credential_args} ${_dst_db} >> $log_file 2> $tmp_err_msg if [[ $? -eq 0 ]];then echo_ok else echo_failed error "$(cat $tmp_err_msg)" echo -e " \033[33mcommand was:\033[m \033[1m${mysqldump_exe} ${mysql_source_credential_args} $_src_db 2> /dev/null \\ | ${mysql_target_exe} ${mysql_target_credential_args} ${_dst_db}\033[m " echononl "\n continue anyway [yes/no]: " read OK OK=${OK,,} while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi done # - Reset (global) Autocommit value # - echo "" echononl " Reset (global) Autocommit value to '$CUR_AUTOCOMMIT'" ${mysql_target_exe} ${mysql_target_credential_args} -N -s -e "SET GLOBAL AUTOCOMMIT='${CUR_AUTOCOMMIT}'" \ >> $log_file 2> $tmp_err_msg if [[ $? -eq 0 ]];then echo_ok else echo_failed error "$(cat $tmp_err_msg)" fi fi rm $tmp_err_msg echo "" exit 0