mysql 复制基础
一、引入
mysql 服务器性能不够、压力大,如何解决?
一种、纵向扩展,为服务器升级配置(cpu、内存、磁盘)
另一种 则是水平扩展,添加多台服务器共同工作,mysql复制就是解决多台mysql服务器协同工作问题
mysql复制的其他功用
- 数据分布
- 负载均衡读
- 备份
- 高可用和故障切换
- MySQL升级测试
mysql 复制的特点
- 每个节点都有相同的数据集
- 向外扩展
- 二进制日志
- 单向
- 主从复制特点:
- 异步复制
- 主从数据不一致比较常见
二、MySQL复制的模型
-
一主一从
读写分离 -
一主多从
为了解决服务读的压力,但是无法解决写压力大的问题,由于复制(同步数据)过程是串行的,过多的从服务器,会造成主服务器的进程压力大
-
级联复制
解决了一主多从的主服务器压力,但是仍然无法解决写压力大的问题
-
主主复制
可以同时写,但是如果两个服务器同时写入同一个主键的记录时,会产生冲突 ;实际通常通过调度器用来做一主一从,相比较传统的一主一从,当主从发生故障切换时,恢复的时间更短
-
环状复制
主主的变形,一个数据更新了数据,会一级一级的更新,直到所有的数据库都更新完
-
多主一从
实际上是从节点上跑了两个没有业务逻辑关系的数据库,两个主节点上各有一个,本质上仍然是一主一从,从节点上运行mysql的多实例可以达到相同效果。 生产极少这样用
三、mysql 复制解决写压力大的策略
mysql 解决写压力大的方法只有一种,就是分库分表
而分的方式有2种,
垂直分区
这种方式对应业务上没有关系的表,不存在连接关系,把不同的业务上的库表,分开放在不同的机器上
水平分片
若业务上有联系,表与表有连接关系,只能把一张表横向拆开成多个部分,例如按id来拆表,把1-500万行的放在一台机器上,500万行以后放在另外一台机器上,除此外还可以按照id的奇偶数、或者按用户的地区、等级来拆表
分片调度器
因为表在不同的机器上,所以依赖调度器对访问请求进行调度,调度器里有表的索引,按照索引即可查询到记录在哪台机器上
四、mysql 复制原理
简介:
当 master 发生数据更新时,会把更新的数据记录到二进制日志中,master 上会有一个dum线程用于把更新的数据查出发送给slave
slave 上会有一个io Thread 线程来接收mater 发出的数据,并写到中继日志(relay Log)中,然后SQL Thread 线程负责读取relay log 中的日志并且更新到数据库中
主从复制线程:
主节点:
dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其
发送binary log events
MariaDB [hellodb]> show processlist ;
+----+------+---------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+---------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+----------+
| 34 | root | localhost | hellodb | Query | 0 | init | show processlist | 0.000 |
| 35 | r1 | 192.168.1.102:56274 | NULL | Binlog Dump | 65 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL | 0.000 |
+----+------+---------------------+---------+-------------+------+-----------------------------------------------------------------------+------------------+----------+
2 rows in set (0.00 sec)
从节点:
I/O Thread:向Master请求二进制日志事件,并保存于中继日志中
SQL Thread:从中继日志中读取日志事件,在本地完成重放
MariaDB [(none)]> show processlist ;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+----------+
| 42 | root | localhost | NULL | Query | 0 | init | show processlist | 0.000 |
| 43 | system user | | NULL | Connect | 152 | Waiting for master to send event | NULL | 0.000 |
| 44 | system user | | NULL | Connect | 152 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | 0.000 |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+----------+
跟复制功能相关的文件:(chang master to 时生成)
master.info:
用于保存slave连接至master时的相关信息,例如账号、密码、
服务器地址等
relay-log.info:
保存在当前slave节点上已经复制的当前二进制日志和本地 replay log日志的对应关系
五、mysql 主从复制通用配置
5.1主从配置过程:
参看官网
https://mariadb.com/kb/en/library/setting-up-replication/
https://dev.mysql.com/doc/refman/5.5/en/replication-configuration.ht
5.2 主节点配置:
(1) 启用二进制日志
[mysqld]
log_bin
(2) 为当前节点设置一个全局惟一的ID号
[mysqld]
server_id=#
log-basename=master 可选项,设置datadir中日志名称,确保不依赖主机名
(3) 创建有复制权限的用户账号
GRANT REPLICATION SLAVE ON . TO ‘repluser’@‘HOST’ IDENTIFIED BY ‘replpass’;
MariaDB [(none)]> grant replication slave on *.* to 'r1'@'192.168.%' identified by '123';
Query OK, 0 rows affected (0.01 sec)
星点星表示所有库的所有表
5.3从节点配置:
(1) 启动中继日志
[mysqld]
server_id=# 为当前节点设置一个全局惟的ID号
read_only=ON 设置数据库只读
relay_log=relay-log relay log的文件路径,默认值hostname-relay-bin
relay_log_index=relay-log.index 默认值hostname-relay-bin.index
==注意:==relay_only 只是针对普通用户无法复制, root 不存在的
(2) 使用有复制权限的用户账号连接至主服务器,并启动复制线程
语法:
mysql> CHANGE MASTER TO MASTER_HOST=‘host’,
MASTER_USER=‘repluser’,
MASTER_PASSWORD=‘replpass’,
MASTER_LOG_FILE=’ mariadb-bin.xxxxxx’,
MASTER_LOG_POS=#;
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.1.101', MASTER_USER='r1', MASTER_PASSWORD='123', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=313;
此时可以看到slave 的IO 和sql Thread 还没有启动
MariaDB [(none)]> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.1.101
Master_User: r1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 313
Relay_Log_File: mysqld-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
同时生成 下列文件
root@z2:/var/lib/mysql# ll -t
total 110688
drwxr-xr-x 8 mysql mysql 4096 Feb 2 15:52 ./
-rw-rw---- 1 mysql mysql 249 Feb 2 15:52 mysqld-relay-bin.000001
-rw-rw---- 1 mysql mysql 26 Feb 2 15:52 mysqld-relay-bin.index
-rw-rw---- 1 mysql mysql 49 Feb 2 15:52 relay-log.info
-rw-rw---- 1 mysql mysql 150 Feb 2 15:52 master.info
生成中继日志(mysqld-relay-bin.000001)、中继日志目录(mysqld-relay-bin.index 记录了中继日志的位置和个数)、master.info (主服务器的账户信息),relay-log.info
root@z2:/var/lib/mysql# cat relay-log.info
./mysqld-relay-bin.000001
4
mysql-bin.000001
313
relay-log.info内容: 表示的是二进制日志(下面的313)与中继日志(上面的4)位置对应关系
然后开启IO、sql thread。 完成!
MariaDB [(none)]> start slave ;
Query OK, 0 rows affected (0.00 sec)
show processlist ; 可以分别查看复制相关的3个进程详细信息
show slave status \G;可以看到从节点上的两个进程都已启动
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
来源:CSDN
作者:山贼王
链接:https://blog.csdn.net/qq_36801585/article/details/104146069