前言:之前搭建的gitlab双机互备环境(参考之前的博文)还存在一个问题:后台数据库是单台服务器,存在单点故障的风险,这几天调研了相关资料,发现可以借助mysql-proxy来解决这个问题。
需要环境:
两台mysql服务器搭建主备环境: master-master
一台服务器搭建mysql-proxy
1. 搭建mysql的主备环境:master-master
2. 通过mysql-proxy实现Failover
3. 修改gitlab的数据库配置,直接连接mysql-proxy
4. 待解决问题
准备两台Linux服务器: A和B(mysql版本,5.0),分别在A、B上进行如下操作:
1. 安装mysql
1 $A/$B: yum install mysql-server.x86_64
2. 创建同步账号并赋予同步权限
1 $A/$B: GRANT REPLICATION SLAVE ON *.* TO 'slave'@'$B' IDENTIFIED BY 'slave'; 2 $A/$B: flush privileges;
3. 修改mysql配置,在/etc/my.cnf文件中添加:
1 log-bin=mysql-bin #同步事件的日志记录文件 2 log-salve-updates 3 server-id=47 #数据库的标识Id 4 5 master-host = $A/$B #同步数据库的地址 6 master-user = slave #同步数据库的用户 7 master-password = slave #同步数据库的密码 8 master-connect-retry=60 #如果从服务器发现主服务器断掉,重新连接的时间差
重启mysql服务器
4. 设置服务器参数
停止当前主机上同步状态
1 $A/$B: mysql>stop slave;
在备机($B)上查看当前数据库mysqlbinlog日志位置
1 mysql> show master status; 2 +——————+———-+——————+——————+ 3 | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | 4 +——————+———-+——————+——————+ 5 | mysql-bin.00008 | 210 | ikey_db | 6 +——————+———-+——————+——————+ 7 1 row in set (0.00 sec)
记录下当前的同步日志文件mysql-bin.00008,同步位置:210;
更改主机($A)同步备机数据位置
1 mysql>CHANGE MASTER TO 2 -> MASTER_HOST=’$B′, #原备节点IP地址 3 -> MASTER_USER=’slave’, 4 -> MASTER_PASSWORD=’slave’, 5 -> MASTER_LOG_FILE=’ mysql-bin.00008′, # 刚才我们记录备节点数据库要执行复制的日志文件。 6 -> MASTER_LOG_POS=210; #刚才记录的虚拟机备节点数据库要复制的日志文件位置。 7 Query OK, 0 rows affected (0.02 sec)
同样的,查看主机($A)的当前数据库mysqlbinlog日志位置
1 mysql> show master status; 2 +——————+———-+——————+——————+ 3 | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | 4 +——————+———-+——————+——————+ 5 | mysql-bin.00009 | 213 | ikey_db | 6 +——————+———-+——————+——————+ 7 1 row in set (0.00 sec)
更改备机($B)同步主机数据位置
1 mysql>CHANGE MASTER TO 2 -> MASTER_HOST=’$A’, #原主节点IP地址 3 -> MASTER_USER=’slave’, 4 -> MASTER_PASSWORD=’slave’, 5 -> MASTER_LOG_FILE=’ mysql-bin.00009′, # 刚才我们记录主节点数据库要执行复制的日志文件。 6 -> MASTER_LOG_POS=213; #刚才记录的虚拟机主节点数据库要复制的日志文件位置。 7 Query OK, 0 rows affected (0.02 sec)
5. 启动同步状态并检查是否成功
1 $A/$B: mysql>start slave;
检测数据同步状态
1 $A/$B: mysql> show slave status\G; 2 *************************** 1. row *************************** 3 Slave_IO_State: Waiting for master to send event 4 Master_Host: 虚拟机备节点IP 5 Master_User: sync_ikey 6 Master_Port: 3306 7 Connect_Retry: 60 8 Master_Log_File: mysql-bin.000008 9 Read_Master_Log_Pos: 210 10 Relay_Log_File: node1-relay-bin.000003 11 Relay_Log_Pos: 251 12 Relay_Master_Log_File: mysql-bin.000002 13 Slave_IO_Running: Yes 14 Slave_SQL_Running: Yes 。。。
只要数据库中查看得到
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
此代表数据同步状态正常。
准备linux服务器C, 下载mysql-proxy的安装包http://dev.mysql.com/downloads/mysql-proxy/,解压缩到本地
编写failover脚本
vi $mysql-proxy_path/share/doc/mysql-proxy/mysql_failover.lua
1 function connect_server() 2 for i = 1, #proxy.backends do 3 local s = proxy.backends[i] 4 print ("s.state:" + s.state) 5 if s.state ~= proxy.BACKEND_STATE_DOWN then 6 proxy.connection.backend_ndx = i 7 print ("connecting to " .. i) 8 return 9 end 10 end 11 end 12 13 function read_query(packet) 14 for i = 1, #proxy.backends do 15 local s = proxy.backends[i] 16 print ("s.state:" + s.state) 17 if s.state ~= proxy.BACKEND_STATE_DOWN then 18 proxy.connection.backend_ndx = i 19 print ("connecting to " .. i) 20 return 21 end 22 end 23 end
启动mysql-proxy
$mysql-proxy_path/bin/mysql-proxy --proxy-address=:4040 --proxy-lua-script=$mysql-proxy_path/share/doc/mysql-proxy/mysql_failover.lua --proxy-backend-addresses=$A:3306 --proxy-backend-addresses=$B:3306 --log-level=error --log-file=$mysql-proxy_path/mysql-proxy.log --keepalive --proxy-fix-bug-25371
mysql-proxy默认连接的是A服务器,如果A服务器挂了,mysql-proxy会自动切换到B,如果之后A恢复了,mysql-proxy又会切换到A,这样就可以实现mysql双机互备和Failover
vi $gitlab_path/config/database.yml
1 production: 2 adapter: mysql2 3 encoding: utf8 4 reconnect: false 5 database: gitlab 6 pool: 25 7 username: root 8 password: 9 host: $C #mysql-proxy的主机地址 10 port: 4040 #mysql-proxy的主机端口 11 # socket: /tmp/mysql.sock
mysql-proxy最大问题就是自身可能成为单点,存在单点故障的风险。