OS:CentOS 7
master:192.168.189.141
backup:192.168.189.142
vip:192.168.189.143
主主同步
# 下载MySQL安装源
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
# 安装MySQL安装源
yum -y localinstall mysql57-community-release-el7-11.noarch.rpm
# 安装MySQL
yum -y install mysql-community-server
# 启动MySQL并开机启动
systemctl start mysqld && systemctl enable mysqld && systemctl daemon-reload
# 查看密码(这里记录了密码)
# root@localhost: fTY?edpKx7Kt
cat /var/log/mysqld.log
# 登录后修改密码
set global validate_password_policy=LOW;
set global validate_password_length=4;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
flush privileges;
# 开启二进制日志,设置id
vi /etc/my.cnf
[mysqld]
server-id = 1 # backup这台设置2
log-bin = mysql-bin
binlog-ignore-db = mysql,information_schema #忽略写入binlog日志的库
auto-increment-increment = 2 #字段变化增量值
auto-increment-offset = 1 #初始字段ID为1
slave-skip-errors = all #忽略所有复制产生的错误
# 重启MySQL服务
service mysqld restart
先确定 log bin 日志和 pos 值位置:show master status;
master 配置如下:
# 登录MySQL
mysql -uroot -proot
# 创建用户
create user 'replication'@'192.168.189.%' identified by 'replication';
# 赋予权限
grant replication slave on *.* to 'replication'@'192.168.189.%';
# 设置root远程访问(远程连接)
grant all on *.* to 'replication'@'192.168.189.%';
# 刷新生效
flush privileges;
# master 节点(里面是backup节点上的:log bin 日志和 pos 值位置)
change master to master_host='192.168.189.142', master_user='replication', master_password='replication', master_log_file='mysql-bin.000001', master_log_pos=909;
# backup节点(里面是master节点上的:log bin 日志和 pos 值位置)
change master to master_host='192.168.189.141', master_user='replication', master_password='replication', master_log_file='mysql-bin.000006', master_log_pos=91;
# 启动同步
start slave;
# 查看同步状态
# 主动节点,都关闭防火墙
show slave status\G;
主主同步配置完毕,查看同步状态
Slave_IO 和 Slave_SQL 是 YES 说明主主同步成功
在 master 插入数据测试下:
在 backup 查看是否同步成功:
可以看到已经成功同步过去,同样在 backup 插入到 user 表数据,一样同步过去,双主就做成功了。
keepalived 热备
双主
# 安装依赖包
yum install -y pcre-devel openssl-devel popt-devel
# 下载keepalived
wget http://www.keepalived.org/software/keepalived-1.2.7.tar.gz
# 解压
tar zxvf keepalived-1.2.7.tar.gz && cd keepalived-1.2.7
# 安装
./configure --prefix=/usr/local/keepalived && make && make install
# 将 keepalived 配置成系统服务
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
主
# vi /etc/keepalived/keepalived.conf
! Configuration File forkeepalived
global_defs {
notification_email {
test@sina.com
}
notification_email_from admin@test.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MYSQL_HA # 标识,双主相同
}
vrrp_instance VI_1 {
state BACKUP # 两台都设置BACKUP
interface ens33 # 这里根据网卡设置
virtual_router_id 51 # 主备相同
priority 100 # 优先级,backup设置90
advert_int 1
nopreempt # 不主动抢占资源,只在master这台优先级高的设置,backup不设置
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.189.143
}
}
virtual_server 192.168.189.143 3306 {
delay_loop 2
# lb_algo rr # LVS算法,用不到,我们就关闭了
# lb_kind DR # LVS模式,如果不关闭,备用服务器不能通过VIP连接主MySQL
persistence_timeout 50 # 同一IP的连接60秒内被分配到同一台真实服务器
protocol TCP
real_server 192.168.189.141 3306 { # 检测本地mysql,backup也要写检测本地mysql
weight 3
notify_down /usr/local/keepalived/mysql.sh # 当mysq服down时,执行此脚本,杀死keepalived实现切换
TCP_CHECK {
connect_timeout 3 # 连接超时
nb_get_retry 3 # 重试次数
delay_before_retry 3 # 重试间隔时间
}
}
# 查看keepalived日志
tail -f /var/log/messages
# vi /usr/local/keepalived/mysql.sh
#!/bin/bash
pkill keepalived
chmod +x /usr/local/keepalived/mysql.sh
/etc/init.d/keepalived start
备
- backup 服务器只修改一部分:
- priority 90
- 注释nopreempt
- real_server 设置本机 IP
测试高可用
- 通过 Mysql 客户端通过 VIP 连接,看是否连接成功
- 停止 master 这台 mysql 服务,是否能正常切换过去,可通过 ip addr 命令来查看 VIP 在哪台服务器上
- 可通过查看 /var/log/messges 日志,看出主备切换过程
- master 服务器故障恢复后,是否主动抢占资源,成为活动服务器
备份数据库
Crontab
crontab -l
:查看已存在的定时任务crontab -e
:编辑定时任务,cat /var/spool/cron/root
同样效果
# 每分钟执行一遍备份
cat > /var/spool/cron/root << EOF
* * * * * /root/data/sql_back_file/sql-back.sh root
EOF
# 这里的 $1 :接收外部参数,也就是SQL登录密码
# 使用时间戳作为文件名
mysqldump -uroot -p$1 sql_test > /root/data/sql_back_file/`date +%Y-%m-%d_%H-%M-%S_epgn.sql`
# 查看定时任务
crontab -e
>> * * * * * /root/data/sql_back_file/sql-back.sh root
mysqldump
mysqldump | mysqlhotcopy | |
---|---|---|
备份方式 | 停机备份 |
热备份 |
操作方式 | 一个数据库端的 SQL 语句集合 | 快速文件意义上的 COPY |
执行位置 | 可以用在远程客户端 | 只能运行在数据库目录所在的机器上 |
执行方式 | 在线执行 | 在线执行 |
恢复方式 | 导入SQL文件 | COPY 备份文件到源目录覆盖 |
针对引擎 | InnoDB |
MyISAM |
因为备份针对的存储引擎不同,这里也简单介绍下两种存储引擎的区别
InnoDB
- 支持事务处理等
- 不加锁读取
- 支持外键
- 支持行锁
- 不支持 FULLTEXT 类型的索引
- 不保存表的具体行数,扫描表来计算有多少行
- DELETE 表时,是一行一行的删除
- InnoDB 把数据和索引存放在表空间里面
- 跨平台可直接拷贝使用
- InnoDB 中必须包含 AUTO_INCREMENT 类型字段的索引
- 表格很难被压缩
MyISAM
- 不支持事务,回滚将造成不完全回滚,不具有原子性
- 不支持外键
- 支持全文搜索
- 保存表的具体行数,不带 where 时,直接返回保存的行数
- DELETE 表时,先 drop 表,然后重建表
- MyISAM 表被存放在三个文件
- frm:存放表格定义
- MYD:数据文件(MYData)
- MYI:索引文件(MYIndex)
- 跨平台很难直接拷贝
- MyISAM 中可以使 AUTO_INCREMENT 类型字段建立联合索引
- 表格可以被压缩
区别
区别 | InnoDB | MyISAM |
---|---|---|
事务处理 | 事务安全(支持事务处理等高级处理) | 非事务安全 |
锁粒度 | 行级锁 | 表级锁 |
CRUD | 执行大量的 INSERT 或 UPDATE(性能) | 执行大量的 SELECT |
查询表行数 | 不保存表的具体行数,查询count时扫描 | 读出保存好的行数(包含 where 时,两表操作相同) |
外键 | 支持 | 不支持 |
查询速度 | 慢6~7倍 | 快 |
全文索引 | 支持 | 不支持 |
应用场景 | 1、可靠性要求比较高,或者要求事务 2、频繁update/select,较大机会行锁定 |
1、很多 count 的计算 2、插入不频繁,查询非常频繁 3、没有事务 |
为什么 MyISAM 会比 InnoDB 的查询速度快?
InnoDB 在做 select 的时候,要维护的东西比 MyISAM 引擎多很多:
- 数据块,InnoDB 要缓存,MyISAM 只缓存索引块, 这中间还有换进换出的减少
- InnoDB 寻址要映射到块,再到行,MyISAM 记录的直接是文件的 OFFSET,定位比 InnoDB 要快
- InnoDB 还需要维护 MVCC 一致;虽然你的场景没有,但他还是需要去检查和维护
参考:MySQL高可用性之 Keepalived+Mysql(双主热备)
评论区