随着系统中业务访问量的增大,如果是单机部署服务器,就会导致 I/O 访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单个机器的 I/O 性能。
MySQL Replication (MySQL 主从复制) 是什么?为什么要主从复制以及它的实现原理是什么?
mysql主从复制是指数据可以从一个mysql数据库服务器主节点复制到一个或多个从节点。mysql默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制 主数据库中的所有数据库或者特定的数据库,或者特定的表。
主要用途:
1.
读写分离
在开发工作中,有时候会遇到某个sql语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。2.数据实时备份,当系统中的某个节点发生故障时,可以方便的故障切换
3.高可用HA
4.架构扩展
MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:
- 主节点 binary log dump 线程 当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁, 当读取完成,甚至在发动给从节点之前,锁会被释放。
- 从节点I/O线程 当从节点上执行
start slave
命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
- 从节点SQL线程 SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都 有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执 行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如, 如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进 程已经从主节 点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。
主从复制的步骤:
- 主库将所有的写操作记录在binlog日志中,并生成log dump线程,将binlog日志传给从库的I/O线程
- 从库生成两个线程,一个是I/O线程,另一个是SQL线程
- I/O线程去请求主库的binlog日志,并将binlog日志中的文件写入relay log(中继日志)中
- SQL线程会读取relay loy中的内容,并解析成具体的操作,来实现主从的操作一致,达到最终数据一致的目的
配置主从的步骤
- 确保从数据库与主数据库里的数据一致
- 在主数据库里创建一个同步账户授权给从数据库使用
- 配置主数据库(修改配置文件)与开启binlog日志
mysql8.0新加了很多功能,其中在用户管理中增加了角色的管理,默认的密码加密方式也做了调整,由之前的sha1
改为sha2
,同事加上5.7的禁用用户和用户过期的设置,这样方便用户的管理和权限的管理,也增加了用户的安全性
。
验证插件和密码加密方式的变化在mysq8.0中,caching_sha2_password是默认的身份验证插件而不是之前版本的mysql_native_password,默认的密码加密方式是sha2。
如果需要保持之前的验证方式并保持之前版本的密码加密方式需要在配置文件中修改,暂不支持动态修改,需要重启生效。
default_authentication_plugin = mysql_native_password
将8.0已有的sha2密码修改为sha1的模式:
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY 'passowrd' PASSWORD EXPIRE NEVER;
#修改加密规则为永不过期
ALTER USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'password';
#更新一下用户的密码加密方式为之前版本的方式
FLUSH PRIVILEGES; #刷新权限
MySQL8.0的用户授权和之前有所区别,老版本的常用授权语句在8.0中会报错:
--MySQL8.0之前版本:
GRANT ALL ON *.* TO `root`@`127.0.0.1` IDENTIFIED BY 'passowrd' WITH GRANT OPTION;
--MySQL8.0版本:
--创建账号密码
CREATE USER `root`@`127.0.0.1` IDENTIFIED BY 'passowrd';
--授予权限
GRANT ALL ON *.* TO `root`@`127.0.0.1` WITH GRANT OPTION;
--删除权限
REVOKE all privileges ON databasename.tablename FROM 'username'@'host';
--修改密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
要全局建立自动密码到期策略,请使用default_password_lifetime系统变量。其默认值为0,禁用自动密码过期。如果值default_password_lifetime正整数N,则表示
允许的密码生存期,以便密码必须每天更改N。可以加在配置文件中:
1:要建立全局策略,密码的使用期限大约为六个月,请在服务器my.cnf文件中使用以下行启动服务器:
[mysqld]
default_password_lifetime=180
2:要建立全局策略,以便密码永不过期,请将其设置default_password_lifetime为0:
[mysqld]
default_password_lifetime=0
这个参数是可以动态设置并保存的:
SET PERSIST default_password_lifetime = 180;
SET PERSIST default_password_lifetime = 0;
创建和修改带有密码过期的用户,帐户特定的到期时间设置示例:
要求每90天更换密码:
CREATE USER 'root'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
ALTER USER 'root'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
禁用密码过期:
CREATE USER ' wangwei'@'localhost' PASSWORD EXPIRE NEVER;
ALTER USER 'wangwei'@'localhost' PASSWORD EXPIRE NEVER;
遵循全局到期政策:
CREATE USER 'wangwei'@'localhost' PASSWORD EXPIRE DEFAULT;
ALTER USER 'wangwei'@'localhost' PASSWORD EXPIRE DEFAULT;
MySQL用户密码重用策略设置
MySQL允许限制重复使用以前的密码。可以根据密码更改次数、已用时间或两者来建立重用限制。帐户的密码历史由过去分配的密码组成。MySQL可以限制从
此历史记录中选择新密码:
注意:空密码不记录在密码历史记录中,并随时可以重复使用。
要全局建立密码重用策略,请使用password_history和password_reuse_interval系统变量。要在服务器启动时指定变量值,请在服务器my.cnf文件中定义它们。
示例:
[mysqld]
password_history=6password_reuse_interval=365
要动态设置和保存配置,请使用如下所示的语句:
SET PERSIST password_history = 6;
SET PERSIST password_reuse_interval = 365;
3.MySQL8.0的角色管理
MySQL角色是指定的权限集合。像用户帐户一样,角色可以拥有授予和撤消的权限。可以授予用户帐户角色,授予该帐户与每个角色相关的权限。用户被授予角色权限,则该用户拥有该角色的权限。
以下列表总结了MySQL提供的角色管理功能:
CREATE ROLE并 DROP ROLE角色创建和删除;
GRANT并 REVOKE为用户和角色分配和撤销权限;
SHOW GRANTS 显示用户和角色的权限和角色分配;
SET DEFAULT ROLE 指定哪些帐户角色默认处于活动状态;
SET ROLE 更改当前会话中的活动角色。
CURRENT_ROLE()功能显示当前会话中的活动角色。
单Mysql问题:
1.性能问题
2.数据备份问题
多MySql好处
1.性能问题--不一定提高
2.数据冗余
Mysql支持一台主服务器同时向多台服务器进行复制操作,从服务器同时可以作为其他从服务器的主服务器,如果mysql主服务器访问量比较大,可以通过复制数据,然后在从服务器上进行查询操作
,从而降低主服务器的访问压力,同时从服务器作为主服务器的备份,可以避免主服务器因为故障数据丢失的问题。
MySql数据库复制操作大致可以分成三个步骤:
1.主服务器将数据的改变记录到二进制日志(binary log)中。
2.从服务器将主服务器的 binary log events 复制到它的中继日志(relay log)中。
3.从服务器重做中继日志的时间,将数据的改变与从服务器保持同步。
首先,主服务器会记录二进制日志,每个实务更新数据完成之前,主服务器将这些操作的信息记录在二进制日志里面在事件写入二进制日志完成后主服务器通知存储引擎提交事务。
准备:了解 binlog 日志,mysql用户 - 权限
mysql服务器配置复制不难,但是因为场景不同可能会存在一定的差异化,总的来说分为以下几步:
1.在服务器上创建复制账号
2.通知备库连接到主库并从主库复制数据
准备服务器:
角色 | Ip | 操作系统 | mysql版本 | 端口 | 复制账号 | 密码 |
---|---|---|---|---|---|---|
主Master | 192.168.81.132 | CentOS7.6.1810 | mysql8.0.19 | 3306 | slave | slave |
从slave1 | 192.168.81.132 | CentOS7.6.1810 | mysql8.0.19 | 3306 | … | … |
从slave2 | 192.168.81.132 | CentOS7.6.1810 | mysql8.0.19 | 3306 | … | … |
对于主从复制,在本质上就是通过与从数据库复制主服务器的binlog日志文件,通过重做实现的同步;但是一定要注意尽量保证主从服务器上安装了相同的版本的数据库,设定主从的服务器ip地址为是192.168.81.140,192.168.81.141。然后在主服务器上设置一个复制使用的账号,并赋予replication slave权限。我们可以根据ip创建账号为slave
创建账号sql:
create user 'username'@'localhost' identified by 'password';
授权grant [权限] on *.* to 'username'@'localhost' identified by 'password';
*/ mysql> CREATE USER 'slave'@'192.168.81.%' IDENTIFIED WITH mysql_native_password BY 'slave'; Query OK, 0 rows affected (0.04 sec)
mysql> select user,host from mysql.user;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.81.%'; Query OK, 0 rows affected, 1 warning (0.00 sec)
对于mysql的主从复制来说最重要的主要就是binlog日志,所以我们就需要开启binlog日志,并设置server-id的值。需要重启服务器之后才生效二进制日志,也就说我们常说的binlog。
二进制日志记录了MySql所有修改数据库的操作,然后以二进制的形式记录日志在日志文件中,其中还包括没调语句所执行的时间和消耗的资源,以及相关的事务信息。默认情况下二进制日志功能是没有开启的,启动可以配置log-bin[=file_name]开启。
mysql> show global variables like '%log_bin%';
作用就是
1.增量备份(不是所有数据备份,而是最近的写操作)
2.用于mysql主从复制
[root@localhost panel]# vi /etc/my.cnf
主要就是下配置文件中添加如下配置
[mysqld]
log-bin=mysql-bin
server-id=1
注意:对于使用虚拟机的同学 – 注意克隆之后的系统你需要稍稍修改一下系统的ip地址
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=192.168.153.131
NETMASK=255.255.255.0
GATEWAY=192.168.153.2
[root@localhost ~]# systemctl restart network
在进行配置之前,回顾一下过程
要先明确配置的架构Master-slave
1. 配置主节点
1.1 配置账号
1.2 开启binlog日志
2 .配置从节点
2.1 配置同步日志
2.2 指定主节点的ip,端口,用户...
2.3 启动从节点
修改配置
[root@localhost ~]# find / -name my.cnf
[root@localhost ~]# vi /etc/my.cnf
[root@localhost ~]# find / -name mysqld /etc/rc.d/init.d/mysqld /www/server/mysql/bin/mysqld
[root@localhost ~]# /etc/rc.d/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
在配置文件中添加
#配置从节点
server-id = 2
relay_log = /usr/local/mysql/data/mysql-relay-bin
relay_log-index = /usr/local/mysql/data/mysql-relay-bin.index
log_slave_updates = 1
read_only = 1
查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;
参数介绍:
1. server_id:这是服务id系统会自动命名的, 可以将你主库和备库上的log-bin设置相同的值。
2. relay-log:指定 中继日志的位置和命名
指定主节点的ip,端口,用户
mysql> change master to master_host='192.168.81.132',master_port=3306,master_user='slave',master_password='slave',master_log_file='mysql-bin.000002',master_log_pos=155;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
启动从节点
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status \G;
对于我们来说其中的信息主要是关注
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
reset slave all 清楚slave信息 测试的方法就是在主服务器中,添加一些数据测试观察从服务器中的数据变化情况。
systemctl status firewalld -- 查看防火墙状态
systemctl stop firewalld -- 关闭防火墙
./mysql.server restart
mysql 5.6的复制引入了uuid的概念,各个复制结构中的server_uuid得保证不一样,但是查看到直接copy data文件夹后server_uuid是相同的,show variables like ‘%server_uuid%’;
解决方法:
find / -name auto.cnf
找到data文件夹下的auto.cnf文件,修改里面的uuid值,保证各个db的uuid不一样,重启db即可
reset slave;