目录

1. 主从MySQL主从复制介绍... 1

2. MySQL主从复制的企业应用场景... 3

3. 实现MySQL主从读写分离的方案... 5

4. MySQL主从复制原理... 7

5. 主从复制实战... 8

5.1 MySQL主从配置... 8

5.2 MySQL数据库级联配置... 12

5.3 MySQL主从复制配置步骤小结... 15

5.4 主从配置表示成功后的关键参数说明... 15

5.5 MySQL主从复制配置问题汇总... 16

6. MySQL主从复制更多应用技巧... 17

 

1. 主从MySQL主从复制介绍

MySQL的主从复制方案,其实就和文件及文件系统级别同步是类似的,都是数据的传输,只不过MySQL无需借助第三方工具,而是自带的同步复制功能,另外一点,MySQL的主从复制并不是磁盘上文件直接同步,而是逻辑的binlog日志同步到本地在应用执行的过程。

MySQL数据库支持单向、双向、链式级联等不同场景的复制,在复制过程中,一台服务器充当主服务器(Master),而一个或多个其它的服务器充当从服务器(Slave)。

复制可以单向:M==>S;可以双向:M<==>S;当然也可以多M环装同步等。

如果设置了链式级联复制,那么,从(slave)服务器本身除了充当从服务器外,也会同时充当其下面从服务器的主服务器,链式级联复制类似A==>B==>C==>D的复制形式。

下面是MySQL各种同步结构的逻辑图:

1. 单向主从复制逻辑图,此架构只能在Master端进行数据写入

2. 双向主主同步逻辑图,此架构可以在Master1端或Master2端进行数据写入

3. 线性级联单向双主同步逻辑图,此架构只能在Master端进行数据写入

4. 环装级联单向多主同步逻辑图,任意一个点都可以写入数据

5. 环装级联单向多主多从同步逻辑图,次架构只能在任意一个master端进行数据写入

6. MySQL官方同步架构图

在当前的生产环境中,MySQL主从复制都是异步的复制方式,既不是严格实时的数据同步。

2. MySQL主从复制的企业应用场景

MySQL主从复制集群功能使得MySQL数据库支持大规模高并发读写称为可能,同时有效的保护了物理服务器宕机场景的数据备份。


应用场景1:从服务器作为主服务器的实时数据备份

主从服务器架构的设置可以大大加强MySQL数据库架构的健壮性,例如:当主服务器出现问题时,我们可以人工或设置自动切换到从服务器继续提供服务,此时从服务器的数据与宕机时的数据库几乎是一致的。

这类似NFS存储数据通过inotify+rsync同步到备份的NFS服务器,只不过MySQL的复制方案是其自带的工具。

利用MySQL的复制功能进行数据备份时,在硬件故障、软件故障的场景下,该数据备份是有效的,但对于人为执行drop、delete等语句删除数据的情况,从库的备份功能就没用了,因为从服务器也会执行删除的语句。


应用场景2:主从服务器实现读写分离,从服务器实现负载均衡

主从服务器架构可通过(PHP、java等)或代理软件(mysql-proxy、Amoeba)实现对用户(客户端)的请求读写分离,揖让从服务器金聪处理用户的select查询请求,降低用户查询响应时间,以及同时读写在主服务器上带来的访问压力,对于更新的数据(例如:update、insert、delete语句),则仍然交给主服务器处理,确保主服务器和从服务器保持实时同步。


应用场景3:把多个从服务器根据业务重要性进行拆分访问

可以把几个不同的从服务器,根号月公司的业务进行拆分,例如:在为外部用户提供查询服务的从服务器,在内部DBA用来数据备份的从服务器,还有为公司内部人员提供访问的后台、脚本、日志分析及供开发人员查询使用的从服务器,这样拆分除了减轻主服务器的压力外,还可以是数据库对外不用户浏览,内部用户业务处理及DBA人员的备份等互不影响。

3. 实现MySQL主从读写分离的方案

(1)通过程序实现读写分离(性能和效率最佳,推荐)

PHP和java程序都可以通过设置多个连接文件轻松地实现对数据库的读写分离,即当语句关键字为select时,就去连接读库的连接文件,若为update、insert、delete时,则连接写库的文件。

通过程序实现读写分离的缺点就是需要开发人员对程序进行改造,使其对下层不透明,但这种方式更容易开发和实现,适合互联网业务场景。


2)通过开源的软件实现读写分离

MySQL-Proxy、Amoeba等代理软件也可以是实现读写分离功能,这些软件的稳定性和功能一般,不建议生产使用,绝大多数公司常用的还是在应用端发程序实现读写分离。


(3)大型门户独立开发DAL层综合软件

百度、阿里等大型门户都有开发牛人,会花大力气开发适合自己业务的读写分离,负载均衡,监控报警,自动扩容,自动收缩等一系列功能的DAL层软件。

4. MySQL主从复制原理

简单描述MySQL Replication的复制原理过程

1. 在Slave服务器上执行start slave命令开启主从复制开关,开始进行主从复制。

2. 此时,slave服务器的I/O线程会通过在Master上已经授权的复制用户权限请求选择Master服务器,并   请求从指定binlog日志文件的指定位置(日志文件名和位置就是在哦诶之主从渎职服务时执行change   master命令指定的)之后,之后开始发送binlog日志内容。

3. Master服务器接收来自slave服务器的IO线程的请求后,其上负责复制的I/O线程会根据slave服务器   的io线程请求的信息分批读取指定binlog日志文件指定位置之后的binlog日志信息,然后返回给     slave端的I/O线程,返回的信息中除了binlog日志内容外,还有在master服务器端记录的新的binlog   文件名称,以及在新的binlog中的下一个指定的跟新位置。

4. 当slave服务器的io线程获取带master服务器上io线程发送的日志内容,日志文件及位置点后,会将   binlog日志内容写到slave端自身的relay loy(即中继日志)的最末端,并将新的binlog日志文件名   和位置点记录到master-info文件中,以便下一次读取master端新的binlog日志是能够告诉master服   务端从新的binlog日志指定文件及位置开始请求新的binlog日志内容。

5.slave服务器端的SQL线程会实时监测本地relay log中的io线程新增加的日志内容。然后及时的把  relay.log文件中的内容解析成SQL语句,并且自身slave服务器上按解析sql语句的位置顺序执行应用  这些SQL语句,并在relay-log.info中记录当前应用中继日志文件名及位置点。


MySQL主从复制原理的重点小结:

  • 主从复制是异步的逻辑的SQL语句级的复制

  • 复制时,主库有一个线程,从库有两个线程,即I/O和SQL线程

  • 实现主从复制的前提条件时主库开启记录binlog功能

  • 作为复制的所有MySQL节点的sever id都不能相同

binlog文件只记录对数据有更改的SQL语句(来自主数据库内容的变更),不记录任何查询(如:select、show)语句。

5. 主从复制实战

实现主从复制条件

  • 开启binlog功能。

  • 主库建立同步账号。

  • 从库配置master.info(change master..)。

startslave复制开关。

5.1 主从配置

如图:

配置主从复制

测试环境:使用一台服务器,多实例,一个实例做主,另外的实例做从(多台服务器也一样)


(1)主库操作


1. 先确认主库binlog功能是否开启和各个实例server-id实例的不同

[root@db01 3308]# egrep "log-bin|server-id" /data/{3306,3307}/my.cnf
/data/3306/my.cnf:log-bin= /data/3306/mysql-bin
/data/3306/my.cnf:server-id= 1
/data/3307/my.cnf:#log-bin= /data/3307/mysql-bin
/data/3307/my.cnf:server-id= 3

2. 主库授权同步的用户

[root@db01 /]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock  #<== 登录数据库
mysql> grant replication slave on *.* torep@'172.16.1.%' identified by 'oldboy123';
Query OK, 0 rowsaffected (0.00 sec)                 #<== 创建rep用户并授权
mysql> flush privileges;                            #<== 刷新数据库
Query OK, 0 rowsaffected (0.00 sec)mysql> select user,host from mysql.user;            #<== 创建用户后查看确认
mysql> show grants for rep@'172.16.1.%';            #<== 查看rep用户权限

3. 备份前对主数据库锁表(只读)

mysql> flush table with read lock;
Query OK, 0 rowsaffected (0.00 sec)

测试:单开一个窗口,创建一个数据库(这时会发现创建不了,因为表锁了)

mysql> create database oldgirl;

4. 查看全备与增量之间的临界点

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

5. 开始备份

创建备份目录

[root@db01 ~]# mkdir -p /server/backup/

全备

[root@db01~]# mysqldump -uroot -poldboy123 -S/data/3306/mysql.sock -B -A --events|gzip >/server/backup/rep_bak_$(date+%F).sql.gz
[root@db01 ~]# ll -htr /server/backup/|tail -1
-rw-r--r-- 1 root root 149K Aug 31 23:57rep_bak_2016-08-31.sql.gz

6. 因为数据已经备份完,所以可以开放用户写入功能,此时会发现测试窗口的数据会写入

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

(2)从库操作

1. 确保所有用户server-id不同(主库已经确认过)

[root@db01 3308]# egrep "log-bin|server-id" /data/{3306,3307}/my.cnf
/data/3306/my.cnf:log-bin= /data/3306/mysql-bin
/data/3306/my.cnf:server-id= 1
/data/3307/my.cnf:#log-bin= /data/3307/mysql-bin
/data/3307/my.cnf:server-id= 3

2. 把主库的全备导入到从库

[root@db01 ~]# gzip -d/server/backup/rep_bak_2016-08-31.sql.gz
[root@db01 ~]# ll /server/backup/rep_bak_2016-08-31.sql
-rw-r--r-- 1 root root 552788 Aug 31 23:57//server/backup/rep_bak_2016-08-31.sql
[root@db01 ~]# mysql -uroot -poldboy123 -S/data/3307/mysql.sock </server/backup/rep_bak_2016-08-31.sql

3. 找位置点,开始配置masterinfo

[root@db01 3307]# mysql -uroot -poldboy123 -S/data/3307/mysql.sock
CHANGE MASTER TO
MASTER_HOST='172.16.1.51',           #<== 主库IP
MASTER_PORT=3306,                    #<== 主库端口(如果配置一主多从可不写,默认)
MASTER_USER='rep',                   #<== 这里是主库上建立的用于复制的用户rep
MASTER_PASSWORD='oldboy123',         #<== rep用户密码
MASTER_LOG_FILE='mysql-bin.000016',  #<== 这里是showmaster status; 时看到的临界点binlog文件,注意,这里不能多空格
MASTER_LOG_POS=107;                  #<== 这是showmaster status; 查看二进制文件偏移量,注意,不能多空格[root@db01 ~]# ll /data/3307/
-rw-rw---- 1 mysql mysql   51 Sep 1 03:40 relay-log.info

参数如下:

CHANGE MASTER TO
MASTER_HOST='172.16.1.51',
MASTER_PORT=3306,
MASTER_USER='rep',
MASTER_PASSWORD='oldboy123',
MASTER_LOG_FILE='mysql-bin.000016',
MASTER_LOG_POS=107;

4. 开启同步开关

mysql> start slave;
Query OK, 0 rowsaffected (0.01 sec)

5. 查看同步状态,看到以下×××部分是以下状态就算成功

mysql> show slave status\G
*************************** 1. row***************************
-----------------------省略部分内容------------         Relay_Master_Log_File: mysql-bin.000017Slave_IO_Running: Yes                #<== 看这IO线程yes和SQLyes就成功了Slave_SQL_Running: YesReplicate_Do_DB:
-------------------------------------省略-----------Seconds_Behind_Master: 0                  #<== 主到从复制的延迟
1 row in set (0.00 sec)

或者使用命令查看:

mysql -S /data/3307/mysql.sock -e"show slave status\G"|egrep -i "_running|Behind "Slave_IO_Running: YesSlave_SQL_Running: Yes
Seconds_Behind_Master: 0

(3)简单测试是否成功

1. 在主库创建数据库,查看从库是否同步

[root@db01 3307]# mysql -uroot -poldboy123 -S/data/3306/mysql.sock
mysql> show databases;
+-----------------------+
| Database              |
+-----------------------+
| information_schema    |
| mysql                 |
| performance_schema    |
+-----------------------+
8 rows in set (0.00 sec)
mysql> create database testdatabase;
Query OK, 1 row affected (0.00 sec)mysql> show databases;
+-----------------------+
| Database              |
+-----------------------+
| information_schema    |
| mysql                 |
| performance_schema    |
| testdatabase          |
+-----------------------+
9 rows in set (0.00 sec)

登录从库查看

[root@db01 3307]# mysql -uroot -poldboy123 -S/data/3307/mysql.sock
mysql> show databases;
+-------------------------------+
| Database              |
+-------------------------------+
| information_schema   |
| mysql                |
| performance_schema  |
| testdatabase         |
+-------------------------------+
9 rows in set (0.00 sec)

------------------成功!!!-------------------

5.2 MySQL数据库级联配置

说明:在配置了MySQL一主一从或MySQL一主多从的情况下,在该基础上的从库下面在配置一台从库,构成线性级联单向双主同步。


环境:在以上5.1的配置上继续配置级联

以下在以上配置的3307从库上操作

1. 开启从库3309记录binlog日志功能,配置如下:

[root@db01 3307]# vim /data/3307/my.cnf
[mysqld]
log-slave-updates                      #<==在从库上配置binloa文件时,此行也是必须加的
log-bin = /data/3309/mysql-bin

重启生效

[root@db01 3307]# /data/3307/mysql restart
Restarting MySQL...
Stoping MySQL...
Starting MySQL..

2. 全备3307从库实例,导入到3309

[root@db01 3307]# mysqldump -uroot -poldboy123 -S/data/3307/mysql.sock -B -A --master-data=1 --events>/server/backup/3307.sql
[root@db01 3307]# mysql -uroot-poldboy123 -S /data/3309/mysql.sock </server/backup/3307.sql


以下步骤在3309上面操作

3. 在3309上面配置master info文件

[root@db01 3309]# mysql -uroot -poldboy123 -S/data/3309/mysql.sock
mysql> CHANGE MASTER TO->MASTER_HOST='172.16.1.51',                     ->MASTER_PORT=3307,                                     ->MASTER_USER='rep',                             ->MASTER_PASSWORD='oldboy123';
Query OK, 0 rows affected (0.01 sec)
说明:这里没有进行查看并指定binlog文件的位置点是因为备份时已经使用参数-x(锁表),和--master-data=1
(标记binlog文件数据位置)两个参数,--master-data=1会自动会自动生成位置点。

参数如下:

CHANGEMASTER TO
MASTER_HOST='172.16.1.51',
MASTER_PORT=3307,
MASTER_USER='rep',
MASTER_PASSWORD='oldboy123';

4. 在3309上面开启slave开关

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

5. 查看状态

mysql> show slave status\G Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 0
说明:以上输出部分内容省略,只要以上三行是该状态就表示正确(此三行是配置成功标志最关键的参数)

# 还可以在命令行外执行命令查看,如下:

[root@db01 3309]# mysql -uroot -poldboy123 -S/data/3309/mysql.sock  -e "showslave status\G"|egrep -i "_running|Seconds"Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 0

测试:

在主库3306里面写入数据,这时在3307库里面和3309库里面就会同时有啦,如下:

# 在3306查看并创建数据库

[root@db01 3308]# mysql -uroot -poldboy123 -S/data/3306/mysql.sock
mysql> show databases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| mysql               |
| oldboy              |
| performance_schema  |
+---------------------+
4 rows in set (0.00 sec)
mysql> create database zyl;                         #<== 创建名为zyl的库
mysql> show databases;                              #<==在3306上面查看
+-------------------------------+
| Database            |
+-------------------------------+
| information_schema   |
| mysql                    |
| oldboy              |
| performance_schema  |
| zyl                |
+-------------------------------+
5 rows in set (0.00 sec)[
[root@db01 3307]# mysql -uroot -poldboy123 -S/data/3307/mysql.sock
mysql> show databases;                               #<==在3307上面查看
+-------------------------------+
| Database            |
+-------------------------------+
| information_schema   |
| mysql                     |
| oldboy              |
| performance_schema  |
| zyl                |
+-------------------------------+
5 rows in set (0.00 sec)
[root@db01 3307]# mysql -uroot -poldboy123 -S/data/3309/mysql.sock
mysql> show databases;                              #<==在3309上面查看
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| mysql               |
| oldboy              |
| performance_schema  |
| zyl                 |
+---------------------+
5 rows in set (0.00 sec)

报错原因:  1. 防火墙原因;

2. 复制账号和密码不对。

5.3 MySQL主从复制配置步骤小结

1. 一主一从环境为一台服务器(多实例),3306为主,3307为从,3309为级联。

2. 配置my.cnf文件,主库配置bin-log和server-id出本书,从库配置sever-id,该值个库不能一样,一般不开启从库的binlog功能,但是在5.2因为在3307从库下还有配置级联从库,所以需要开启。配置这些参数要重启才能生效。

3. 登录主库,增加从库连接主库同步的账户,例如:rep、并授权replication slave复制同步的权限。

4. 登录主库,整库锁表flus tablewith read lock(窗口关闭后即失效,超时参数设定的时间到了,锁表也会失效),然后show master status查看binlog的位置状态。

5 . 离开窗口,在linux命令行备份导出原有的数据库数据,并拷贝到从库所在的服务器目录,如果数据量庞大,并且允许停机,可以停机打包,而不用mysqldump。

6. 导出主库数据后,执行unlocktables解锁主库。

7. 把主库导出的数据恢复到从库。

8. 根据主库的show masterstatus查看到的binlog的位置状态,在从库执行change master to...语句。

9. 从库开启复制开关,即执行Lstartslave;。

5.4 主从配置表示成功后的关键参数说明

主从复制是否配置成功,最关键的是下面的3项状态参数

Slave_IO_Running:Yes

这个是I/O线程状态,I/O线程复制从主库到从库读取binlog日志,并写入从库的中继日志,状态为yes表示I/O线程工作正常。


Slave_SQL_Running:Yes

这个是SQL线程状态,SQL线程负责读取中继日志(relay-log)中的数据并装换为SQL语句应用到数据库中,状态为YES表示I/O线程工作正常。


Seconds_Behind_Master:0

这个是复制过程中从库比主库延迟的描述,这个参数很重要,但企业更准确地判断主从延迟的方法为:在主库写时间戳,然后从库读取时间戳,和当前数据库时间进行比较,从而认定是否延迟。

5.5 MySQL主从复制配置问题汇总

1. 主库show master status没返回状态结果,如下

mysql> show master status;
0 row in set (0.00 sec)

原因:binlog功能开关没开或没生效导致。正确开启方式如下:

[root@db01 3307]# grep "log-bin"/data/3306/my.cnf
log-bin = /data/3306/mysql-bin               #<== 在配置文件中将此行注释打开
[root@db01 3307]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock-e "show variables like 'log_bin';"             #<== 修改后查看结果
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

2. 出现错误信息:“Last_IO_Error:GOTdatal errow 1236 drom master when when reading data from binary log; ‘ Couldnot find first log file name in binary log index file’ ”

原因:以上故障原因是执行CHANGE MASTER 命令时,某一个参数的值多个空格导致,如下:

CHANGE MASTER TO
MASTER_HOST='172.16.1.51',
MASTER_PORT=3307,
MASTER_USER='rep',
MASTER_PASSWORD='oldboy123';
说明;以上参数均不能有空格

3. MySQL服务无法启动

[root@db01 /]# /data/3306/mysql start
MySQL is running...                                  #<==正在运行[root@db01 /]# ps -ef|grep mysql                     #<== 并无mysql进程
root     30345  26941  0 22:16 pts/4    00:00:00 grep mysql

原因:其原因是启动脚本里对mysql.sock是否存在做了判断,如果存在mysql.sock,就认为服务运行,这是个bug,解决如下:

[root@db01 /]# rm -f /data/3306/mysql.sock
# 说明:删除后重新启动查看即可

4. 当从起或关闭MySQL服务从起或关闭不了,报错如下:

[root@db01 3307]# /data/3307/mysql restart
Restarting MySQL...
Stoping MySQL...
/application/mysql/bin/mysqladmin: connect toserver at 'localhost' failed
error: 'Access denied for user 'root'@'localhost'(using password: YES)'
MySQL is running...

原因:是启动文件/data/3306/mysql里面没有修改数据库密码,当我们设置完密码后,在mysql启动文件mysql中也是有密码的,如果不改,就无法停止服务。

[root@db01 /]# vim /data/3306/mysql
mysql_pwd="oldboy123"

6. MySQL主从复制更多应用技巧


1.工作中MySQL从库停止复制故障案例

模拟重现故障的能力是运维人员最重要的能力。下面就来次模拟操作。先在从库创建一个库,然后去主库创建同名的库来模拟数据冲突,命令如下:

show slave status;报错:且 show slavestatus\G:
Slave_IO_Running:Yes
Slave_SQL_Running:NO
Seconds_Behind_Master:NULL
Last_Error:Error 'Can't create database 'xiaoliu';database exists' onquery. Default database:'xiaoliu'. Query:'create database xiaoliu'

对于该冲突,解决方法1如下:

top slave;                               #<== 临时停止同步开关
set global sql_slave_skip_counter =1;    #<== 将同步指针向下移动一个,如果多次不同步,可以重复操作
start slave;                             #<== 冲洗你开启
show slave status\G:                     #<== 再次进行查看确认

如果修改后还会报错,那可以适当的将set global sql_slave_skip_counter值增大即可。

提示:setglobal sql_slave_skip_counter=n;#n取值>0,忽略执行N个更新。

解决方法2:根据可以忽略的错误号事先在配置文件中配置,跳过指定的不影响业务数据的错误,例如:

root@MySQL ~]# grep slave-skip /data/3306/my.cnf
slave-skip-errors = 1032,1062,1007

提示:类似由于入库重复导致的失败可以忽略,其他情况是不是可以忽略需要根据不同公司的具体业务来评估。可以查看博客的代码含义


其他可能引起复制故障的原因:


  • MySQL自身的原因及人为重复插入数据。

  • 不同的数据库版本会引起不同步,低版本到高版本可以,但是高版本不能往低版本同步。

  • ·MySQL的运行错误或程序bug。

  • ·binlog记录模式,例如:row level模式就比默认的语句模式要好。


2. 让MySQL从库记录binlog日志的方法

从库需要记录binlog的应用场景:当前的从库还要作为其他从库的主库,例如级联复制或双主互为主从场景的情况下。下面介绍从库记录binlog日志的方法。

在从库的my.cnf中加入如下参数,然后重启服务生效即可。

log-slave-updates                       #<== 必须要有这个参数
log-bin = /data/3307/mysql-bin          #<==开启从库binlog功能
expire_logs_days = 7  #<==相当于find/data/3307/ -type f -name " mysql-bin.000*" -mtime +7 |xargs rm -f

3. MySQL主从复制集群架构的数据备份策略

有主从复制了,还需要做定时全量加增量备份么?答案是肯定的!

因为,如果主库有语句级误操作(例如:drop database oldboy;),从库也会执行drop databaseoldboy;,这样MySQL主从库就都删除了该数据。

把从库作为数据库备份服务器时,备份策略如下:

高并发业务场景备份时,可以选择在一台从库上备份(Slave5),把从库作为数据库备份服务器时需要在从库开启binlog功能,其逻辑如图所示。

步骤如下:

1.选择一个不对外提供服务的从库,这样可以确保和主库更新最接近,专门用于做数据备份。

2.开启从库的binlog功能。

备份时可以选择只停止SQL线程,停止应用SQL语句到数据库,I/O线程保留工作状态,执行命令为stop slave sql_thread;,备份方式可以采取mysqldump逻辑备份或直接物理备份,例如:使用cp、tar(针对/data/目录)工具或xtrabackup(第三方的物理备份软件)进行备份,则逻辑备份和物理备份的选择,一般是根据总的备份数据量的多少进行选择的,数据量低于30G,建议选择mysqldump逻辑备份方法,安全稳定,最后把全备和binlog数据发送到备份服务器上留存。


4. MySQL主从复制延迟问题的原因及解决方案


问题一:主库的从库太多,导致复制延迟。

从库数量以3~5个为宜,要复制的从节点数量过多,会导致复制延迟。


问题二:从库硬件比主库差,导致复制延迟。

查看Master和Slave的系统配置,可能会因为机器配置不当,包括磁盘I/O、CPU、内存等各方面因素造成复制的延迟。这一般发生在高并发大数据量写入场景U、内存等各方面因素造成复制的延迟。这一般发生在高并发大数据量写入场景中。


问题三:慢SQL语句过多

假如一条SQL语句执行时间是20秒,那么从执行完毕到从库上能查到数据至少需要20秒,这样就延迟20秒了。

一般要把SQL语句的优化作为常规工作,不断地进行监控和优化,如果单个SQL的写入时间长,可以修改后分多次写入。通过查看慢查询日志或show fullprocesslist命令,找出执行时间长的查询语句或大的事务。


问题四:主从复制的设计问题。

例如,主从复制单线程,如果主库写并发太大,来不及传送到从库,就会导致延迟。

更高版本的MySQL可以支持多线程复制,门户网站则会自己开发多线程同步功能。


问题五:主从库之间的网络延迟。

主从库的网卡、网线、连接的交换机等网络设备都可能成为复制的瓶颈,导致复制延迟,另外,跨公网主从复制很容易导致主从复制延迟。

问题六:主库读写压力大,导致复制延迟。

主库硬件要搞好一点,架构的前端要加buffer及缓存层。


5. 通过read-only参数让从库只读访问

read-only参数选项可以让从服务器只允许来自从服务器线程或具有SUPER权限的数据库用户进行更新,确保从服务器不接受来自用户端的非法用户更新。

read-only参数允许数据库更新的条件为:

  • 具有SUPER权限的用户可以更新,不受read-only参数影响,例如:管理员root。

  • 来自从服务器线程可以更新,不受read-only参数影响,例如:前文的rep用户。

在生产环境中,可以在从库Slave中使用read-only参数,确保从库数据不被非法更新。

read-only参数的配置方法如下。

方法一:直接带--read-only参数启动或重启数据库,使用

killall mysqld

mysqladmin -uroot -poldboy123 -S/data/3307/mysql.sock shutdown
mysqld_safe --defaults-file=/data/3307/my.cnf--read-only &

方法二:在my.cnf里[mysqld]模块下加read-only参数重启数据库,配置如下:

[mysqld]
read-only


6.Web用户专业设置方案:MySQL主从复制读写分离集群

专业的运维人员提供给开发人员读写分离的账户设置方法如下:

1)访问主库和从库时使用一套用户密码,例如,用户为web,密码为oldboy123。

2)即使访问IP不同,端口也尽量相同(3306)。例如:写库VIP为10.0.0.7,读库VIP为10.0.0.8。

除了IP没办法修改之外,要尽量为开发人员提供方便,如果数据库前端有DAL层(DBProxy),还可以只给开发人员一套用户、密码、IP、端口,这样就更专业了,剩下的都由运维人员搞定。

下面是授权Web连接用户访问的方案:MySQL主从复制读写分离集群。


方法1:主库和从库使用不同的用户,授予不同的权限。

主库上对web_w用户授权如下:

用户:web_w   密码:oldboy123   端口:3306   主库VIP:10.0.0.7

权限:SELECT,INSERT,UPDATE,DELETE

命令:
GRANT SELECT,INSERT,UPDATE,DELETE ON `web`.* TO 'web_w'@'10.0.0.%' identified by 'oldboy123';

从库上对web_r用户授权如下:

用户:web_r   密码:oldboy123    端口:3306  从库VIP:10.0.0.8

权限:SELECT

命令:
GRANT SELECT ON `web`.* TO 'web_r'@'10.0.0.%' identified by'oldboy123'

提示:此法显得不够专业,但是可以满足开发需求。

方法2:主库和从库使用相同的用户,但授予不同的权限。

主库上对web用户授权如下

用户:web   密码:oldboy123   端口:3306    主库VIP:10.0.0.7

权限:SELECT,INSERT,UPDATE,DELETE

命令:
GRANT SELECT,INSERT,UPDATE,DELETE ON `web`.* TO 'web'@'10.0.0.%'identified by 'oldboy123'
;

从库上对web用户授权如下:

用户:web  密码:oldboy123    端口:3306    主库VIP:10.0.0.8

权限:SELECT

提示:由于主库和从库是同步复制的,所以从库上的web用户会自动和主库保持一致,即无法实现只读select的授权

要实现方法2中的授权方案,有如下两个方法。

一是在主库上创建用户和权限后,从库上revoke收回对应更新权限(insert、update、delete)。

命令为:
REVOKE INSERT,UPDATE,DELETE ONweb.* FROM 'web'@'10.0.0.%';

二是忽略授权库MySQL同步,主库的配置参数如下:

binlog-ignore-db = mysql
replicate-ignore-db = mysql

提示:上面参数等号两边必须有空格。

方法3:在从库上设置read-only参数,让从库只读。

主库从库:主库和从库使用相同的用户,授予相同的权限(非ALL权限)。

用户:web   密码:oldboy123   端口:3306  主库VIP:10.0.0.7,从库VIP:10.0.0.8

权限:SELECT,INSERT,UPDATE,DELETE

命令:
GRANT SELECT,INSERT,UPDATE,DELETE ON web.* TO 'web_w'@'10.0.0.%' identified by 'oldboy123';

由于从库设置了read-only,非super权限是无法写入的,因此,通过read-only参数就可以很好地控制用户,使其不能非法将数据写入从库


老男孩生产工作场景的设置方案如下:

1)忽略授权库MySQL同步,主库配置参数如下:

binlog-ignore-db = mysql
replicate-ignore-db = mysql

提示:上面参数等号两边必须有空格。

2)主库和从库使用相同的用户,但授予不同的权限。

主库上对web用户授权如下:

用户:web  密码:oldboy123  端口:3306   主库VIP:10.0.0.7

权限:SELECT,INSERT,UPDATE,DELETE

命令:
GRANT SELECT,INSERT,UPDATE,DELETE ON web.* TO 'web'@'10.0.0.%' identified by 'oldboy123';

从库上对web用户授权如下:

用户:web  密码:oldboy123  端口:3306  主库VIP:10.0.0.8

权限:SELECT

3)从库设置read-only,增加双保险。

转载于:https://blog.51cto.com/zhaoyulin/1862328

第五章:MySQL主从复制相关推荐

  1. 五、MySQL主从复制原理

    MySQL主从复制原理.半同步操作步骤及原理 标签(空格分隔): mysql 1.1 企业Linux运维场景数据同步方案 1.1.1 文件级别的异机同步方案 1.scp/sftp/nc 命令可以实现远 ...

  2. 第五章 mysql表操作

    1.添加字段 alter table 表名 add 字段 修饰符; mysql> alter table t3 add math int(10);-------添加的字段 mysql> a ...

  3. 第五章· MySQL数据类型

    一.数据类型介绍 二.列属性介绍 一.数据类型介绍 1.四种主要类别  1)数值类型 2)字符类型 3)时间类型 4)二进制类型 2.数据类型的 ABC 要素 1)Appropriate(适当) 2 ...

  4. MySql 主从复制及配置实现

    一.什么是Mysql主从复制 MySQL主从复制是其最重要的功能之一.主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中.对于多级复 ...

  5. MySQL主从复制和基于Amoeba的读写分离部署

    文章目录 MySQL主从复制和基于Amoeba读写分离 什么是主从复制? 为什么要有MySQL主从复制? 什么是读写分离? 一.MySQL主从复制原理 二.主从复制的工作过程 三.主从复制方式 1.异 ...

  6. mysql第五章事务_mysql 第五章 备份恢复

    mysql 第五章 备份恢复 一.备份策略***** 1.每周一次全备,每天一次增量备 2.每天检查备份是否成功 3.每季度进行备份恢复演练 4.设置 -master-data=2 (记录备份的GTI ...

  7. mysql第五章项目二_Todo List:Node+Express 搭建服务端毗邻Mysql – 第五章(第1节)

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 万丈高楼平地起,我们的Todo List项目也是越来越结实了.Todo List的前面4章内容都是在为Client端开发, ...

  8. mysql主从复制 火墙_MySQL高级知识(十五)——主从复制

    前言:本章主要讲解MySQL主从复制的操作步骤.由于环境限制,主机使用Windows环境,从机使用用Linux环境.另外MySQL的版本最好一致,笔者采用的MySQL5.7.22版本,具体安装过程请查 ...

  9. Mysql(五)Mysql架构、数据库优化、主从复制

    文章目录 一.Mysql架构 1.1 查询语句的执行过程 1.1.1 连接器 1.1.2 查询缓存 1.1.3 分析器 1.1.4 优化器 1.1.5 执行器 1.1.6 存储引擎 1.1.7 执行引 ...

最新文章

  1. js 使用a标签 下载资源
  2. 20200605笔记
  3. Linux(Ubuntu,Cent OS)环境安装mkfontscale mkfontdir命令以及中文字库
  4. Linux ALSA 图解
  5. backupexec mysql_MySQL备份可能遇到的坑
  6. 怎样在linux中创建硬盘,在linux中添加新硬盘并创建LVM组
  7. HashMap深度分析
  8. 戴尔商台试机选购指南
  9. 查找文章中出现频率最高的单词
  10. hadoop-2.6.5安装
  11. 第103篇Python:Python爬虫系列之书籍爬取,细节拉满
  12. 机器学习笔记【一】- 线性回归(末):统计学推导以及局部加权线性回归算法实例
  13. linux c获取进程状态,Linux C 获取进程的退出值
  14. 《CDN技术详解》 - CDN知多少?
  15. tkinter教程目录
  16. 梁定郊:一个人行贿赠西藏、新疆狂 野之旅
  17. mysql查看表备注_mysql表中如何查看备注
  18. (ISC)² 2021年会暨网络安全峰会
  19. C++中armadillo矩阵库使用说明
  20. 七问七答 买到假戴森吹风机我该怎么办?

热门文章

  1. schedulewithfixeddelay
  2. 对Java.io中一些类的归纳,层次结构图
  3. 异常处理:.net.UnknownHostException nodename nor servname provided, or not known
  4. Platform 概述
  5. SFuzz: Slice-based Fuzzing for Real-Time Operating Systems
  6. Boosting AdaBoost算法
  7. 数据治理的成功要素2:数据架构设计
  8. MSVCRTD.lib
  9. 第五章——大数定律和中心极限定理
  10. 全文搜索引擎,索引库