Mysql 高可用
Mysql 高可用
复制
复制是解决系统高可用的常见手段。其思路就是:不要把鸡蛋都放在一个篮子里。
复制解决的基本问题是让一台服务器的数据与其他服务器保持同步。一台主库的数据可以同步到多台备库上,备库本身也可以被配置成另外一台服务器的主库。主库和备库之 间可以有多种不同的组合方式。
MySQL 支持两种复制方式:基于行的复制和基于语句的复制。这两种方式都是通过在主库上记录 bin log、在备库重放日志的方式来实现异步的数据复制。这意味着:复制过程存在时延,这段时间内,主从数据可能不一致。
复制如何工作
在 Mysql 中,复制分为三个步骤,分别由三个线程完成:
- binlog dump 线程 - 主库上有一个特殊的 binlog dump 线程,负责将主服务器上的数据更改写入 binlog 中。
- I/O 线程 - 备库上有一个 I/O 线程,负责从主库上读取 binlog,并写入备库的中继日志(relay log)中。
- SQL 线程 - 备库上有一个 SQL 线程,负责读取中继日志(relay log)并重放其中的 SQL 语句。
这种架构实现了数据备份和数据同步的异步解耦。但这种架构也限制了复制的过程,其中最重要 的一点是在主库上并发运行的查询在备库只能串行化执行,因为只有一个 SQL 线程来重放 中继日志中的事件。
主备配置
假设需要配置一对 Mysql 主备节点,环境如下:
- 主库节点:192.168.8.10
- 备库节点:192.168.8.11
主库上的操作
(1)修改配置并重启
执行 vi /etc/my.cnf
,添加如下配置:
1 | [mysqld] |
server-id
- 服务器 ID 号。在主从架构中,每台机器的 ID 必须唯一。log_bin
- 同步的日志路径及文件名,一定注意这个目录要是 mysql 有权限写入的;
修改后,重启 mysql 使配置生效:
1 | systemctl restart mysql |
(2)创建用于同步的用户
进入 mysql 命令控制台:
1 | $ mysql -u root -p |
执行以下 SQL:
1 | -- a. 创建 slave 用户 |
注意:在 Mysql 8 中,默认密码验证不再是
password
。所以在创建用户时,create user 'username'@'%' identified by 'password';
客户端是无法连接服务的。所以,需要加上IDENTIFIED WITH mysql_native_password BY 'password'
补充用户管理 SQL:
1 | -- 查看所有用户 |
(3)加读锁
为了主库与从库的数据保持一致,我们先为 mysql 加入读锁,使其变为只读。
1 | mysql> FLUSH TABLES WITH READ LOCK; |
(4)查看主库状态
1 | mysql> show master status; |
注意:需要记录下
File
和Position
,后面会用到。
(5)导出 sql
1 | mysqldump -u root -p --all-databases --master-data > dbdump.sql |
(6)解除读锁
1 | mysql> UNLOCK TABLES; |
(7)将 sql 远程传送到备库上
1 | scp dbdump.sql root@192.168.8.11:/home |
备库上的操作
(1)修改配置并重启
执行 vi /etc/my.cnf
,添加如下配置:
1 | [mysqld] |
server-id
- 服务器 ID 号。在主从架构中,每台机器的 ID 必须唯一。log_bin
- 同步的日志路径及文件名,一定注意这个目录要是 mysql 有权限写入的;
修改后,重启 mysql 使配置生效:
1 | systemctl restart mysql |
(2)导入 sql
1 | mysql -u root -p < /home/dbdump.sql |
(3)在备库上建立与主库的连接
进入 mysql 命令控制台:
1 | mysql -u root -p |
执行以下 SQL:
1 | -- 停止备库服务 |
MASTER_LOG_FILE
和MASTER_LOG_POS
参数要分别与show master status
指令获得的File
和Position
属性值对应。MASTER_HOST
是主库的 HOST。MASTER_USER
和MASTER_PASSWORD
是在主节点上注册的用户及密码。
(4)启动 slave 进程
1 | mysql> start slave; |
(5)查看主从同步状态
1 | mysql> show slave status\G; |
说明:如果以下两项参数均为 YES,说明配置正确。
Slave_IO_Running
Slave_SQL_Running
(6)将备库设为只读
1 | mysql> set global read_only=1; |
注:设置 slave 服务器为只读,并不影响主从同步。
复制的原理
读写分离
主服务器用来处理写操作以及实时性要求比较高的读操作,而从服务器用来处理读操作。
读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。
MySQL 读写分离能提高性能的原因在于:
- 主从服务器负责各自的读和写,极大程度缓解了锁的争用;
- 从服务器可以配置 MyISAM 引擎,提升查询性能以及节约系统开销;
- 增加冗余,提高可用性。