MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
mysql服务器的抗压能力有限。假设一台服务器最多能够接受的并发请求数是500个。当并发超过500的时候,很显然一台服务器就不能正常工作了,就需要更多的服务器来支持。保证服务器之间的数据及时同步,需要使用主从的技术解决方案实现数据同步。
vim /etc/my.cnf
server-id=12 //这是服务器的唯一区别号,不能相同
log-bin=master-bin //主服务器日志文件/usr/local/mysql/data
log-slave-updates=true //从服务器更新二进制日志
systemctl restart mysqld //重启mysql数据库
mysql -uroot -p 123123 //连接数据库
grant replication slave on *.* to 'myslave'@'192.168.60.%'
identified by '123456'; //设置主从复制账号和密码
flush privileges; //刷新权限
show master status; //查看主服务器的二进制文件状态及位置
master_log_file='master-bin.000002' //二进制文件
master_log_pos=154 //位置点
vim /etc/my.cnf
server-id=22 //不能和其他数据库的server-id相同
relay-log=relay-log-bin //从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
systemctl restart mysqld
mysql -uroot -p 123123
change master to master_host='192.168.60.20', //主服务器的IP地址
master_user='myslave', //主从复制的账户
master_password='123456',
master_log_file='master-bin.000002', //主服务器的二进制文件
master_log_pos=154; //主从复制开始的位置点
start slave; //启动从服务器通过myslave账户同步主服务器的数据
show slave status\G;
//注意:显示结果连个线程必须是yes状态,否则请检查防火墙是否关闭或者账号和密码是否错误!
为了确保数据库产品的稳定性,很多数据库拥有双机热备功能。也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器;第二台数据库服务器,主要进行读的操作。
在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
在主从复制的基础上进行下面的配置实现读写分离
vim /etc/my.cnf
server-id=12
log-bin=master-bin //主服务器日志文件/usr/local/mysql/data
log-slave-updates=true //从服务器更新二进制日志
systemctl restart mysqld
mysql -uroot -p 123123
grant replication slave on *.* to 'myslave'@'192.168.60.%' identified by '123456';
flush privileges;
show master status;
master_log_file='master-bin.000002'
master_log_pos=154
vim /etc/my.cnf
server-id=22
relay-log=relay-log-bin //从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
systemctl restart mysqld
mysql -uroot -p 123123
change master to master_host='192.168.60.20',
master_user='myslave',
master_password='123456',
master_log_file='master-bin.000002',
master_log_pos=603;
start slave;
show slave status\G;
vim /etc/my.cnf
server-id=32
relay-log=relay-log-bin //从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
systemctl restart mysqld
mysql -uroot -p 123123
change master to master_host='192.168.60.20',
master_user='myslave',
master_password='123456',
master_log_file='master-bin.000002',
master_log_pos=603;
start slave;
show slave status\G;
cd /opt
amoeba-mysql-binary-2.2.0.tar.gz jdk-6u14-linux-x64.bin
mkdir /usr/local/amoeba
tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local/
chmod +x jdk-6u14-linux-x64.bin
./ jdk-6u14-linux-x64.bin //一直到输出yes然后一直回车
mv jdk1.6.0_14/ jdk1.6.0
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6.0
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
source /etc/profile
chmod -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba //检查是否成功 start|stop 表示成功
//设置读写分离账号和密码
grant all on *.* to 'test'@'192.168.60.%' identified by '123.com';
flush privileges;
//amoeba主配置文件
vim /usr/local/amoeba/conf/amoeba.xml
//设置客户端访问账户和密码
30amoeba
//允许客户端访问amoeba的用户名和密码
32 123123
115 master
116 //去掉注释,指定读写数据库服务器
117
121 true
//数据库服务配置文件
vim /sur/local/amoeba/conf/dbServers.xml
23 mysql
26 test
27
28
29 123.com
45
46
47
48 192.168.60.20
49
50
52
53
54
55 192.168.60.30
56
57
58
59
60
61
62 192.168.60.40
63
64
66
72 slave1,slave2
/usr/local/amoeba/bin/amoeba start &
netstat -natp | grep java/8066
//安装线网数据库充当客户端数据库服务器
yum install -y mysql mysql-server
//连接amoeba服务器
mysql -u amoeba -p123123 -h 192.168.60.10 -P8066
//查看是否和主服务器以及从服务其中的数据一致
show databases;
断开主从复制,在主服务器master和从服务器slaves上面分别写入不同的数据
在客户端服务器上面查看,是否只读slaves上面的数据
在客户端写入一条数据,看看是否只在master上面写入!
高可用是系统的一个特性,保证系统能在足够长的时间内提供指定程度的服务等级。再细化一下,可以说是在有限的故障条件下,提供一定级别的稳定服务。
主服务器的负载严重,如果主服务器宕机或者出现故障就会导致应用层用户访问不到数据库数据,所以为了提高数据库的可用性,为master服务器准备一个备用机,而这个备用机平时充当为slave服务器,只有在master不可用之后才充当master的角色。
MHA能做到0-30秒内自动完成故障切换,从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失。
MHA Manager (管理节点,管理健康状态)、MHA Node(数据节点)
四个节点,其中master、master/slave和slave使用的数据库版本是5.6,cmake2.8.6
【1】MHA-manager、MHA-Node:监控下面三台服务器192.168.60.50
【1】master:192.168.60.70
【2】master/slave:在主服务器不挂的时候是slave,在主服务器挂了之后是master(192.168.60.80)
【3】slave:192.168.60.90
systemctl stop firewalld //关闭防火墙
setenforce 0 //关闭防护中心
操作步骤:
【1】安装MySQL数据库
【2】配置MySQL一主两从
【3】安装MHA软件
【4】配置无密码认证—免密登录
【5】配置MySQL、MHA高可用
【6】模拟master故障切换
//安装依赖环境
yum install -y ncurses-devel gcc-c++ perl-Module-Install
//安装gmake编译软件
tar zxvf cmake-2.8.6.tar.gz
cd cmake-2.8.6
./configure
gmake && gmake install
//安装MySQL数据库
tar zxvf mysql-5.6.36.tar.gz
cd mysql-5.6.36
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DSYSCONFIDIR=/etc
make && make install
//优化数据库配置
cp support-files/my-default.cnf /etc/my.cnf
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
chmod +x /etc/rc.d/init.d/mysqld
chkconfig --add mysqld //开机自启动
//设置环境变量
echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
//创建数据库管理用户
groupadd mysql
useradd -M -s /sbin/nologin mysql -g mysql
chown -R mysql.mysql /usr/local/mysql
mkdir -p /data/mysql
//初始化数据库
/usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--datadir=/usr/local/mysql/data \
--basedir=/usr/local/mysql
//优化启动脚本命令
ln -s /usr/local/mysql/bin/mysql /usr/sbin
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin
//启动mysql服务器命令
/usr/local/mysql/bin/mysqld_safe --user=mysql & //启动mysql服务
vim /etc/my.cnf
[mysqld]
server-id = 70
log_bin = master-bin
log-slave-updates = true
/usr/local/mysql/bin/mysqld_safe --user=mysql & //启动mysql服务
mysql -uroot -p
password:无密码
grant replication slave on *.* to 'myslave'@'192.168.60.%' identified by '123'; //数据库同步权限
grant all privileges on *.* to 'mha'@'192.168.60.%' identified by 'manager';
flush privileges;
此三条按照理论是不用添加的,但是实验会出现报错--两个slave通过主机名连接不上主库master
grant all privileges on *.* to 'mha'@'master' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave01' identified by 'manager';
grant all privileges on *.* to 'mha'@'salve02' identified by 'manager';
flush privileges;
show master status;
master_log_file='master-bin.000002',
master_log_pos=603;
vim /etc/my.cnf
[mysqld]
server-id = 80
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
/usr/local/mysql/bin/mysqld_safe --user=mysql & //启动mysql服务
mysql -uroot -p
password:无密码
grant replication slave on *.* to 'myslave'@'192.168.60.%' identified by '123'; //数据库同步权限
grant all privileges on *.* to 'mha'@'192.168.60.%' identified by 'manager';
flush privileges;
此三条按照理论是不用添加的,但是实验会出现报错--两个slave通过主机名连接不上主库master
grant all privileges on *.* to 'mha'@'master' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave01' identified by 'manager';
grant all privileges on *.* to 'mha'@'salve02' identified by 'manager';
flush privileges;
change master to master_host='192.168.60.70',
master_user='myslave',
master_password='123',
master_log_file='master-bin.000002',
master_log_pos=603;
start slave;
show slave status\G;
set global read only=1; //必须把两个从库设置为全局只读模式
flush privileges;
vim /etc/my.cnf
[mysqld]
server-id = 90
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
/usr/local/mysql/bin/mysqld_safe --user=mysql & //启动mysql服务
mysql -uroot -p
password:无密码
grant replication slave on *.* to 'myslave'@'192.168.60.%' identified by '123'; //数据库同步权限
grant all privileges on *.* to 'mha'@'192.168.60.%' identified by 'manager';
flush privileges;
此三条按照理论是不用添加的,但是实验会出现报错--两个slave通过主机名连接不上主库master
grant all privileges on *.* to 'mha'@'master' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave01' identified by 'manager';
grant all privileges on *.* to 'mha'@'salve02' identified by 'manager';
flush privileges;
change master to master_host='192.168.60.70',
master_user='myslave',
master_password='123',
master_log_file='master-bin.000002',
master_log_pos=603;
start slave;
show slave status\G;
set global read only=1; //必须把两个从库设置为全局只读模式
flush privileges;
//四个节点所有服务器安装MHA依赖环境,首先安装epel源
yum install -y epel-release --nogpgcheck
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \ //管理框架
perl-ExtUtils-CBuilder \ //构建包
perl-ExtUtils-MakeMaker \
perl-CPAN //函数库
//MHA软件包对每个操作系统的版本不一样,centos7.4必须选择0.57版本,
在所有服务器上面必须先安装node组件,最后在MHA-manager节点上安装manager组件,因为manager依赖的是node组件
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install
//在MHA-manager上面安装manager组件
tar zxvf mha4MHA-manager-0.57.tar.gz
cd mhaMHA-manager-0.57
perl Makefile.PL
make && make install
manager安装后再/usr/local/bin下面生成几个工具:
masterha_check_ssh //检查MHA的ssh配置状况
masterha_check_repl //检查MySQL的复制状况
masterha_manager //启动manager的脚本
masterha_check_status //检测当前MHA运行状态
masterha_master_monitor //检测master是否宕机
masterha_master_switch //控制故障转移(自动或手动)
masterha_conf_host //添加或删除配置的server信息
masterha_stop //关闭manager
//node安装后也会在/usr/local/bin下面生成几个脚本(这些工具通常有MHA-Manager的脚本触发,无需人为的操作)
save_binary_logs //保存和复制master的二进制日志
apply_diff_relay_logs //识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog //去除不必要的rollback事件(MHA已经不再使用这个工具)
purge_relay_logs //清除中级日志(不会阻塞SQL线程)
1、在manager上面配置到所有数据库节点的无密码认证
ssh-keygen -t rsa //一路回车
ssh-copy-id 192.168.60.70
ssh-copy-id 192.168.60.80
ssh-copy-id 192.168.60.90
2、在master上面配置到所有数据库节点的无密码认证
ssh-keygen -t rsa //一路回车
ssh-copy-id 192.168.60.80
ssh-copy-id 192.168.60.90
3、在slave01上面配置到所有数据库节点的无密码认证
ssh-keygen -t rsa //一路回车
ssh-copy-id 192.168.60.70
ssh-copy-id 192.168.60.90
4、在slave02上面配置到所有数据库节点的无密码认证
ssh-keygen -t rsa //一路回车
ssh-copy-id 192.168.60.70
ssh-copy-id 192.168.60.80
1、在manager节点上复制相关脚本到/usr/local/bin目录
cp -ra /opt/mha4MHA-manager-0.57/samples/scripts /usr/local/bin
ls /usr/local/bin/scripts
master_ip_failover //自动切换为vip(虚拟IP)管理的脚本
master_ip_online_change //在线切换时vip管理脚本
power_manager //故障发生后关闭主机的脚本
send_report //因故障切换后发送报警的脚本
2、复制自动切换vip管理脚本到/usr/local/bin下面
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
3、删除所有内容,复制下面所有
vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#添加内容部分
my $vip = '192.168.60.254';
my $brdc = '192.168.60.255';
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $exit_code = 0;
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
#
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
4、创建MHA软件目录并拷贝配置文件
mkdir /etc/masterha
cp /opt/mha4MHA-manager-0.57/samples/conf/app1.cnf /etc/masterha
vim /etc/masterha/app1.cnf
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/scripts/master_ip_online_change
ping_interval=1
remote_workdir=/tmp
repl_user=myslave
repl_password=123
report_script=/usr/local/bin/scripts/send_report
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.60.80 -s 192.168.60.90
shutdown_script=""
ssh_user=root
user=mha
password=manager
[server1]
hostname=192.168.60.70
port=3306
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.60.80
port=3306
[server3]
hostname=192.168.60.90
port=3306
masterha_check_ssh -conf=/etc/masterha/app1.cnf
masterha_check_repl -conf=/etc/masterha/app1.cnf
ifconfig ens33:1 192.168.60.200/24
//下面内容是一行输出
nohup masterha_manager --conf=/etc/masterha/app1.cnf
--remove_dead_master_conf
--ignore_last_failover < /dev/null >/var/log/masterha/app1/manager.log 2>&1 &
masterha_check_status --conf=/etc/masterha/app1.cnf
cat /var/log/masterha/app1/manager.log
tailf /var/log/masterha/app1/manager.log //启动监控观察日志记录
pkill -9 mysql //在主服务器master上模拟数据库宕机
ifconfig //查看虚拟IP是否漂移到slave01上面
分析:查看各个节点的配置都是没有问题的,经查找之后发现mysql5.7版本对默认数据库没有test库,而MySQL5.6之前的版本是有默认库test的。
vim /sur/local/amoeba/conf/dbServers.xml
23 mysql //将原有的test修改为mysql
分析:没有生成二进制文件说明配置文件没有生效,但进去之后配置文件是对的,经查找之后发现mysql5.6版本对书写格式有严格要求,“=”前后必须要空格。
server-id = 70
log_bin = master-bin
log-slave-updates = true
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 120 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)