[关闭]
@saltyang 2018-06-19T11:40:51.000000Z 字数 6601 阅读 1005

Mysql HA:Mysql + Keepalived

Mysql, 主主, keepalived


Mysql Sync Replication

  • 写事务会向master的块设备与一些用来复制的日志(bin_log)写入记录,完成后立即向应用程序发出事物完成的确认信息,master不关心该事物是否已经被slaves复制。对于Slaves来说,他们会在另外的时间里,从master上拿到自己所需要的数据进行复制
  • master保存事务与"Sync replication"大致相同,不同的地方在于它仅需要等待slaves中的任一台slave回复确认信息即可。这台回复的slave,它仅仅需要将该事务日志记录从master取回,写入至自己的中继日志(relay log)并将日志刷新至块设备。所以并不意味着该事务数据已经在数据库中执行(在mysql中就是sql thread是否已执行)。master一收到slave的确认消息即向应用程序返回事务已完成。

本系统采用Keepalived + Mysql主主模式来保证数据库的高可用

  1. Linux: Centos 6.9
  2. Mysql Version: 5.5
  3. master_mysql1 ip: 192.168.1.146
  4. master_mysql2 ip: 192.168.1.148
  5. VIP: 192.168.1.149

ENV Prepare

  1. yum install keepalived mysql; #Install mysql and keepalived
  2. chkconfig keepalived on; chkconfig mysqld on; # Add keepalived and mysql to machine start

Mysql Config

  1. [mysqld]
  2. log-bin=mysql-bin
  3. server-id=146
  4. auto-increment-increment = 2
  5. uto-increment-offset = 1
  1. [mysqld]
  2. log-bin=mysql-bin
  3. server-id=148
  4. auto-increment-increment = 2
  5. uto-increment-offset = 1
  1. # master_mysql1
  2. mysql > grant replication client,replication slave on *.* to backup@192.168.1.148 identified by '123456';
  3. mysql > flush privileges;
  4. # master_mysql2
  5. mysql > grant replication client,replication slave on *.* to backup@192.168.1.146 identified by '123456';
  6. mysql > flush privileges;
  1. # master_mysql1
  2. mysql > show master status;
  3. # master_mysql2
  4. mysql > change master to master_host='192.168.1.146',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=263; # mysql-bin.000001 and 263 is output of last command
  5. mysql > start slave;
  6. mysql > show slave status\G #excute this command and check two args below ,yes is success
  7. Slave_IO_Running: Yes
  8. Slave_SQL_Running: Yes
  1. # master_mysql2
  2. mysql > show master status;
  3. # master_mysql1
  4. mysql > change master to master_host='192.168.1.148',master_user='backup',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=278; # mysql-bin.000002 and 278 is output of last command
  5. mysql > start slave;
  6. mysql > show slave status\G #excute this command and check two args below ,yes is success
  7. Slave_IO_Running: Yes
  8. Slave_SQL_Running: Yes

Keepalived Config

  1. ! Configuration File for keepalived
  2. global_defs {
  3. notification_email {
  4. salt_yang@puyacn.com
  5. }
  6. notification_email_from service@webackup.cn
  7. smtp_server smtp.mxichina.cn
  8. smtp_connect_timeout 30
  9. router_id MASTER
  10. }
  11. vrrp_script check_mysql {
  12. script "/etc/keepalived/checkmysql.sh check"
  13. interval 30
  14. }
  15. vrrp_instance MASTER {
  16. state BACKUP
  17. interface eth4
  18. virtual_router_id 51
  19. priority 100
  20. advert_int 1
  21. authentication {
  22. auth_type PASS
  23. auth_pass 1111
  24. }
  25. virtual_ipaddress {
  26. 192.168.1.149
  27. }
  28. track_script {
  29. check_mysql
  30. }
  31. debug
  32. nopreempt
  33. notify_master "/etc/keepalived/checkmysql.sh master"
  34. notify_backup "/etc/keepalived/checkmysql.sh backup"
  35. }
  1. ! Configuration File for keepalived
  2. global_defs {
  3. notification_email {
  4. salt_yang@puyacn.com
  5. }
  6. notification_email_from service@webackup.cn
  7. smtp_server smtp.mxichina.cn
  8. smtp_connect_timeout 30
  9. router_id BACKUP
  10. }
  11. vrrp_script check_mysql {
  12. script "/etc/keepalived/checkmysql.sh check"
  13. interval 30
  14. }
  15. vrrp_instance BACKUP {
  16. state BACKUP
  17. interface eth5
  18. virtual_router_id 51
  19. priority 90
  20. advert_int 1
  21. authentication {
  22. auth_type PASS
  23. auth_pass 1111
  24. }
  25. virtual_ipaddress {
  26. 192.168.1.149
  27. }
  28. track_script {
  29. check_mysql
  30. }
  31. debug
  32. nopreempt
  33. notify_master "/etc/keepalived/checkmysql.sh master"
  34. notify_backup "/etc/keepalived/checkmysql.sh backup"
  35. }
  1. #!/bin/dash
  2. # Script to handle MySQL from keepalived.
  3. #
  4. # Usage: checkmysql.sh action
  5. #
  6. # Where action is :
  7. #
  8. # check : MySQL is running
  9. #
  10. # backup: set to backup state.
  11. # fault : set to fault state. Killing MySQL
  12. # master: set to master state. start MySQL
  13. #
  14. #
  15. # Note: you can use $MAINTENANCE (/etc/keepalived/maintenance) to disable MySQL checks
  16. # in case of short MySQL maintenance
  17. #
  18. # Usage func :
  19. [ "$1" = "--help" ] && { sed -n -e '/^# Usage:/,/^$/ s/^# \?//p' < $0; exit; }
  20. #
  21. # CONFIG
  22. #
  23. MYSQL="/usr/bin/mysql"
  24. # must return "1" string:
  25. CHECKSQL="SELECT 1"
  26. CHECKSQLSTR="1"
  27. # MySQL server settings
  28. MYSQLPID="/var/run/mysqld/mysqld.pid"
  29. MYSQLINIT="/etc/init.d/mysqld"
  30. MYSQLUSER="root"
  31. MYSQLPWD="111111"
  32. # Keepalived
  33. KEEPALIVEDPID=/var/run/keepalived.pid
  34. KEEPALIVED=/etc/init.d/keepalived
  35. # warmup delay
  36. MAXWAIT=240
  37. # MySQL fatal errors, which will provoke a node switch
  38. # (should be completed with next bad events...)
  39. MYSQL_FATAL_ERRORS='(2000|2001|2002|2003|2005|2008|28000)'
  40. # maintenance flag: used to do maintenance on MySQL without switch between nodes
  41. MAINTENANCE="/etc/keepalived/maintenance"
  42. #
  43. # CONFIG LOGGER
  44. #
  45. LOG="logger -t KeepMYSQL[$$] -p syslog" # do not use -i
  46. LOGWARN="$LOG.warn"
  47. LOGERR="$LOG.err"
  48. check() {
  49. # master and slave need check mysql status,
  50. # if mysql is down in master ,need switch master to slave. But it's not needed in salve.
  51. if ip addr | grep "${VIP}"
  52. then
  53. if check_mysql
  54. then
  55. $LOGWARN "MySQL is ok"
  56. else
  57. $MYSQLINIT restart
  58. $LOGWARN "Restart Mysqld service"
  59. if check_mysql
  60. then
  61. $LOGWARN "After restart mysqld service, but it's also down. Switch keepalive status"
  62. $KEEPALIVED restart
  63. fi
  64. fi
  65. else
  66. $LOGWARN "This is Mysql Salve."
  67. if check_mysql
  68. then
  69. $LOGWARN "MySQL is ok"
  70. else
  71. $MYSQLINIT restart
  72. $LOGWARN "Restart Mysqld service"
  73. if check_mysql
  74. then
  75. $LOGWARN "After restart mysqld service, but it's also down. Switch keepalive status"
  76. fi
  77. fi
  78. fi
  79. return $?
  80. }
  81. set_master() {
  82. # Starting MySQL
  83. if [ $( pidof mysqld | wc -w ) -gt 0 ]
  84. then
  85. $LOGWARN "MySQL already started ? What did I have to do ?"
  86. else
  87. $LOGWARN "Starting MySQL ..."
  88. $MYSQLINIT start
  89. for i in $( seq 1 $MAXWAIT )
  90. do
  91. sleep 1
  92. if check_mysql
  93. then
  94. break
  95. fi
  96. done
  97. fi
  98. if check_mysql
  99. then
  100. $LOGWARN "Checking MySQL MyISAM tables ..."
  101. mysql_check mysql
  102. $MYSQL -ABN -e "select TABLE_SCHEMA, TABLE_NAME from tables WHERE ENGINE='MyISAM' AND TABLE_SCHEMA NOT LIKE '%_schema' AND TABLE_SCHEMA NOT LIKE 'mysql'" information_schema | while read db table
  103. do
  104. mysql_check $db $table
  105. done
  106. else
  107. $LOGWARN "MySQL is broken and need a manual repair :("
  108. fi
  109. }
  110. # Do a mysqlcheck
  111. mysql_check() {
  112. db=$1
  113. table=$2
  114. param="$db $table"
  115. if [ -z "$table" ]
  116. then
  117. param="-B $db"
  118. fi
  119. cmd="${MYSQL}check --medium-check -F --auto-repair $param"
  120. $LOGWARN "$cmd"
  121. $cmd 2>&1 | while read l
  122. do
  123. $LOGWARN "$l"
  124. done
  125. }
  126. # Check that MySQL is responding
  127. # Return:
  128. # 0 if everything is OK (or in maintenance mode)
  129. # 1 if SQL did not return the expected string
  130. # 2 if MySQL did not reply
  131. check_mysql() {
  132. if [ -e $MAINTENANCE ]
  133. then
  134. return 0
  135. fi
  136. m=$( $MYSQL --connect-timeout=2 -ABN -e "$CHECKSQL" mysql -u$MYSQLUSER -p$MYSQLPWD 2>&1 )
  137. mcode=$?
  138. # Check MySQL error codes. Not all errors are fatal, like "1023 too many connections"
  139. if [ $mcode -gt 0 ]
  140. then
  141. merrno=$( echo "$m" | grep -Eo 'ERROR ([0-9]+) ' | cut -d" " -f2 )
  142. $LOGWARN "[MySQL is unavailable] $m"
  143. if echo "$merrno" | grep -qE "$MYSQL_FATAL_ERRORS"
  144. then
  145. return 2
  146. else
  147. return 0 # not fatal ...
  148. fi
  149. # Check MySQL reply to SQL query
  150. elif [ "$m" = "$CHECKSQLSTR" ]
  151. then
  152. return 0
  153. else
  154. $LOGWARN "MySQL did not return expected value: '$CHECKSQLSTR' != '$m'"
  155. return 1
  156. fi
  157. return 1
  158. }
  159. case "$1" in
  160. check)
  161. check
  162. exit $?
  163. ;;
  164. backup)
  165. $LOGWARN "=> set to backup state <="
  166. set_master
  167. exit $?
  168. ;;
  169. master)
  170. $LOGWARN "=> set to master state <="
  171. set_master
  172. exit $?
  173. ;;
  174. esac
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注