• 一、MySQL主从复制原理

  随机站点访问量的鞥集啊,单台的MySQL服务器压力也不断地增加,此时需要对MySQL进行优化,如果在MySQL优化无明显改善时期,可以使用高可用、主从复制、读写分离、分库分表等方式进行进一步的优化。

  MySQL主从复制的目的是为了实现数据库冗余备份,将master数据库数据定时同步至slave库中,一旦master数据库宕机,可以将web应用数据库配置快速地切换到slave数据库,确保web应用的 可用性,MySQL主从复制架构图如下:

  MySQL主从复制至少需要2台数据库服务器,其中1台为master,一台为slave库,MySQL主从数据同步是一个异步复制的过程,要实现复制首先需要在master上开启bin-log日志功能,bin-log日志用于记录在master库中所执行的增、删、改的SQL语句,整个过程需要开启3个线程,分别是master开启I/O线程,slave开启I/O线程和SQL线程,具体主从同步原理如下:

(1)slave上执行slave start,开启主从复制开关,产生I/O线程和SQL 线程。slave I/O线程会通过在master创建的授权用户连接上至master,并请求master从指定的文件和位置之后发送bin-log日志内容;

(2)master接受到来自slave I/O线程的请求后,首先进行验证,验证通过后,master I/O线程会根据slave I/O线程请求读取指定bin-log日志文件的指定position点之后的bin-log内容,然后返回给slave的I/O线程;

(3)返回的信息当中除了bin-log日志内容以外,还有master最新的bin-log文件名以及在bin-log中的下一个指定更新的position点;

(4)slave I/O线程接到信息后,将收到的日志内容依次添加到slave端的中继日志(relay-log)文件的最末端(MySQL-relay-bin.xxxxx),并将读取到的master端的bin-log的文件名和position点记录到master.info文件当中,以便下一次读取的时候能够告诉master从相应的bin-log文件名和最后一个position点开始发起请求;

(5)slave SQL线程检测到relay-log中内容有更新,会立刻解析relay-log日志中的内容,将解析后的SQL语句在slave中执行,执行成功后slave库和master库数据保持一致。

  • 二、主从复制实战

1、环境说明

HOST OS MySQL version Port Path Master/Slave
192.168.56.11 Centos 7.4

MySQL 5.6.35

3306 /usr/local/mysql/data/ Master
192.168.56.12 Centos 7.4 MySQL 5.6.35 3306 /usr/local/mysql/data Slave

2、配置Master和Slave的my.cnf

[root@master ~]# vim /etc/my.cnf
log-bin=/usr/local/mysql/data/mysql-bin  #开启Master的bin-log日志记录功能
server-id=1  #配置Master的server-id,必须和slave不一样
[root@slave ~]# vim /etc/my.cnf
server-id=2  #配置Slave的server-id

3、在Master上创建主从复制的用户rep并授权

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

mysql> grant replication slave on *.* to rep@'192.168.56.%' identified by '';  #创建主从复制授权用户
Query OK, rows affected (0.03 sec) mysql> flush privileges;  #刷新权限
Query OK, rows affected (0.04 sec) mysql> select user,host from mysql.user;  #查看创建的rep用户
+-----------+--------------+
| user | host |
+-----------+--------------+
| root | % |
| wordpress | % |
| root | 127.0.0.1 |
| rep | 192.168..% |
| root | localhost |
+-----------+--------------+
rows in set (0.03 sec) mysql> show grants for rep@'192.168.56.%';
+---------------------------------------------------------------------------------------------------------------------------+
| Grants for rep@192.168..% |
+---------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.56.%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+---------------------------------------------------------------------------------------------------------------------------+
row in set (0.00 sec)

4、在Master上对数据库进行全备

mysql> flush table with read lock;  #给主库加上读锁(备份结束前,该会话不能关闭,否则binlog的文件名或位置点会有变化
Query OK, rows affected (0.02 sec) mysql> show master status;  #查看主库的binlog日志名称和POS值
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin. | | | | |
+------------------+----------+--------------+------------------+-------------------+
row in set (0.00 sec)

********新开一个xshell窗口进行备份**********
[root@master ~]# mkdir /server/backup -p  #创建数据库备份目录
[root@master ~]# mysqldump -uroot -p123456 -A -B --events |gzip > /server/backup/rep_bak_$(date +%F).sql.gz  #全备Master的库
[root@master ~]# ls -lrt /server/backup/
total
-rw-r--r-- root root Jul : rep_bak_2018--.sql.gz
[root@master ~]# scp /server/backup/rep_bak_2018--.sql.gz root@192.168.56.12:/tools/  #将备份拷贝到Slave上
rep_bak_2018--.sql.gz % 317KB .9MB/s : *********拷贝完成后,进行解锁**********
mysql> unlock tables;

5、在Slave上恢复Master上的数据

[root@slave ~]# gzip -d /tools/rep_bak_2018--.sql.gz
[root@slave ~]# mysql -uroot -p123456 < /tools/rep_bak_2018--.sql

6、在Slave上配置master.info

[root@slave ~]# mysql -uroot -p

mysql> stop slave;
Query OK, rows affected (0.02 sec) mysql> change master to master_host='192.168.56.11',master_user='rep',master_password='', master_log_file='mysql-bin.000005' ,master_log_pos=;
Query OK, rows affected, warnings (0.10 sec)

7、在Slave上启动主从复制

mysql> start slave;  #开启主从复制
Query OK, rows affected (0.02 sec) mysql> show slave status\G  #查看slave上的IO和SQL线程是否运行
*************************** . row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.56.11
Master_User: rep
Master_Port:
Connect_Retry:
Master_Log_File: mysql-bin.
Read_Master_Log_Pos:
Relay_Log_File: slave-relay-bin.
Relay_Log_Pos:
Relay_Master_Log_File: mysql-bin.
Slave_IO_Running: Yes  #表示Slave上的IO线程是否运行
Slave_SQL_Running: Yes  #表示Slave上的SQL线程是否运行

Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno:
Last_Error:
Skip_Counter:
Exec_Master_Log_Pos:
Relay_Log_Space:
Until_Condition: None
Until_Log_File:
Until_Log_Pos:
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master:   #表示落后master的秒数,0表示不落后,正常
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno:
Last_IO_Error:
Last_SQL_Errno:
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id:
Master_UUID: 885e2479-89f6-11e8-a128-000c29ce31fd
Master_Info_File: /usr/local/mysql-5.6./data/master.info
SQL_Delay:
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count:
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position:
row in set (0.00 sec) [root@slave ~]# ll /usr/local/mysql/data/slave-relay-bin.*  #查看从上的relay-log是否生成
-rw-rw---- mysql mysql Jul : /usr/local/mysql/data/slave-relay-bin.
-rw-rw---- mysql mysql Jul : /usr/local/mysql/data/slave-relay-bin.
-rw-rw---- mysql mysql Jul : /usr/local/mysql/data/slave-relay-bin.index

8、测试在Master上的操作是否能同步到Slave上

mysql> create database repppp;  #在主上创建数据库repppp
Query OK, row affected (0.02 sec) mysql> show databases;  #在从上查看是否存在repppp数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| repppp |
| test |
| wordpress |
+--------------------+
rows in set (0.00 sec)

9、总结

(1)异步方式同步
(2) 逻辑同步模式(binlog 有三种模式: SQL、混合、 rowlevel),默认是通过 SQL 语句执行
(3)主库通过记录 binlog 实现对从库的同步
(4)主库 1 个线程(IO 线程),从库 2 个线程(IO 和 SQL)来完成
(5)从库的关键文件: master.info、 relay-log、 relay-info
(6)如果从库还想级联从库,需打开 log-bin 和 log-slave-updates 参数

10、生产场景快速配置 MySQL 主从复制的方案

(1)安装好要配置从库的数据库,配置好 log-bin 和 server-id 参数。
(2)无需配置主库的 my.cnf 文件,主库的 log-bin 和 server-id 参数默认就是配置好的。
(3)登陆主库增加用于从库连接的帐户,并授 replication slave 的权限。
(4)半夜使用 mysqldump 带--master-data=1 参数全备主库,并在从库进行恢复。
(5)在从库执行 change master to 语句,无需 binlog 文件及对应位置点。
(6)在从库开启同步开关 start slave。
(7)从库 show slave status\G,检查同步状态,并在主库进行更新测试。 tips:
(1)主从库服务器的配置差距不要太大。
(2)撰写方案文档和实施步骤。如可能需要停机维护,需要事先申请停机维护时间

 11、遇到的问题

(1)当在执行start slave这条命令时,系统提示 ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO, 执行show slave status;又提示Empty set (0.00 sec)

原因:slave已经默认开启,要先关闭再开启,执行stop slave;   再执行change master to master_host='192.168.56.11',master_user='rep',master_password='123456', master_log_file='mysql-bin.000005' ,master_log_pos=120;

(2)出现错误提示  :Slave_IO_Running:NO ,mysql的error日志中信息: Slave I/O: error connecting to master 'replication@172.16.0.100:3306' - retry-time: 60  retries: 86400, Error_code: 1045

解决方法
1.在主mysql中创建slave远程连接访问时候的登录密码一定要设置对。

2.停止slave上的mysqld服务,从服务器上删除掉所有的二进制日志文件,包括一个数据目录下的master.info文件和hostname-relay-bin开头的文件,然后启动slave上的mysqld服务。

master.info::记录了Mysql主服务器上的日志文件和记录位置、连接的密码。

(3)slave上Slave_SQL_Running: No ,提示某个表定义不正确

解决方法:
清空drop掉master和slave上的已经存在所有表,然后从master库上导入新的数据即可。

MySQL入门篇(四)之MySQL主从复制的更多相关文章

  1. 第二章 MySQL入门篇

    第一章 MySQL入门篇 一.MySql简介 简言: 和SQL Server数据库相同,MySQl也是一个关系型数据库管理系统.由瑞典的MySQL AB公司开发,2008年被SUN公司收购,2009年 ...

  2. 最新MySQL入门篇

    一.SQL简介 ​ SQL:结构化查询语言(Structured Query Language),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系 ...

  3. 【SSRS】入门篇(四) -- 向报表添加数据

    原文:[SSRS]入门篇(四) -- 向报表添加数据 定义好数据集后 [SSRS]入门篇(三) -- 为报表定义数据集 ,就可以开始设计报表了,将要显示在报表的字段.文本框.图像和其他项从工具箱拖放到 ...

  4. FPGA基础入门篇(四) 边沿检测电路

    FPGA基础入门篇(四)--边沿检测电路 一.边沿检测 边沿检测,就是检测输入信号,或者FPGA内部逻辑信号的跳变,即上升沿或者下降沿的检测.在检测到所需要的边沿后产生一个高电平的脉冲.这在FPGA电 ...

  5. MySQL入门篇(七)之Xtrabackup备份与恢复

    一.Xtrabackup介绍 MySQL冷备.mysqldump.MySQL热拷贝都无法实现对数据库进行增量备份.在实际生产环境中增量备份是非常实用的,如果数据大于50G或100G,存储空间足够的情况 ...

  6. MySQL入门篇(三)之my.cnf配置文件详解【转】

    转自:https://www.cnblogs.com/panwenbin-logs/p/8360703.html #*** client options 相关选项 ***# #以下选项会被MySQL客 ...

  7. Docker入门(四)——MySQL镜像中的数据库可视化

      在详细介绍这篇文章的内容前,需要说明下笔者写这篇文章的意图:笔者在现有的开发中,前后端联调的方式为Docker镜像对接,数据库使用MySQL镜像,开发环境为远程服务器,因此,笔者迫切需要一种能将远 ...

  8. MySQL入门篇(一)之MySQL部署

    MySQL 二进制免编译安装 (1)下载二进制免编译版本mysql 5.6.35 [root@localhost tools]# wget http://mirrors.sohu.com/mysql/ ...

  9. MySQL入门篇(二)之常见命令管理

    一.SQL结构化查询语言 SQL,英文全称Structured Query Language,中文意思是结构化查询语言.它是一种对关系数据库中的数据进行定义和操作的语言方法,是大多数关系数据库管理系统 ...

随机推荐

  1. python中基于descriptor的一些概念(下)

    @python中基于descriptor的一些概念(下) 3. Descriptor介绍 3.1 Descriptor代码示例 3.2 定义 3.3 Descriptor Protocol(协议) 3 ...

  2. Input and Output-The input is all the sources of action for your app

    Programs take input and produce output. The output is the result of doing something with the input. ...

  3. 以太网,IP,TCP,UDP数据包分析

    http://www.cnblogs.com/feitian629/archive/2012/11/16/2774065.html 网络层的IP 协议是构成Internet 的基础.IP 协议不保证传 ...

  4. D、CSL 的字符串 【栈+贪心】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551#question 题目描述 CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助. ...

  5. 【JavaScript】富文本编辑器

    这是js写的富文本编辑器,还存在一些bug,但基本功能已经实现,通过这个练习,巩固了js富文本编辑方面的知识,里面包含颜色选择器.全屏.表情.上传图片等功能,每个功能实际对应的就是一个小插件啦 部分程 ...

  6. StackExchange.Redis学习笔记(一) Redis的使用初探

    Redis Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化. 与其它键值数据存储相比,Redis有一组相对丰富的数据类型. Redis可以将数据复制到任意数量的从机中 Redis的安装 官 ...

  7. topk两种解法

    1.这个通过partition实现topk,时间复杂度是o(logn*logn),也就是0(n),但需要修改原数组的顺序 下面这个代码本身有一些错误,并且throw excption会在牛客上报错 c ...

  8. priority_queue详解

    priority_queue是一个安排好的顺序存储的队列,队首是优先级最高的元素. Template<class T , class Container = vector<T> , ...

  9. LoadRunner调用java函数测试oracle

    LoadRunner调用java函数测试oracle 测试oracle的方法有很多,可以使用loadrunner的oracle协议直接调用oracle进行测试,也可以调用开发的java程序对oracl ...

  10. 阅读AuTO利用深度强化学习自动优化数据中心流量工程(一)

    目录 问题 解决方法 模型选择 框架构建 Sigcomm'18 AuTO: Scaling Deep Reinforcement Learning for Datacenter-Scale Autom ...