MySQL 主从复制、读写分离理论分析+实战演示


引言

在企业应用中,成熟的业务通常数据量都比较庞大,如果对 MySQL 数据库的读和写都在一台数据库服务器上操作,无论是在安全性、高可用性,还是高并发等各个方面都是不能满足实际需求的。因此,一般来说都是通过主从复制(Master-Slave)的方式来同步数据,再通过读写分离来提升数据库的并发负载能力这样的方案进行部署与实施。


一、主从复制

1. 原理

MySQL 的主从复制和 MySQL 的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复制完成了,才能在此基础上进行数据的读写分离。

  • 主从复制的核心:2个日志、3个线程

master 线程:bin log 二进制日志、dump 线程
master 上的 dump 线程会监控 bin log 二进制日志的更新,若有更新会通知 slave的 I/O 线程

slave:relay log 中继日志、I/O 线程、SQL 线程
线程1:
slave上的 I/O 线程会向 master 申请同步 bin log 二进制日志的更新内容,slave的 I/O 线程把更新内容写入自己的中继日志
线程2:
slave 的 SQL 线程把日志中的更新语句同步执行到内容,以达到和 master 数据库趋于一致

2. 支持的复制类型

  • STATEMENT:基于语句的复制,在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句;MySQL 默认采用基于语句的复制,效率比较高
  • ROW:基于行的复制,把改变的内容复制过去,而不是把命令在从服务器上执行一遍
  • MIXED:混合类型的复制,默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制

3. 复制的工作过程

  ① 在每个事务更新数据完成之前,Master 都会在二进制日志记录这些改变;写入二进制日志完成后,Master 通知存储引擎提交事务;
  ② Slave 将 Master 的 Binary log 复制到其中继日志
首先,Slave 开始一个工作线程——I/O 线程,I/O 线程在 Master 上打开一个普通的连接,然后开始 Binlog dump process;Binlog dump process 从 Master 的二进制日志中读取时间,如果已经跟上 Master,它会睡眠并等待Master 产生新的时间;I/O 线程将做这些事件写入中继日志;
  ③ SQL slave thread(SQL 从线程)处理该过程的最后一步
SQL 线程从中继日志读取事件,并重放其中的事件而更新 Slave 的数据,使其与 Master 中的数据一致;只要该线程与 I/O 线程保持一致,中继日志通常会位于 OS 的缓存中,所以中继日志的开销很小;
  ④ 复制过程有一个很重要的限制,即复制在 Slave 上是串行化的,也就是说 Master 上的并行更新操作不能在 Slave 上并行操作。

在这里插入图片描述

4. MySQL主从复制延迟

  • master 服务器高并发,形成大量事务
  • 网络延迟
  • 主从硬件设备导致:cpu主频、内存io、硬盘io
  • 本来就不是同步复制、而是异步复制
  • 从库优化 Mysql 参数,比如增大 innodb_buffer_pool_size,让更多操作在 Mysql 内存中完成,减少磁盘操作。
  • 从库使用高性能主机,包括 cpu 强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了I/O方面性能。
  • 从库使用SSD磁盘
  • 网络优化,避免跨机房实现同步

二、读写分离

1. 原理

  • 读写分离就是只在主服务器上写,只在从服务器上读
  • 基本的原理是让主数据库处理事务性查询,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库

为什么要读写分离呢?
因为数据库写 10000 条数据可能要 3 分钟,操作比较耗时,但是数据库读 10000 条数据可能只要5秒钟,所以读写分离,解决的是,数据库的写入,影响了查询的效率。

  • 读写分离的过程如下图所示
    在这里插入图片描述

2. 读写分离作用

  • 数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。
  • 利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能

3. 实现方式

  • 读写分离分为以下两种∶

3.1 基于程序代码内部实现

  • 在代码中根据 select、insert,进行路由分类,这类方法也是目前生产环境应用最广泛的。
  • 优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支; 缺点是需要开发人员来实现,运维人员无从下手。
  • 但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的 Java 应用,如果在程序代码中实现读写分离对代码改动就较大。

3.2 基于中间代理层实现

代理一般位于客户端和服务器之间, 代理服务器接到客户端请求后通过判断后转发到后端数据库, 有以下代表性程序:

  • MySQL-Proxy :MySQL-Proxy 为 MySOL开源项目, 通过其自带的 lua 脚本进行SOL 判断。
  • Atlas:是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy0.8.2版本的基础上,对其进行了优化, 增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以 及存储过程。
  • Amoeba:由陈思儒开发,作者曾就职于阿里巴巴。该程序由Jaya语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

由于使用 MySQL Proxy 需要写大量的 Lua 脚本,这些 Lua 并不是现成的,而是需要自己去写。这对于并不熟悉 MySQL Proxy 内置变量和 MySQL Protocol 的人来说是非常困难的。
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。

三、MySQL 主从复制架构搭建

1. 服务器配置

主机名操作系统IP地址所需软件
MasterCentOS 7192.168.8.14mysql-5.7
AmoebaCentOS 7192.168.8.17jdk1.6、Amoeba
Slave1CentOS 7192.168.8.16mysql-5.7
Slave2CentOS 7192.168.8.15mysql-5.7
client端CentOS 7192.168.8.13mysql5.7

2. 环境准备

#关闭防火墙与安全增强系统
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
setenforce: SELinux is disabled

3. mysql 主从服务器时间同步

  • 主服务器:192.168.8.14
[root@master ~]#yum install -y ntp
[root@master ~]#vim /etc/ntp.conf 							#尾行加入下面内容

server 127.127.8.0											#设置本地是时钟源,注意修改自己的网段
fudge 127.127.8.0 stratum 8									#设置时间层级为 8(限制在 15 内)
[root@master ~]#systemctl start ntpd
  • slave1 :192.168.8.16
[root@slave1 ~]#yum install -y ntp ntpdate
[root@slave1 ~]#systemctl start ntpd 
[root@slave1 ~]#/usr/sbin/ntpdate 192.168.8.14				#时间同步
 1 Nov 11:16:58 ntpdate[31306]: the NTP socket is in use, exiting

[root@slave1 ~]#crontab -e									#设置计划任务

*/30 * * * * /usr/sbin/ntpdate 192.168.8.14
  • slave2 :192.168.8.15
[root@slave2 ~]#yum install -y ntp ntpdate
[root@slave2 ~]#service ntpd start
[root@slave2 ~]#crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.8.14

4. 主服务器的 mysql 配置

[root@master ~]#vim /etc/my.cnf
#添加下面配置
server-id = 1								#定义 server-id,每台主机不可相同
log-bin=master-bin							#主服务器开启二进制日志
binlog_format = MIXED						#本次使用 MIXED 模式
log-slave-updates=true						#允许从服务器更新二进制日志

#注意:default-character-set=utf8 这个需要注释掉,不然会报错


systemctl restart mysqld.service 			#重启服务

#设置从服务器账号并授权
mysql -uroot -p123456

#给从服务器授权
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.8.%' IDENTIFIED BY '123456';
mysql> flush privileges;
mysql> use mysql;
mysql> select user,host,authentication_string from user;
+-----------+-------------+-------------------------------------------+
| user      | host        | authentication_string                     |
+-----------+-------------+-------------------------------------------+
| root      | localhost   | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| mysql.sys | localhost   | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| myslave   | 192.168.8.% | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+-----------+-------------+-------------------------------------------+
3 rows in set (0.00 sec)

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      862 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#File 列显示日志名,Position 列显示偏移量

5. 从服务器的 mysql 配置

5.1 slave1 配置

vim /etc/my.cnf
server-id = 2								#注意 id 与其他主机都不能相同
relay-log=relay-log-bin						#开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index		#定义中继日志文件的位置和名称
relay_log_recovery = 1                  	#选配项

#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,
并且重新从 master 上获取日志,这样就保证了relay-log 的完整性。
默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启。

systemctl restart mysqld

[root@slave1 ~]#mysql -uroot -p123456

#配置同步,注意 master_log_file 和 master_log_pos 的值要与 Master 查询的一致
mysql> CHANGE master to master_host='192.168.8.14',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;

mysql> start slave;							#启动同步,如有报错执行 reset slave;
mysql> show slave status\G;					#查看 Slave 状态,确保 IO 和 SQL 线程都是 Yes,代表同步正常


在这里插入图片描述

5.2 slave2 配置

vim /etc/my.cnf

server-id = 3										#注意不能和 master 、slave1 相同         
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery = 1

systemctl restart mysqld

[root@slave2 ~]#mysql -uroot -p123456
mysql> CHANGE master to master_host='192.168.8.14',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;

mysql> start slave;
mysql> show slave status\G;

在这里插入图片描述

5.3 一般 Slave_IO_Running: No 的可能性

  • 网络不通
  • my.cnf 配置有问题
  • 密码、file 文件名、pos 偏移量不对
  • 防火墙没有关闭

6. 验证主从复制

#主服务器
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
| test1              |
+--------------------+
6 rows in set (0.00 sec)

mysql> create database test;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
7 rows in set (0.00 sec)
#slave1
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
-----------------------------------------------------------------------------------------------
#slave2
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

四、MySQL 读写分离架构搭建

1. amoeba 服务器安装配置

  • 安装Java 环境

因为 amoeba 是基于 jdk1.5 开发的,所以官方推荐使用 jdk1.5 或 1.6 版本,高版本不建议使用。

[root@localhost ~]#cd /opt/ 
[root@localhost /opt]#ls
amoeba-mysql-binary-2.2.0.tar.gz  jdk-6u14-linux-x64.bin  rh

cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local/
chmod +x jdk-6u14-linux-x64.bin
./jdk-6u14-linux-x64.bin
#按住Enter,提示输入YES等待完成并回车

mv jdk1.6.0_14/ /usr/local/jdk1.6	
						
#编辑全局配置文件,在最后一行添加以下配置
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin

#输出定义Java的工作目录
#输出指定的java类型
#将java加入路径环境变量
#输出定义amoeba工作目录
#加入路径环境变量

[root@localhost /usr/local]#source /etc/profile				#执行修改后的全局配置文件
[root@localhost /usr/local]#java -version					#查看java版本信息以检查是否安装成功
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
  • 安装 Amoeba
[root@localhost /usr/local]#mkdir /usr/local/amoeba
[root@localhost /usr/local]#tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@localhost /usr/local]#chmod -R 755 /usr/local/amoeba/			#为目录赋予权限
[root@localhost /usr/local]#/usr/local/amoeba/bin/amoeba			#开启amoeba
amoeba start|stop													#提示stop说明安装成功

2. 配置 amoeba 读写分离,两个 slave 读负载均衡

  • 在master、slave1、slave2 的 mysql上开放权限给 amoeba 访问
mysql> grant all on *.* to test@'192.168.8.%' identified by '123456';
mysql> select user,host,authentication_string from mysql.user;
  • amoeba 服务器配置 amoeba 服务
#先备份
cd /usr/local/amoeba/conf/
cp amoeba.xml amoeba.xml.bak
cp dbServers.xml dbServers.xml.bak
vim /usr/local/amoeba/conf/amoeba.xml		#修改 amoeba 配置文件
#--30--
<property name="user">amoeba</property>
#--32-- 
<property name="password">123456</property>
#--115--
<property name="defaultPool">master</property>
#--117-120行,取消注释并修改
<property name="writePool">master</property>
<property name="readPool">slaves</property>
......
-------------------------------------------------------------------------------------------
vim /usr/local/amoeba/conf/dbServers.xml	#修改数据库配置文件
#--23--注释掉  作用:默认进入 test 库,以防 mysql 中没有 test 库时会报错
<!-- <property name="schema">test</property> -->
#--26--修改,使用之前创建的授权用户
<property name="user">test</property>
#--29--去掉注释,密码为之前创建的授权用户密码
<property name="password">123456</property>
#--45--修改,设置主服务器的名 master
<dbServer name="master"  parent="abstractServer">
#--48--修改,设置主服务器的地址
<property name="ipAddress">192.168.10.20</property>
#--52--修改,设置从服务器的名 slave1
<dbServer name="slave1"  parent="abstractServer">
#--55--修改,设置从服务器1的地址
<property name="ipAddress">192.168.10.30</property>
#--58--复制上面 6 行粘贴,设置从服务器 2 的名 slave2 和地址
<dbServer name="slave2"  parent="abstractServer">
<property name="ipAddress">192.168.10.40</property>
#--65--修改
<dbServer name="slaves" virtual="true">
#--71--修改
<property name="poolNames">slave1,slave2</property>
......

/usr/local/amoeba/bin/amoeba start &		#启动 amoeba 软件,按 ctrl+c 返回
netstat -anpt | grep java					#查看 8066 端口是否开启,默认端口为 TCP 8066
tcp6       0      0 127.0.0.1:61721         :::*                    LISTEN      4346/java           
tcp6       0      0 :::8066                 :::*                    LISTEN      4346/java           
tcp6       0      0 192.168.8.17:58290      192.168.8.15:3306       ESTABLISHED 4346/java           
tcp6       0      0 192.168.8.17:58300      192.168.8.14:3306       ESTABLISHED 4346/java           
tcp6       0      0 192.168.8.17:56808      192.168.8.16:3306       ESTABLISHED 4346/java  

3. 客户端测试读写分离

client:192.168.8.13 ,已装好 MySQL 服务

  • 客户端
[root@client ~]#mysql -uamoeba -p123456 -h 192.168.8.17 -P8066
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ggll               |
| mysql              |
| performance_schema |
| sys                |
| test               |
| test1              |
+--------------------+

mysql> use test;
mysql> create table test(id int,name char(20));
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)
  • master 服务器
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)
  • slave 1 服务器
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+

mysql> use test;
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)
  • slave 2 服务器
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+

mysql> use test;
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+

可以看到客户端中做出的修改,在所有服务器上都能看到。

4. 关闭 slave 功能后在主从服务器插入数据

  • slave 1 服务器
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test values(1,'slave1');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    1 | slave1 |
+------+--------+
1 row in set (0.00 sec)
  • slave 2 服务器
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test values(2,'slave2');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    2 | slave2 |
+------+--------+
1 row in set (0.00 sec)
  • master 服务器
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)

mysql> insert into test values(3,'master');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    3 | master |
+------+--------+
1 row in set (0.00 sec)
  • client 服务器
mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    2 | slave2 |
+------+--------+
1 row in set (0.01 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    1 | slave1 |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    2 | slave2 |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    1 | slave1 |
+------+--------+
1 row in set (0.00 sec)

上面输出结果中:客户端在 slave1、slave2 中轮询查看数据。由于从服务器都关闭了 slave 功能,因此无法查看 master 服务器中的修改。

5. 关闭 slave 功能后,客户端服务器写入数据

  • 客户端服务器
mysql> insert into test values(4,'client1');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    2 | slave2 |
+------+--------+
1 row in set (0.01 sec)

mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    1 | slave1 |
+------+--------+
1 row in set (0.00 sec)
  • master 服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    3 | master  |
|    4 | client1 |
+------+---------+
2 rows in set (0.00 sec)
  • slave 1 服务器
mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    1 | slave1 |
+------+--------+
1 row in set (0.00 sec)
  • slave 2 服务器
mysql> select * from test;
+------+--------+
| id   | name   |
+------+--------+
|    2 | slave2 |
+------+--------+
1 row in set (0.00 sec)

结果:客户端服务器的修改操作是对于 master 服务器进行的,因此 master 服务器上可以看到客户端服务器所做的 insert 操作。
由于客户端服务器的 select 操作是对从服务器进行的,而从服务器关闭了 slave 功能,无法获取更新,因此客户端服务器本身以及从服务器都无法查看更新操作。

6. 从服务器开启 slave 服务

  • slave 1 服务器
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    1 | slave1  |
|    3 | master  |
|    4 | client1 |
+------+---------+
3 rows in set (0.00 sec)
  • slave 2 服务器
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    2 | slave2  |
|    3 | master  |
|    4 | client1 |
+------+---------+
3 rows in set (0.00 sec)
  • master 服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    3 | master  |
|    4 | client1 |
+------+---------+
2 rows in set (0.00 sec)
  • 客户端服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    2 | slave2  |
|    3 | master  |
|    4 | client1 |
+------+---------+
3 rows in set (0.00 sec)

mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    1 | slave1  |
|    3 | master  |
|    4 | client1 |
+------+---------+
3 rows in set (0.00 sec)

结果:从服务器开启 slave 服务后可以从 master 服务器上获取更新,但是从服务器上的更新不会被 master 服务器看到。

7. 客户端服务器再次插入数据

  • 客户端服务器
mysql> insert into test values(5,'client2');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    2 | slave2  |
|    3 | master  |
|    4 | client1 |
|    5 | client2 |
+------+---------+
4 rows in set (0.00 sec)
  • master 服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    3 | master  |
|    4 | client1 |
|    5 | client2 |
+------+---------+
3 rows in set (0.00 sec)
  • slave1 服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    1 | slave1  |
|    3 | master  |
|    4 | client1 |
|    5 | client2 |
+------+---------+
4 rows in set (0.00 sec)
  • slave2 服务器
mysql> select * from test;
+------+---------+
| id   | name    |
+------+---------+
|    2 | slave2  |
|    3 | master  |
|    4 | client1 |
|    5 | client2 |
+------+---------+
4 rows in set (0.00 sec)

结果:客户端服务器上的数据修改,会同步到所有服务器中。

总结

  • MySQL 主从复制原理:
      MySQL主服务器在用户增删改查操作,提交事务的以后,会按顺序写入到binlog日志中,从服务器节点会在一定时间间隔内对主服务器的二进制日志进行探测,观察是否发生数据改变,若发生改变则开启一个I/O线程请求主服务器的二进制事件。
      同时主服务器会为每个I/O线程开启dump线程,用于向其发送二进制事件,并保存到从服务器的中继日志中,从服务器会开启SQL线程从中继日志中读取二进制日志,在本地重放,也就是说把二进制日志解析成SQL语句逐一执行,使其数据与主服务器保持一致,最后I/O线程和SQL线程会进入休眠状态,等待下一次被唤醒。

  • 当 MySQL 主从复制在 show slave status\G 时出现 Slave_IO_RunningSlave_SQL_Running 的值不为YES时,需要首先通过 stop slave 来停止从服务器,然后再执行一次上一步操作即可恢复。

  • 但如果想尽可能的同步更多的数据,可以在 Slave 上将 master_log_pos 节点的值在之前同步失效的值的基础上增大一些,然后反复测试,直到同步OK。

  • 因为MySQL主从复制的原理其实就是从服务器读取主服务器的 binlog,然后根据 binlog 的记录来更新数据库。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
mysql 总结........................................................................................................................................6 1.1 数据库的种类...........................................................................................................6 1.1.1 关系型数据库介绍.................................................................................................6 1.1.2 非关系型数据库介绍.............................................................................................7 1.1.3 非关系型数据库种类.............................................................................................7 1.1.4 关系型数据库产品介绍.........................................................................................8 1.1.5 常用非关系型数据库产品介绍.............................................................................8 1.2 mysql 多实例安装实战......................................................................................................9 1.2.1 什么是 mysql 多实例? .........................................................................................9 1.2.2 mysql 的多实例结构图.........................................................................................10 1.2.3 实战安装 mysql 多实例需要的依赖包...............................................................10 1.2.4 安装编译 mysql 需要的软件...............................................................................10 1.2.5 安装 mysql 软件...................................................................................................11 1.2.6 创建存放两个 mysql 实例的数据目录...............................................................11 1.2.7 创建两个 mysql 多实例的配置文件...................................................................12 1.2.7.1 3306 的实例................................................................................................12 1.2.7.2 3307 的实例................................................................................................16 1.2.7.3 多实例本地登录 mysql .............................................................................20 1.2.7.4 远程连接登录 mysql 多实例....................................................................20 1.3 mysql 基础安全................................................................................................................21 1.3.1 启动程序设置 700,属主和用户组为 mysql .....................................................21 1.3.2 为 mysq 超级用户 root 设置密码........................................................................21 1.3.3 登录时尽量不要在命令行暴漏密码,备份脚本中如果有密码,给设置 700, 属主和用户组为 mysql 或 root......................................................................................21 1.3.4 删除默认存在的 test 库 .......................................................................................21 1.3.5 初始删除无用的用户,只保留 root 127.0.0.1 和 root localhost........................21 1.3.6 授权用户对应的主机不要用%,权限不要给 all,最小化授权,从库只给 select 权限.................................................................................................................................21 1.3.7 不要给一个用户管所有的库,尽量专库专用户...............................................21 1.3.8 清理 mysql 操作日志文件~/mysql_history.........................................................21 1.3.9 禁止开发获取到 web 连接的密码,禁止开发连接操作生产对外的库...........21 1.4.0 服务器禁止设置外网 IP ......................................................................................21 1.4.1 防 SQL 注入(WEB), php.ini 配置文件里面设置 ..........................................21 1.4.2 mysql 的备份的脚本给 700 的权限,并且属主和属组为 root..........................21 1.4 关于 mysql 的启动与关闭..............................................................................................21 1.4.1 单实例 MySQL 启动与关闭方法........................................................................21 1.4.2 多实例 MySQL 启动与关闭方法示例................................................................21 1.5 生产环境关闭 mysql 的命令..........................................................................................22 1.5.1 生产环境不能用强制命令关闭 mysql 服务 .......................................................22 1.5.2 下面来介绍优雅关闭数据库方法: ...................................................................22 1.6 登录 mysql 方法..............................................................................................................22 1.6.1 单实例 MySQL 登录的方法................................................................................22 1.6.2 多实例 MySQL 的登录方法................................................................................22 1.7 关于 mysql 管理员设置..................................................................................................22资源由 www.eimhe.com 美河学习在线收集分享 1.7.1 为管理员 root 用户设置密码并修改方法之一...................................................22 1.7.2 修改管理员 root 密码法二(sql 语句修改) .....................................................22 1.7.3 找回丢失的 mysql root 用户密码(单实例和多实例) ....................................23 1.8 SQL 结构化查询语言......................................................................................................23 1.8.1 什么是 SQL? ......................................................................................................23 1.8.2 SQL 语句最常见的分类一般就是 3 类 ...............................................................24 1.9 数据库的管理应用..........................................................................................................24 1.9.1 创建数据库...........................................................................................................24 1.9.2 查看库的字符集及校队规则...............................................................................24 1.9.3 企业场景创建什么字符集的数据库呢? ...........................................................26 1.9.4 显示数据库...........................................................................................................26 1.9.5 删除数据库...........................................................................................................26 1.9.6 进入数据库中指定的库.......................................................................................27 1.9.7 查看进入当前数据库的用户...............................................................................27 1.9.8 删除数据库多余的账号.......................................................................................27 1.9.9 查看数据库的用户...............................................................................................27 2.0.0 创建 MySQL 用户及赋予用户权限............................................................................27 2.0.1 使用语法:..............................................................................................................27 2.0.2 第一种创建用户及授权方法: ...........................................................................28 2.0.3 第二种创建用户及授权方法: ...........................................................................28 2.0.4 创建用户及授权哪个网段的主机可以连接 oldboy_gbk 库..............................29 2.0.4.1 第一种方法: .............................................................................................29 2.0.4.2 第二种方法: ............................................................................................29 2.0.5 关于 mysql 回收某个用户权限...........................................................................29 2.0.6 企业生产环境如何授权用户权限(mysql 主库) ............................................30 2.1 数据库表操作..................................................................................................................31 2.1.1 以默认字符集 latin1 建库....................................................................................31 2.1.2 建立表并查看表的结构.......................................................................................31 2.1.3 mysql 表的字符类型.............................................................................................32 2.1.3.1 数字类型.....................................................................................................32 2.1.3.2 日期和时间类型.........................................................................................32 2.1.3.3 字符串类型................................................................................................33 2.1.3.4 关于字符类型小结....................................................................................33 2.1.4 为表的字段创建索引...........................................................................................33 2.1.4.1 为表创建主键索引的方法........................................................................33 2.1.4.2 查看 student 表的结构 ..............................................................................34 2.1.4.3 怎么删除一个表的主键............................................................................34 2.1.4.4 利用 alter 命令修改 id 列为自增主键列..................................................34 2.1.4.5 建表后利用 alter 增加普通索引...............................................................34 2.1.4.6 对表字段的前 n 个字符创建普通索引....................................................36 2.1.4.7 为表的多个字段创建联合索引................................................................38 2.1.4.8 为表的多个字段的前 n 个字符创建联合索引........................................38 2.1.4.9 主键也可以联合多列做索引....................................................................39 2.1.5.0 统计一个字段列的唯一值个数................................................................40资源由 www.eimhe.com 美河学习在线收集分享 2.1.5.1 创建唯一索引(非主键) ........................................................................41 2.1.5.2 索引列的创建及生效条件........................................................................42 2.1.5 往表中插入数据...................................................................................................42 2.1.6 往表中删除一条数据...........................................................................................44 2.1.7 查询数据................................................................................................................44 2.1.7.1 查询表的所有数据行................................................................................44 2.1.7.2 查看 mysql 库的用户................................................................................45 2.1.7.3 根据指定条件查询表的部分数据............................................................45 2.1.7.4 根据固定条件查数据................................................................................46 2.1.7.5 指定固定条件范围查数据........................................................................46 2.1.7.6 根据顺序查看列数据................................................................................46 2.1.6.7 在表中根据条件导出数据至文件中........................................................47 2.1.8 多表查询...............................................................................................................47 2.1.8.1 创建学生表................................................................................................47 2.1.8.2 在学生表里插入数据.................................................................................47 2.1.8.3 创建课程表................................................................................................47 2.1.8.4 在课程表里插入数据................................................................................48 2.1.8.5 创建选课表................................................................................................48 2.1.8.6 联表查询命令............................................................................................49 2.1.9 使用 explain 查看 select 语句的执行计划..........................................................49 2.1.9.1 用查询语句查看是否使用索引情况........................................................49 2.1.9.2 为该列创建索引,再用查询语句查看是否走了索引............................50 2.2.0 使用 explain 优化 SQL 语句(select 语句)的基本流程..................................50 2.2.1 用命令抓取慢 SQL 语句,然后用 explain 命令查看查询语句是否走的索 引查询.....................................................................................................................50 2.2.2 设置配置参数记录慢查询语句...................................................................51 2.2.3 对抓取到的慢查询语句用 explain 命令检查索引执行情况 .....................51 2.2.4 对需要建索引的条件列建立索引...............................................................51 2.2.5 切割慢查询日志,去重分析后发给大家...................................................51 2.2.1 修改表中数据.......................................................................................................51 2.2.1.1 修改表中指定条件固定列的数据............................................................51 2.2.2 删除表中的数据...................................................................................................52 2.2.2.1 实践删除表中的数据................................................................................52 2.2.2.2 通过 update 伪删除数据...........................................................................53 2.2.3 增删改表的字段...................................................................................................53 2.2.3.1 命令语法及默认添加演示........................................................................53 2.2.4 更改表名...............................................................................................................55 2.2.5 删除表名...............................................................................................................56 2.2.6 mysql 数据库的备份与恢复.................................................................................56 2.2.6.1 备份单个数据库练习多种参数使用........................................................56 2.2.6.2 查看数据库 oldboy 的内容.......................................................................56 2.2.6.3 执行备份的命令........................................................................................57 2.2.6.4 查看备份的结果........................................................................................57 2.2.6.5 mysqldump 备份时加上-B 参数时的备份,然后比较不加-B 备份的不同资源由 www.eimhe.com 美河学习在线收集分享 .................................................................................................................................57 2.2.6.6 删除数据库中备份过的库 oldboy,然后将备份的数据重新导入数据库 .................................................................................................................................58 2.2.6.7 利用 mysqldump 命令对指定的库进行压缩备份...................................59 2.2.6.8 利用 mysqldump 命令备份多个库(-B 参数后可以指定多个库) ......59 2.2.6.9 分库备份(对 mysql、 oldboy、 oldboy_gbk、 wordpress 库进行备份) .................................................................................................................................60 2.2.7.0 对一个库的多个表备份............................................................................60 2.2.7.1 备份多个表................................................................................................61 2.2.7.2 备份单个表................................................................................................61 2.2.7.3 关于 mysqldump 的参数说明...................................................................61 2.2.7.4 刷新 binglog 的参数..................................................................................62 2.2.7.5 生产场景不同引擎 mysqldump 备份命令...............................................62 2.2.8 恢复数据库实践...................................................................................................63 2.2.8.1 数据库恢复事项........................................................................................63 2.2.8.2 利用 source 命令恢复数据库 ...................................................................63 2.2.8.3 利用 mysql 命令恢复(标准) ................................................................64 2.2.8.4 针对压缩的备份数据恢复........................................................................66 2.2.9 实现和 mysql 非交互式对话...............................................................................66 2.2.9.1 利用 mysql –e 参数查看 mysql 数据库的库名........................................66 2.2.9.2 利用 mysql –e 参数查看 mysql 数据库的线程状态................................66 2.2.9.3 mysql sleep 线程过多的问题案例............................................................66 2.2.9.4 查看 mysql 配置文件有没有在数据库中生效 ........................................67 2.2.9.5 不重启数据库修改数据库参数................................................................68 2.2.9.6 不重启数据库更改数据库参数小结........................................................69 2.3.0 查看 mysql 状态的信息(利用 zabbix 可以监控其状态信息) .......................69 2.3.1 mysqladmin 的命令...............................................................................................75 2.3.2 mysql 工具 mysqlbinlog........................................................................................76 2.3.2.1 mysql 的 binlog 日志是什么? ..................................................................76 2.3.2.2 mysql 的 binlog 日志作用是什么? ..........................................................76 2.3.2.3 mysqlbinlog 工具解析 binlog 日志实践....................................................76 2.3.2.4 解析指定库的 binlog 日志........................................................................76 2.3.3 mysql 数据库的服务日志.....................................................................................77 2.3.3.1 错误日志(error log)介绍与调整..........................................................77 2.3.3.2 普通查询日志(general query log)介绍与调整(生产环境中不用) 77 2.3.3.3 慢查询日志介绍与调整............................................................................78 2.3.3.4 二进制日志介绍与调整............................................................................78 2.3.4 mysql 的 binlog 有三种模式.................................................................................78 2.3.4.1 row level......................................................................................................78 2.3.4.2 statement level(默认) ..................................................................................79 2.3.4.3 Mixed ..........................................................................................................79 2.3.5 企业场景如何选择 binlog 的模式.......................................................................79 2.3.6 设置 mysql binlog 的格式....................................................................................79 2.3.7 mysql 生产备份实战应用指南.............................................................................80资源由 www.eimhe.com 美河学习在线收集分享 2.3.7.1 全量备份....................................................................................................80 2.3.7.2 增量备份....................................................................................................80 2.3.7.3 企业场景和增量的频率是怎么做的? ....................................................81 2.3.7.4 mysql 增量恢复必备条件..........................................................................81 2.3.7.5 实战模拟凌晨 00 点对 oldboy库做个全备,早上 10 点左右删除了 oldboy 库,下面是其恢复过程.........................................................................................81 2.3.7.6 实战模拟凌晨 00 点对 oldboy库做个全备,早上 10 点左右更新了 oldboy 库的 test 表中所有字段数据,下面是其恢复过程(update 表中的数据的时候, 把表中的字段换成了一个相同的内容,这时候要停库) .................................83 2.3.8 mysql主从复制的结构图.................................................................................85 2.3.8.1 单向的主从复制图,此架构只能在 master 端进行数据写入(生产环境 可以使用) .............................................................................................................85 2.3.8.2 双向的主主同步逻辑图,此架构可以在 master1 端或 master2 端进行数 据写入(生产环境不建议使用) .........................................................................85 2.3.8.3 线性级联单向双主同步逻辑图,此架构只能在 master1 端进行数据写入 (生产环境可以使用) .........................................................................................86 2.3.8.4 环状级联单向多主同步逻辑图,任意一个都可以写入数据(生产环境 不建议使用) .........................................................................................................86 2.3.8.5 环状级联单向多主多从同步逻辑图,此架构只能在任意一个 master 端 进行数据写入(生产环境不建议使用) .............................................................86 2.3.9 mysql 主从复制的原理.........................................................................................86 2.4.0 mysql 主从复制的原理图.....................................................................................87 2.4.1 mysql 主从复制的实践.........................................................................................87 2.4.1.1 环境准备....................................................................................................87 2.4.1.2 分别查看 3306 和 3307 不同数据库有哪些库........................................87 2.4.1.3 全量备份 3306 数据库的库,然后到 3307 数据库中............................88 2.4.1.4 在 3306 数据库上授权用户可以到 3306 数据库上复制 binlog.............89 2.4.1.5 在 3307 数据库上开启复制 3306 的 binlog 开关,并查看是否处于同步 状态.........................................................................................................................89 2.4.1.6 在 3306 上创建数据库 zhangxuan,看 3307 上是否同步过来..............91 2.4.2 关于主从复制出现故障怎么解决.......................................................................92 2.4.3 主从复制延迟问题原因及解决方案...................................................................92 2.4.3.1 一个主库的从库太多,导致复制延迟....................................................92 2.4.3.2 从库硬件比主库差,导致复制延迟........................................................92 2.4.3.3 慢 SQL 语句过多 ......................................................................................92 2.4.3.4 主从复制的设计问题................................................................................93 2.4.3.5 主从库之间的网络延迟............................................................................93 2.4.3.6 主库读写压力大,导致复制延迟............................................................93 2.4.4 通过 read-only 参数让从库只读访问..................................................................93 2.4.5 web 用户专业设置方案: mysql 主从复制读写分离集群..................................93 2.4.6 让 mysql 从库记录 binlog 日志方法...................................................................94 2.4.7 mysql 主从复制集群架构的数据备份策略.........................................................94 2.4.8 mysql 一主多从,主库宕机,从库怎么接管.....................................................95 2.4.8.1 半同步从库(谷歌半同步插件 5.5 版本自带) .....................................95资源由 www.eimhe.com 美河学习在线收集分享 2.4.8.2 S1,啥也不干只做同步的从库, 500 台服务器,百度..........................95 2.4.8.3 皇帝驾崩现选(耽误事,容易被篡位) ................................................95 2.4.9 事务介绍...............................................................................................................97 2.4.9.1 事务的四大特性(ACID) ......................................................................97 2.4.9.2 事务的开启................................................................................................97 2.4.9.3 事物的实现................................................................................................98 2.5.0 mysql 引擎概述.....................................................................................................98 2.5.0.1 什么是存储引擎? ....................................................................................98 2.5.0.2 mysql 存储引擎的架构..............................................................................99 2.5.0.3 myisaw 引擎介绍 .......................................................................................99 2.5.0.4 myisaw 引擎特点 .......................................................................................99 2.5.1 myisaw 引擎调忧精要 ........................................................................................100 2.5.2 innodb 引擎..........................................................................................................100 2.5.2.1 什么是 innodb 引擎? .............................................................................100 2.5.2.2 innodb 引擎特点.......................................................................................101 2.5.2.3 innodb 引擎适应的生产业务场景...........................................................102 2.5.2.4 关于 innodb 引擎的一些参数设置.........................................................102 2.5.2.5 innodb 引擎调忧精要...............................................................................102 2.5.3 有关 mysql 引擎特别说明.................................................................................103 2.5.4 关于 mysql 的字符集.........................................................................................103 2.5.4.1 mysql 常见的字符集? ............................................................................103 2.5.4.2 mysql 如何选择合适的字符集? ............................................................103 2.5.4.3 如何查看字符集......................................................................................103 2.5.4.4 不同字符集参数的含义如下(要想数据库字符不乱码,下面几个字符 集要相同) ...........................................................................................................104 2.5.4.5 set names 字符集名,此命令有什么作用 .............................................105 2.5.4.6 根据配置文件更改客户端字符集..........................................................105 2.5.4.7 更改 mysql 服务端的字符集..................................................................106 2.5.4.8 怎么解决乱码问题..................................................................................106 2.5.4.9 插入数据不乱码的方法..........................................................................106 2.5.5.0 更改数据库的字符集..............................................................................106 2.5.5.1 更改表的字符集......................................................................................106 2.5.6 模拟将 latin1 字符集的数据库修改成 UTF8 字符集的实际过程 ..................107
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发莫的了呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值