概述 MySql官网提供了2种复制方案,一种是基于日志文件来实现复制,一种是基于GTIDs来实现复制,这篇文章采用第一种来试验,结合keepalived完成高可用。试验环境如下:
系统环境
IP地址
节点类型
CentOS6.5
192.168.1.92
Master
CentOS6.5
192.168.1.93
Slave(用于备份服务器)
CentOS6.5
192.168.1.94
VIP
CentOS6.5
192.168.1.17
Client
MySql安装 本文采用离线安装包的方式安装mysql服务。使用的版本是5.7.13,下载地址 ,下载的文件清单:
mysql-community-client-5.7.13-1.el6.x86_64.rpm
mysql-community-common-5.7.13-1.el6.x86_64.rpm
mysql-community-libs-5.7.13-1.el6.x86_64.rpm
mysql-community-server-5.7.13-1.el6.x86_64.rpm
Master和Slave节点都安装mysql,执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [root@localhost scripts] [root@localhost ~] mysql-server-5.1.71-1.el6.x86_64 mysql-libs-5.1.71-1.el6.x86_64 mysql-5.1.71-1.el6.x86_64 qt-mysql-4.6.2-26.el6_4.x86_64 [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost mysql] mysql-community-client-5.7.13-1.el6.x86_64.rpm mysql-community-common-5.7.13-1.el6.x86_64.rpm mysql-community-libs-5.7.13-1.el6.x86_64.rpm mysql-community-server-5.7.13-1.el6.x86_64.rpm [root@localhost mysql] warning: mysql-community-common-5.7.13-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY Preparing... 1:mysql-community-common [root@localhost mysql] warning: mysql-community-libs-5.7.13-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY Preparing... 1:mysql-community-libs [root@localhost mysql] warning: mysql-community-client-5.7.13-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY Preparing... 1:mysql-community-client [root@localhost mysql] warning: mysql-community-server-5.7.13-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY Preparing... 1:mysql-community-server
启动mysql服务,获取root初始化密码,测试成功后停止mysql: [root@localhost lib]# service mysqld start [root@localhost lib]# service mysqld status [root@localhost lib]# grep ‘temporary password’ /var/log/mysqld.log [root@localhost lib]# service mysqld stop
mysql服务就这样安装好了,下面接着进行服务的配置:
数据库目录的配置,默认是指向的/var/lib/mysql,这个时候你要注意当前路径所在的磁盘空间是否足够:1 2 3 4 5 [root@localhost mysql] Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_livedvd-lv_root 36G 5.7G 30G 17% / tmpfs 939M 0 939M 0% /dev/shm /dev/sda1 485M 40M 421M 9% /boot
Master的配置文件:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@localhost mysql] [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid server-id=1 log-bin=mysql-bin sync_binlog=1 replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test .% replicate-wild-ignore-table=information_schema.% replicate-wild-ignore-table=performance_schema.% replicate-wild-ignore-table=sys.% relay-log=mysql-relay-bin skip-name-resolve
Slave的配置内容:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@localhost mysql] [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION server-id=2 log-bin=mysql-bin sync_binlog=1 replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test .% replicate-wild-ignore-table=information_schema.% replicate-wild-ignore-table=performance_schema.% replicate-wild-ignore-table=sys.% relay-log=mysql-relay-bin skip-name-resolve
编辑文件/etc/sysconfig/iptables, 打开端口3306:1 2 3 4 5 6 7 8 9 [root@localhost data] -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT [root@localhost data] iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Flushing firewall rules: [ OK ] iptables: Unloading modules: [ OK ] iptables: Applying firewall rules: [ OK ]
启动mysql服务,修改mysql的默认密码:1 2 3 4 5 6 7 [root@localhost opt] [root@localhost opt] Initializing MySQL database: [ OK ] Installing validate password plugin: [ OK ] Starting mysqld: [ OK ] [root@localhost opt] mysql> ALTER USER 'root' @'localhost' IDENTIFIED BY 'Admin@2016' ;
Master配置 1.提供一个slave可以复制的账号,ip地址根据实际情况修改。
1 2 3 4 mysql> CREATE USER 'repl' @'192.168.1.93' IDENTIFIED BY 'Admin@2016' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl' @'192.168.1.93' ; mysql> grant all on *.* to root@'192.168.1.17' identified by 'Admin@2016' ; mysql> flush privileges;
2.去Slave数据库查询坐标信息:
1 2 3 4 5 6 7 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 1304 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
3.命令行里面设置slave配置信息,注意日志文件的起点(Master和Slave都执行了1和2步骤才执行该步骤):
1 2 3 4 5 6 7 mysql> CHANGE MASTER TO \ MASTER_HOST='192.168.1.93' , \ MASTER_PORT=3306, \ MASTER_USER='repl' , \ MASTER_PASSWORD='Admin@2016' , \ MASTER_LOG_FILE='mysql-bin.000003' , \ MASTER_LOG_POS=1304;
Slave配置 1.提供一个Master可以复制的账号,ip地址根据实际情况修改。
1 2 3 4 mysql> CREATE USER 'repl' @'192.168.1.92' IDENTIFIED BY 'Admin@2016' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl' @'192.168.1.92' ; mysql> grant all on *.* to root@'192.168.1.17' identified by 'Admin@2016' ; mysql> flush privileges;
2.去Master数据库查询坐标信息:
1 2 3 4 5 6 7 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 1304 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
3.命令行里面设置Master配置信息,注意日志文件的起点(Master和Slave都执行了1和2步骤才执行该步骤):
1 2 3 4 5 6 7 mysql> CHANGE MASTER TO \ MASTER_HOST='192.168.1.92' , \ MASTER_PORT=3306, \ MASTER_USER='repl' , \ MASTER_PASSWORD='Admin@2016' , \ MASTER_LOG_FILE='mysql-bin.000003' , \ MASTER_LOG_POS=1304;
测试同步效果 两台服务启动slave,查看状态Slave_IO_Running: Yes和Slave_SQL_Running: Yes,并且没有error错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 mysql> start slave; mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.93 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 1304 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.%,test .%,information_schema.% Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1304 Relay_Log_Space: 527 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2 Master_UUID: a811e6e5-918d-11e7-9670-000c29358af8 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log ; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) mysql>show processList\G;
主库创建数据库,创建表,插入数据,去从库看一下是否同步:
1 2 3 4 5 6 7 8 9 10 create database test1; use test1; CREATE TABLE `catalog` ( `id ` varchar(32) NOT NULL, `parent_id` varchar(32) DEFAULT NULL, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id `) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `catalog` VALUES ('01' , 'A' , '农业' ); INSERT INTO `catalog` VALUES ('011' , '01' , '谷物种植' );
从库创建数据库,创建表,插入数据,去主库看一下是否同步:
1 2 3 4 5 6 7 8 9 10 create database test2; use test2; CREATE TABLE `catalog` ( `id ` varchar(32) NOT NULL, `parent_id` varchar(32) DEFAULT NULL, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id `) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `catalog` VALUES ('01' , 'A' , '农业2' ); INSERT INTO `catalog` VALUES ('011' , '01' , '谷物种植2' );
如果两边看到的内容一致,表示主主复制关系没问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test1 | | test2 | +--------------------+ 6 rows in set (0.01 sec) mysql> select * from test2.catalog; +-----+-----------+---------------+ | id | parent_id | name | +-----+-----------+---------------+ | 01 | A | 农业2 | | 011 | 01 | 谷物种植2 | +-----+-----------+---------------+ 2 rows in set (0.00 sec)
系统调优 1 2 3 4 5 6 7 8 9 10 11 12 [root@localhost ~] [root@localhost ~] [root@localhost ~] * soft nofile 65536 * hard nofile 65536 * soft nproc unlimited * hard nproc unlimited [root@localhost ~] * soft nproc unlimited root soft nproc unlimited
LVS安装 检查linux内核是否集成lvs模块:
第一种通过lvs源码安装:
1 2 3 [root@localhost ~] [root@localhost ~] ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)
第二种通过源码编译安装:
1 2 3 4 [root@localhost] [root@localhost ipvsadm-1.26] [root@localhost ipvsadm-1.26] [root@localhost ipvsadm-1.26]
开启路由转发功能:
1 2 3 4 5 6 7 8 9 10 [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] ip_vs_wrr 2179 1 ip_vs 126705 3 ip_vs_wrr libcrc32c 1246 1 ip_vs ipv6 336368 47 ip_vs,bridge,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
Keepalived安装 Master和Slave都执行以下命令:
1 2 3 4 [root@localhost ~] [root@localhost ~] [root@localhost ~] Keepalived v1.2.13 (03/19,2015)
第二种安装方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@localhost] [root@localhost opt] [root@localhost opt] [root@localhost opt] [root@localhost] [root@localhost] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~] [root@localhost ~]
创建mysql_down监控脚本:
1 2 3 4 5 [root@localhost ~] [root@localhost ~] service keepalived stop [root@master ~]
Master节点配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 [root@localhost ~] global_defs { notification_email { sysadmin@firewall.loc } notification_email_from mysql_master@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id MYSQL-HA } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 59 priority 150 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.94/24 dev eth0 scope global label eth0:0 } } virtual_server 192.168.1.94 3306 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.1.92 3306 { notify_down /etc/keepalived/scripts/mysql_down.sh TCP_CHECK { } } }
Slave 节点配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 [root@localhost ~] global_defs { notification_email { sysadmin@firewall.loc } notification_email_from mysql_slave@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id MYSQL-HA } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 59 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.94/24 dev eth0 scope global label eth0:0 } } virtual_server 192.168.1.94 3306 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.1.93 3306 { notify_down /etc/keepalived/scripts/mysql_down.sh TCP_CHECK { } } }
防火墙设置 1 2 [root@localhost ~] -A INPUT -p vrrp -j ACCEPT
测试效果 手动启动服务器试试正常不:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@master~] Starting keepalived: [ OK ] [root@master ~] 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link /ether 00:0c:29:62:98:c0 brd ff:ff:ff:ff:ff:ff inet 192.168.1.92/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.94/24 scope global secondary eth0:0 inet6 fe80::20c:29ff:fe62:98c0/64 scope link valid_lft forever preferred_lft forever --------------------------------------------------------------------------------------------- [root@slave ~] Starting keepalived: [ OK ] [root@localhost ~] 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link /ether 00:0c:29:35:8a:f8 brd ff:ff:ff:ff:ff:ff inet 192.168.1.93/24 brd 192.168.1.255 scope global eth0 inet6 fe80::20c:29ff:fe35:8af8/64 scope link valid_lft forever preferred_lft forever
先修改一下主机名信息,重启服务器:
1 2 [root@localhost ~] [root@localhost ~]
测试故障转移,正常情况下,客户端连接的是Master节点,在Client机子上进行下面测试:
1 2 3 4 5 6 7 mysql> show variables like 'hostname%' ; +---------------+------------------+ | Variable_name | Value | +---------------+------------------+ | hostname | localhost.master | +---------------+------------------+ 1 row in set
此时停掉Master后,在执行下面的命令:
1 2 3 4 5 6 7 mysql> show variables like 'hostname%' ; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | hostname | localhost.slave | +---------------+-----------------+ 1 row in set
可以测试在Slave添加一条数据,然后在恢复Master,查询该数据是否存在.