mysql @a_mysql学习:mysql+keepalived双主高可用配置

我们通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务。当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短。MySQL双主复制,即互为Master-Slave(只有一个Master提供写操作),可以实现数据库服务器的热备,但是一个Master宕机后不能实现动态切换。使用Keepalived,可以通过虚拟IP,实现双主对外的统一接口以及自动检查、失败切换机制,从而实现MySQL数据库的高可用方案。之前梳理了Mysql主从(从只读),下面说下Mysql+keeoalived双主热备高可用方案的实施。

1)先实施Master->Slave的主主同步。主主是数据双向同步,主从是数据单向同步。一般情况下,主库宕机后,需要手动将连接切换到从库上。(但是用keepalived就可以自动切换)

2)再结合Keepalived的使用,通过VIP实现Mysql双主对外连接的统一接口。即客户端通过Vip连接数据库;当其中一台宕机后,VIP会漂移到另一台上,这个过程对于客户端的数据连接来说几乎无感觉,从而实现高可用。

环境描述:

mysql使用的是:mysql-5.7.20的rpm包,最新的可从mysql官网下载

keepalive服务:直接通过yum来进行安装

Centos6.9版本

Master1:192.168.220.70       安装mysql和keepalived

Master2: 192.168.220.71       安装mysql和keepalived

VIP:192.168.220.74

要实现主主同步,可以先实现主从同步,即master1->master2的主从同步,然后master2->master1的主从同步.

这样,双方就完成了主主同步。

注意下面几点:

1)要保证同步服务期间之间的网络联通。即能相互ping通,能使用对方授权信息连接到对方数据库(允许对方master以及客户机访问这两台机器的3306端口)。

将配置文件中的多播地址,防火墙放行

2)同步时间,关闭selinux。

3)同步前,双方数据库中需要同步的数据要保持一致。这样,同步环境实现后,再次更新的数据就会如期同步了。

4)如果数据目录直接从一台机器拷贝到另外一台机器,需要将mysql数据目录下面的auto.cnf文件删除,不然uuid相同会报错

mysql-5.7.20安装说明

新版本安装好后,修改配置文件,根据配置文件创建好需要的数据目录,日志目录,权限等操作

启动mysql服务,刚开始会进行数据初始化操作,初始化完成后,可以使用mysql命令连接服务

新版本会在日志文件中生成一个临时密码,使用临时密码登录,登录后必须修改密码,不然不能操作

关闭服务,在配置文件中添加:validate_password=off 选项,让系统可以接受弱密码,这时可以修改密码为常用的密码

mysql> set password = password("abcdef");

上面的顺序不能错,刚开始不能添加validate_password选项,不然报错

Master1授权

[root@RTB-70 ~]#cat /etc/my.cnf

[client]

password        = abcdefg

port            = 3306

socket          = /data/mysql/mysql.sock

default-character-set=utf8

[mysqld]

port            = 3306

socket          = /data/mysql/mysql.sock

datadir         = /data/mysql

user            = mysql

character-set-server=utf8

server-id       = 70

skip-external-locking

key_buffer_size = 256M

max_allowed_packet = 100M

table_open_cache = 256

sort_buffer_size = 1M

read_buffer_size = 1M

read_rnd_buffer_size = 4M

myisam_sort_buffer_size = 64M

thread_cache_size = 8

query_cache_size= 16M

validate_password=off

skip-name-resolve

slow_query_log

log_warnings=1

expire_logs_days = 30

auto-increment-increment = 2

auto-increment-offset = 1

slave-skip-errors = all

log-bin=/data/mysql_binlog/mysql-bin

binlog-ignore-db = mysql,information_schema

binlog_format=mixed

relay_log=/data/mysql_binlog/mysql-relay

[mysqldump]

quick

max_allowed_packet = 100M

[mysqld_safe]

log-error=/var/log/mysqld/mysqld.log

pid-file=/data/mysql/mysqld.pid

[root@RTB-70 ~]#service mysqld restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

[root@RTB-70 ~]#mysql

mysql> grant replication slave, replication client on *.* to 'rep_user'@'192.168.220.%' identified by '456789';

Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.02 sec)

mysql> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

mysql> show master status;

+------------------+----------+--------------+--------------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |

+------------------+----------+--------------+--------------------------+-------------------+

| mysql-bin.000003 |      884 |              | mysql,information_schema |                   |

+------------------+----------+--------------+--------------------------+-------------------+

1 row in set (0.00 sec)

Master2授权

[root@RTB-71 ~]#cat /etc/my.cnf

[client]

password        = abcdefg

port            = 3306

socket          = /data/mysql/mysql.sock

default-character-set=utf8

[mysqld]

port            = 3306

socket          = /data/mysql/mysql.sock

datadir         = /data/mysql

user            = mysql

character-set-server=utf8

server-id       = 71

skip-external-locking

key_buffer_size = 256M

max_allowed_packet = 100M

table_open_cache = 256

sort_buffer_size = 1M

read_buffer_size = 1M

read_rnd_buffer_size = 4M

myisam_sort_buffer_size = 64M

thread_cache_size = 8

query_cache_size= 16M

validate_password=off

skip-name-resolve

slow_query_log

log_warnings=1

expire_logs_days = 30

auto-increment-increment = 2

auto-increment-offset = 2

slave-skip-errors = all

log-bin=/data/mysql_binlog/mysql-bin

binlog-ignore-db = mysql,information_schema

binlog_format=mixed

relay_log=/data/mysql_binlog/mysql-relay

[mysqldump]

quick

max_allowed_packet = 100M

[mysqld_safe]

log-error=/var/log/mysqld/mysqld.log

pid-file=/data/mysql/mysqld.pid

[root@RTB-71 ~]#service mysqld restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

[root@RTB-71 ~]#mysql

mysql> grant replication slave, replication client on *.* to 'rep_user'@'192.168.220.%' identified by '456789';

Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.02 sec)

mysql> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

mysql> show master status;

+------------------+----------+--------------+--------------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |

+------------------+----------+--------------+--------------------------+-------------------+

| mysql-bin.000004 |      154 |              | mysql,information_schema |                   |

+------------------+----------+--------------+--------------------------+-------------------+

1 row in set (0.00 sec)

Master1->Master2

[root@RTB-71 ~]#mysql

mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='192.168.220.70', master_user='rep_user',

master_password='456789', master_log_file='mysql-bin.000003', master_log_pos=884;

Query OK, 0 rows affected, 2 warnings (0.16 sec)

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.220.70

Master_User: rep_user

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000003

Read_Master_Log_Pos: 884

Relay_Log_File: mysql-relay.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000003

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Master2->Master1

[root@RTB-70 ~]#mysql

mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='192.168.220.71', master_user='rep_user',

master_password='456789', master_log_file='mysql-bin.000004', master_log_pos=154;

Query OK, 0 rows affected, 2 warnings (0.16 sec)

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.220.71

Master_User: rep_user

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000004

Read_Master_Log_Pos: 154

Relay_Log_File: mysql-relay.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000004

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

还是有地方没搞明白,为什么我设置binlog忽略了mysql库,但是执行授权语句,binlog的位置还在增加

主主同步测试

在RTB-70机器测试

mysql> create database abc;

Query OK, 1 row affected (0.01 sec)

mysql> use abc;

Database changed

mysql> create table if not exists hello (id int(10) primary key auto_increment, name varchar(50) not null);

Query OK, 0 rows affected (0.21 sec)

mysql> insert into hello (name) values ('andy');

Query OK, 1 row affected (0.06 sec)

mysql> show tables;

+---------------+

| Tables_in_abc |

+---------------+

| hello         |

+---------------+

1 row in set (0.00 sec)

mysql> select * from hello;

+----+------+

| id | name |

+----+------+

|  1 | andy |

+----+------+

1 row in set (0.00 sec)

在机器RTB-71上面测试

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| abc                |

| mysql              |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0.00 sec)

mysql> use abc;

Database changed

mysql> show tables;

+---------------+

| Tables_in_abc |

+---------------+

| hello         |

+---------------+

1 row in set (0.00 sec)

mysql> select * from hello;

+----+------+

| id | name |

+----+------+

|  1 | andy |

+----+------+

1 row in set (0.00 sec)

mysql> insert into hello (name) values ('bob');

Query OK, 1 row affected (0.03 sec)

mysql> insert into hello (name) values ('mary');

Query OK, 1 row affected (0.03 sec)

mysql> select * from hello;

+----+------+

| id | name |

+----+------+

|  1 | andy |

|  2 | bob  |

|  4 | mary |

+----+------+

3 rows in set (0.00 sec)

keepalived测试

[root@RTB-70 /etc/keepalived]#cat keepalived.conf

! Configuration File for keepalived

global_defs {

notification_email {

root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id keep_mysql

vrrp_mcast_group4 224.0.100.50

}

vrrp_script chk_down {

script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"  #down文件在,返回1。不在返回0

interval 1    #1秒钟调用一次,当上面的脚本执行返回1的时候会执行下面的操作

weight -20    #当down文件存在,这个vs的节点的优先级-20,如果这个节点的优先级低于其他的vs主机,

#这个主机就会处于维护模式,ip被其他优先级高的主机夺走。

}

vrrp_script chk_mysql {

script "killall -0 mysqld && exit 0 || exit 1"    #进程在,返回0,不执行下面的操作。否则1,执行下面的操作

interval 1

weight -20    #当nginx进程不存在了,表示这个节点处错了,将这个节点的优先级调低,让另外的节点来负责工作。

}

vrrp_instance c.com {

state MASTER

interface eth0

virtual_router_id 20

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 2345

}

virtual_ipaddress {

192.168.220.74/24 dev eth0

}

track_script {

chk_down

chk_nginx

}

}

[root@RTB-71 /etc/keepalived]#cat keepalived.conf

! Configuration File for keepalived

global_defs {

notification_email {

root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id keep_mysql

vrrp_mcast_group4 224.0.100.50

}

vrrp_script chk_down {

script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"  #down文件在,返回1。不在返回0

interval 1    #1秒钟调用一次,当上面的脚本执行返回1的时候会执行下面的操作

weight -20    #当down文件存在,这个vs的节点的优先级-20,如果这个节点的优先级低于其他的vs主机,

#这个主机就会处于维护模式,ip被其他优先级高的主机夺走。

}

vrrp_script chk_mysql {

script "killall -0 mysqld && exit 0 || exit 1"    #进程在,返回0,不执行下面的操作。否则1,执行下面的操作

interval 1

weight -20    #当nginx进程不存在了,表示这个节点处错了,将这个节点的优先级调低,让另外的节点来负责工作。

}

vrrp_instance c.com {

state BACKUP

interface eth0

virtual_router_id 20

priority 90

advert_int 1

authentication {

auth_type PASS

auth_pass 2345

}

virtual_ipaddress {

192.168.220.74/24 dev eth0

}

track_script {

chk_down

chk_nginx

}

}

[root@RTB-70 /etc/keepalived]#service keepalived start

Starting keepalived:                                       [  OK  ]

[root@RTB-71 /etc/keepalived]#service keepalived start

Starting keepalived:                                       [  OK  ]

客户机测试

在RTB-70机器上面授权该网段访问

mysql> grant all on *.* to 'root'@'192.168.220.%' identified by '234567';

Query OK, 0 rows affected, 1 warning (0.01 sec)

在RTB-72上面测试

[root@rtb-72 ~]#mysql -uroot -h192.168.220.74 -p234567

MySQL [(none)]> insert into abc.hello (name) values('alix');

Query OK, 1 row affected (0.03 sec)

MySQL [(none)]> select * from abc.hello;

+----+-------+

| id | name  |

+----+-------+

|  1 | andy  |

|  2 | bob   |

|  4 | mary  |

|  5 | tom   |

|  7 | hello |

|  9 | hi    |

| 11 | alix  |

+----+-------+

7 rows in set (0.00 sec)

在RTB-70机器上面创建文件

[root@RTB-70 /etc/keepalived]#touch down

vip漂移到71,正常操作

主主复制自增id说明

根据上面的主从环境部署,master和slave已经实现同步,即在master上写入新数据,自动同步到slave。而从库只能读不能写,一旦从库有写入数据,就会造成主从数据不一致!

下面就说下Mysql主主复制环境,在slave上更新数据时,master也能自动同步过来。

---------------------------------------------------------------------------

温馨提示:

在做主主同步前,提醒下需要特别注意的一个问题:

主主复制和主从复制有一些区别,因为多主中都可以对服务器有写权限,所以设计到自增长重复问题,例如:

出现的问题(多主自增长ID重复)

1)首先在A和B两个库上创建test表结构;

2)停掉A,在B上对数据表test(存在自增长属性的ID字段)执行插入操作,返回插入ID为1;

3)然后停掉B,在A上对数据表test(存在自增长属性的ID字段)执行插入操作,返回的插入ID也是1;

4)然后 同时启动A,B,就会出现主键ID重复

解决方法:

只要保证两台服务器上的数据库里插入的自增长数据不同就可以了

如:A插入奇数ID,B插入偶数ID,当然如果服务器多的话,还可以自定义算法,只要不同就可以了

在下面例子中,在两台主主服务器上加入参数,以实现奇偶插入!

记住:在做主主同步时需要设置自增长的两个相关配置,如下:

auto_increment_offset       表示自增长字段从那个数开始,取值范围是1 .. 65535。这个就是序号。如果有n台mysql机器,则从第一台开始分为设1,2...n

auto_increment_increment    表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535。如果有n台mysql机器,这个值就设置为n。

在主主同步配置时,需要将两台服务器的:

auto_increment_increment     增长量都配置为2

auto_increment_offset        分别配置为1和2。这是序号,第一台从1开始,第二台就是2,以此类推.....

这样才可以避免两台服务器同时做更新时自增长字段的值之间发生冲突。(针对的是有自增长属性的字段)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值