Advertisement
Guest User

Untitled

a guest
Aug 5th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.28 KB | None | 0 0
  1. #!/bin/bash -eu
  2. #
  3. # This script can sync MySQL schema without `DROP TABLE`.
  4. # And If table isn't exists, import tables from source.
  5. #
  6. # Finally there is a confirmation screen.
  7. #
  8. # Need these packages: mysql, mysqldump, mysqldiff
  9. # GitHub: @rluisr
  10.  
  11. # Color init
  12. # ============
  13. NORMAL=$(tput sgr0)
  14. GREEN=$(tput setaf 2; tput bold)
  15. YELLOW=$(tput setaf 3)
  16. RED=$(tput setaf 1)
  17.  
  18. function red() {
  19. echo -e "$RED$*$NORMAL"
  20. }
  21.  
  22. function green() {
  23. echo -e "$GREEN$*$NORMAL"
  24. }
  25.  
  26. function yellow() {
  27. echo -e "$YELLOW$*$NORMAL"
  28. }
  29.  
  30.  
  31. # Script init
  32. # ==============
  33. CMDNAME=`basename $0`
  34.  
  35. FLAG_SRC_SSL=false;
  36. FLAG_DST_SSL=false;
  37.  
  38. function Usage() {
  39. echo "Usage: ${CMDNAME} [--src-host <host>] [--src-user <user>] [--src-pass <pass>] [--src-db <db name>] [--dst-host <host>] [--dst-user <user>] [--dst-pass <pass>] [--dst-db <db name>]"
  40. echo "Option: [--src-ssl-ca <path>] [--dst-ssl-ca <path>]" # Note ssl option not supported yet
  41. exit 1
  42. }
  43.  
  44. if [ $# -eq 16 ] || [ $# -eq 18 ] || [ $# -eq 20 ]; then
  45. :
  46. else
  47. echo "Not enough argument"
  48. Usage
  49. fi
  50.  
  51. PARAM=()
  52. for OPT in "$@"; do
  53. case "${OPT}" in
  54. "--src-host" )
  55. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  56. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  57. exit 1
  58. fi
  59. readonly SRC_HOST="$2"
  60. shift 2
  61. ;;
  62. "--src-user" )
  63. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  64. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  65. exit 1
  66. fi
  67. readonly SRC_USER="$2"
  68. shift 2
  69. ;;
  70. "--src-pass" )
  71. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  72. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  73. exit 1
  74. fi
  75. readonly SRC_PASS="$2"
  76. shift 2
  77. ;;
  78. "--src-db" )
  79. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  80. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  81. exit 1
  82. fi
  83. readonly SRC_DB="$2"
  84. shift 2
  85. ;;
  86. "--src-ssl-ca" )
  87. readonly SRC_SSL_CA="$2"
  88. FLAG_SRC_SSL=true
  89. shift 2
  90. ;;
  91. "--dst-host" )
  92. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  93. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  94. exit 1
  95. fi
  96. readonly DST_HOST="$2"
  97. shift 2
  98. ;;
  99. "--dst-user" )
  100. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  101. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  102. exit 1
  103. fi
  104. readonly DST_USER="$2"
  105. shift 2
  106. ;;
  107. "--dst-pass" )
  108. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  109. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  110. exit 1
  111. fi
  112. readonly DST_PASS="$2"
  113. shift 2
  114. ;;
  115. "--dst-db" )
  116. if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
  117. echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
  118. exit 1
  119. fi
  120. readonly DST_DB="$2"
  121. shift 2
  122. ;;
  123. "--dst-ssl-ca" )
  124. readonly DST_SSL_CA="$2"
  125. FLAG_DST_SSL=true
  126. shift 2
  127. ;;
  128. -* )
  129. echo "${PROGNAME}: illegal option -- '$( echo $1 | sed 's/^-*//' )'" 1>&2
  130. exit 1
  131. ;;
  132. * )
  133. set +u
  134. if [[ -n "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
  135. PARAM+=( "$1" ); shift 2>&1
  136. fi
  137. set -u
  138. ;;
  139. esac
  140. done
  141.  
  142. green "=== Backup"
  143. # DBのバックアップを取得する
  144. # ===========================
  145. mysqldump -h ${SRC_HOST} -u ${SRC_USER} -p${SRC_PASS} ${SRC_DB} > /tmp/backup_${SRC_DB}.sql
  146. mysqldump -h ${DST_HOST} -u ${DST_USER} -p${DST_PASS} ${DST_DB} > /tmp/backup_${DST_DB}.sql
  147.  
  148. green "=== Import table if not exists"
  149. # 存在しないテーブルをインポートする
  150. # ===================================
  151. mysqldump --skip-add-drop-table -h ${SRC_HOST} -u ${SRC_USER} -p${SRC_PASS} -d ${SRC_DB} > /tmp/${SRC_DB}.sql
  152. mysql -h ${DST_HOST} -u ${DST_USER} -p${DST_PASS} -f ${DST_DB} < /tmp/${SRC_DB}.sql > /dev/null 2>&1
  153.  
  154. green "=== Getting table names"
  155. # ソースのテーブル名を配列に入れて,スキーマーなどを宛先と比較する
  156. # =================================================================
  157. # // テーブルの数は一緒なので片方からのみテーブル名は配列に入れる
  158. tablesName=`mysql -h ${SRC_HOST} -u ${SRC_USER} -p${SRC_PASS} ${SRC_DB} -e "SHOW TABLES \G" | grep "Tables_in" | awk '{print $2}'`
  159.  
  160. arrayTablesName=(`echo ${tablesName}`)
  161.  
  162. green "=== Get diff of source and destination"
  163. for i in "${arrayTablesName[@]}"; do
  164. set +e
  165. mdiff=`mysqldiff --force --skip-table-option --changes-for=server2 --difftype=sql --server1=${SRC_USER}:${SRC_PASS}@${SRC_HOST} --server2=${DST_USER}:${DST_PASS}@${DST_HOST} ${SRC_DB}.${i}:${DST_DB}.${i}`
  166. set -e
  167.  
  168. if echo "${mdiff}" | grep -sq "PASS"; then
  169. continue
  170. fi
  171.  
  172. alterCommand=`echo ${mdiff} | cut -d ' ' -f 37- | sed -e "s/ # Compare.*//g"`
  173.  
  174. echo "${alterCommand}"
  175. while true; do
  176. read -p 'Execute this alter command? [Y/n]' Answer
  177. case ${Answer} in
  178. '' | [Yy]* )
  179. executeAlter=`mysql -h ${DST_HOST} -u ${DST_USER} -p${DST_PASS} ${DST_DB} -e "${alterCommand}"`
  180. break;
  181. ;;
  182. [Nn]* )
  183. echo "Ignored"
  184. break;
  185. ;;
  186. * )
  187. echo "Please type [Y/n]"
  188. esac
  189. done;
  190. done
  191.  
  192. green "=== Finished"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement