跳至主要內容

MySQL的高可用

知识库数据库MySQLMySQL大约 4 分钟

基于 binlog 的主从同步

主 master : 192.16.18.101 : MySQL5.7
从 slave : 192.16.18.102 : MySQL5.7
关闭防火墙:systemctl stop iptables && systemctl stop firewalld && systemctl disable firewalld.service

主 master 的配置文件 my.conf
[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
# 0:大小写敏感 1:大小写不敏感
lower_case_table_names=1
character-set-server=utf8
default-time_zone = '+8:00'
# 服务器ID,注意要唯一
server-id=101
# 启动二进制文件(主机需要打开),这个mysql-bin 可自定义,也可加上路径
log-bin=mysql-bin
# binlog刷盘策略
sync_binlog=1
# 需要备份的数据库
binlog-do-db=hello
# 不需要备份的数据库(多个写多行)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
# 主从复制的格式(mixed|statement|row),默认格式是statement
binlog_format=statement
# 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
# 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。1062错误是指一些主键重复
slave_skip_errors=1062

[client]
port=3306
user=root
password=123456
default-character-set=utf8











 

 




















:::

从 slave 的配置文件 my.conf
[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
# 0:大小写敏感 1:大小写不敏感
lower_case_table_names=1
character-set-server=utf8
default-time_zone = '+8:00'
# 服务器ID,注意要唯一
server-id=102
[client]
port=3306
user=root
password=123456
default-character-set=utf8











 





-- 主master
-- 设置密码长度最低位数
set global validate_password_length=4;
-- 设置密码强度级别
set global validate_password_policy=0;
-- 主节点,创建用户`rep1`并授权用户
GRANT REPLICATION SLAVE ON *.* to 'rep1'@'192.16.18.102' identified by '123456';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查看binlog的日志模式,binlog的三种格式:·STATEMENT· 、·ROW· 、·MIXED·
show variables like 'binlog_format';
-- 设置binlog的日志模式为·STATEMENT·
--set binlog_format=STATEMENT;
-- 查看master节点状态
show master status;

-- 从slave
-- 同步master节点,master_log_file和master_log_pos为master执行`show master status`的结果。
change master to master_host='192.16.18.101', master_port=3306, master_user='rep1', master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=2157, MASTER_AUTO_POSITION=0;
-- 启动从服务器复制功能
start slave;
-- 停止从服务器复制功能
stop slave;
-- 检查从服务器复制功能状态
show slave status \G;
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes     两个都为·Yes·表示同步成功。
-- Seconds_Behind_Master: 0   判断主从延迟,0是正常,NULL表示io_thread或是sql_thread有一个发生故障
# 查看bin log和relay log日志
mysqlbinlog --base64-output=decode-rows -v -v mysql-bin.000058 > binlog

Atlas 读写分离

官方文档:https://github.com/Qihoo360/Atlas/blob/master/README_ZH.mdopen in new window

# 下载安装
wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas- 2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
# 安装好了,它会默认在”/usr/local/mysql-proxy”下给你生成4个文件夹,以及需要配置的文件 bin|conf|lib|log

# 进入bin目录,使用encrypt来对数据库的密码进行加密
cd /usr/local/mysql-proxy/bin && ./encrypt root
# 配置Atlas,使用vim进行编辑,配置如下
vi /usr/local/mysql-proxy/conf/test.cnf
# 登录到Atlas的管理员的账号与密码
admin-username = admin
admin-password = admin
# 配置主数据的地址与从数据库的地址
# Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.16.18.101:3306
# Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默 认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 192.16.18.101:3306@1,192.16.18.102:3306@2
# 配置密码,密码为上面`./encrypt root`的结果
pwds = root:DAJnl8cVzy8=
# Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234
# Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345

# 启动Atlas
./mysql-proxyd test start
# 进入管理模式,则说明Atlas正常运行
mysql -h127.0.0.1 -P2345 -uroot -p123456
# 查看MySQL管理员模式都能做些什么
select * from help;

# 读写分离的测试
mysql -h127.0.0.1 -uroot -p123456 -P1234 --protocol=tcp -e"select @@hostname

双节点主从 + keepalived/heartbeat 方案

这种架构是最省事。利用 keepalived/heartbeat 的高可用机制实现快速切换到 slave 节点。

需要注意一下:

  • 自增 ID 的冲突。
  • slave 节点服务器配置不要太差,否则更容易导致复制延迟。
  • keepalived 的检测机制需要适当完善。
  • keepalived 最终确定进行切换时,还需要判断 slave 的延迟程度。
  • keepalived 或 heartbeat 自身都无法解决脑裂的问题。

docker 启动 master 数据库

docker run -p 3316:3306 --name mysql-master \
-v /Users/edz/data/mysql/master/log:/var/log/mysql \
-v /Users/edz/data/mysql/master/data:/var/lib/mysql \
-v /Users/edz/data/mysql/master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7

docker 启动从节点数据库

docker run -p 3326:3306 --name mysql-slave-01 \
-v /Users/edz/data/mysql/slave01/log:/var/log/mysql \
-v /Users/edz/data/mysql/slave01/data:/var/lib/mysql \
-v /Users/edz/data/mysql/slave01/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7

docker run -p 3336:3306 --name mysql-slave-02 \
-v /Users/edz/data/mysql/slave02/log:/var/log/mysql \
-v /Users/edz/data/mysql/slave02/data:/var/lib/mysql \
-v /Users/edz/data/mysql/slave02/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7

MySQL 主从复制操作

## master中操作
docker exec -it master mysql -uroot -p123456
## 开放root访问权限
SELECT host, user FROM mysql.user;
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
## 刷新权限
flush privileges;
## 创建用户
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';
## 查看主节点的状态,其中File 列需要记录下来:
SHOW MASTER STATUS;


## slave中操作
docker exec -it mysql-slave-01 mysql -uroot -p123456
## 开放root访问权限
SELECT host, user FROM mysql.user;
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
## 刷新权限
flush privileges;
## slave中指向master 注意这里的 bedrock-db-master.bedrock-cloud 和 mysql-bin.000003 ,都是上面主节点中的:
CHANGE MASTER TO MASTER_HOST='bedrock-db-master.bedrock-cloud',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=0,MASTER_PORT=3306;
## 开始同步
start slave;
## 查看同步的状态: Slave_IO_Running: Yes Slave_SQL_Running: Yes 即可
show slave status\G;