基于 MySQL 主从模式搭建上万并发的系统架构

来源:html

https://my.oschina.net/u/4205711/blog/3104493mysql


1、主从复制基础概念linux

在了解主从复制以前必需要了解的就是数据库的二进制日志(binlog),主从复制架构大多基于二进制日志进行。

1.1 二进制日志管理说明sql

二进制日志在哪?如何设置位置和命名?shell

在my.cnf文件中使用 log-bin = 指定;命名规则为 mysql-bin.000000 (后为6位数字)数据库

二进制日志位置安全

mysql> show variables like '%log_bin%' ;
+---------------------------------+-----------------------------------------+
| Variable_name | Value |
+---------------------------------+-----------------------------------------+
| log_bin | ON |
| log_bin_basename | /application/mysql/data/mysql-bin |
| log_bin_index | /application/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+-----------------------------------------+
6 rows in set (0.06 sec)

日志命名:服务器

mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 2979 |
| mysql-bin.000002 | 120 |
+------------------+-----------+
2 rows in set (0.00 sec)

二进制日志记录什么?二进制日志中记录的是一个个完成的事件网络

二进制日志格式是怎样的?推荐使用row格式架构

查看当前使用的日志格式:

mysql> show variables like '%format%';
+--------------------------+-------------------+
| Variable_name | Value |
+--------------------------+-------------------+
| binlog_format | ROW |
| date_format | %Y-%m-%d |
| datetime_format | %Y-%m-%d %H:%i:%s |
| default_week_format | 0 |
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
| time_format | %H:%i:%s |
+--------------------------+-------------------+
8 rows in set (0.00 sec)

二进制日志如何滚动?每次重启都会刷新日志,也能够经过命令进行刷新 reset master;

二进制日志用来干吗?备份恢复,起始点的备份恢复

二进制日志的操做命令?查看都有哪些二进制日志

mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 2979 |
| mysql-bin.000002 | 167 |
| mysql-bin.000003 | 120 |
+------------------+-----------+
3 rows in set (0.00 sec)

查看当前使用的二进制日志文件:

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

binlog相关详情参照:

http://www.cnblogs.com/clsn/p/8087678.html#_label6

1.2 mysql传统备份方式和缺陷

  1. 二进制日志备份

  2. mysqldump

  3. 必须有数据库服务器完成逻辑工做,须要更多地cpu周期

  4. 逻辑备份还原速度慢:须要MySQL加载和解释语句、转化存储格式、重建引擎

  5. xtrabackup

  6. 文件大

  7. 不老是能够跨平台、操做系统和MySQL版本

1.3 MySQL主从复制能为咱们作什么

  • 高可用

  • 辅助备份

  • 分担负载

2、MySQL主从复制介绍

2.1 复制技术

做用:

  • 保证数据安全(异机实时备份)

  • 保证服务持续运行(宕机接管)

主从复制实现基本原理

  • 自带功能,复制是 MySQL 的一项功能,容许服务器将更改从一个实例复制到另外一个实例。

  • 主服务器将全部数据和结构更改记录到二进制日志中。

  • 从属服务器从主服务器请求该二进制日志并在本地应用其内容。即经过把主库的binlog传送到从库,重新解析应用到从库。

2.2 复制架构

mysql复制的应用常见场景:

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

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

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

传统的 MySQL复制提供了一种简单的主–从复制方法,有一个主,以及一个或多个从。

主节点执行和提交事务,而后将它们(异步地)发送到从节点,以从新执行(在基于语句的复制中)或应用(在基于行的复制中)。

这是一个 shared-nothing 的系统,默认状况下全部 server 成员都有一个完整的数据副本。

 

640

(图)MySQL 异步复制

还有一个半同步复制,它在协议中添加了一个同步步骤。

这意味着主节点在提交时须要等待从节点确认它已经接收到事务。只有这样,主节点才能继续提交操做。

 

640

(图)MySQL 异步复制

在上面的两个图片中,能够看到传统异步 MySQL 复制协议(以及半同步)的图形展现。

蓝色箭头表示在不一样 server 之间或者 server 与 client 应用之间的信息交互。

2.3 MySQL主从复制原理介绍

复制过程:

  • 开启binlog日志,经过把主库的binlog传送到从库,重新解析应用到从库。

  • 复制须要3个线程(dump、io、sql)完成,5.6从库多个sql。

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

复制前提:

  • 主服务期必定要打开二进制日志

  • 必须两台服务器(或者是多个实例)

  • 从服务器须要一次数据初始化

  • 若是主从服务器都是新搭建的话,能够不作初始化

  • 若是主服务器已经运行了很长时间,能够经过备份将主库数据恢复到从库

  • 主库必需要有对从库复制请求的用户。

  • 从库须要有relay-log设置,存放从主库传送过来的二进制日志:

  • show variables like '%relay%';

  • 在第一次的时候,从库须要change master to 去链接主库。

  • change master信息须要存放到master.info中 :

  • show variables like '%master_info%';

  • 从库怎么知道,主库发生了新的变化?经过relay-log.info记录的已经应用过的relay-log信息。

  • 在复制过程当中涉及到的线程

  • 从库会开启一个IO thread(线程),负责链接主库,请求binlog,接收binlog并写入relay-log。

  • 从库会开启一个SQL thread(线程),负责执行relay-log中的事件。

  • 主库会开启一个dump thrad(线程),负责响应从IO thread的请求。

主从怎么实现的?

  • 经过二进制日志

  • 至少两台(主、从)

  • 主服务器的二进制日志“拿”到从服务器上再运行一遍。

  • 经过网络链接两台机器,通常都会出现延迟的状态。也能够说是异步的。

640

 

2.4 执行原理--第一次开启主从过程

  • 从库经过手工执行change master to 语句链接主库,提供了链接的用户一切条件:

  • (user、password、port、ip)

  • 而且让从库知道,二进制日志的起点位置(file名 position号)

  • start slave

  • 从库的IO和主库的dump线程创建链接

  • 从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求

  • 主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程

  • 从库IO线程接收binlog evnets,并存放到本地relay-log中,传送过来的信息,会记录到master.info中。

  • 从库SQL线程应用relay-log,而且把应用过的记录到relay-log.info,默认状况下,已经应用过的relay会自动被清理purge。

到此为止,一次主从复制就完成

一旦主从运行起来:就不须要手工执行change master to,由于信息都会被存放到master.info(user、password、port、ip,上次获取过的binlog信息file和position)中。

详细的mysql replication 过程

 

640

 

3、 主从搭建配置

本次主从搭建使用mysql多实例进行实验。多实例配置参考文档进行配置:

http://www.cnblogs.com/clsn/p/8038964.html#_label8

3.1 多实例数据库slave配置

系统环境说明:

[root@db02 ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
[root@db02 ~]# uname -r
2.6.32-696.el6.x86_64
[root@db02 ~]# /etc/init.d/iptables status
iptables: Firewall is not running. # 注意:务必关闭防火墙(iptables selinux)
[root@db02 ~]# getenforce
Disabled
[root@db02 ~]# mysql --version
mysql Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using EditLine wrapper

一、启动多实例数据库

[root@db02 ~]# /data/3306/mysql start
Starting MySQL...
[root@db02 ~]# /data/3307/mysql start
Starting MySQL...

二、配置文件说明:

master 配置文件说明:

[root@db02 ~]# cat /data/3306/my.cnf
[client]
port = 3306
socket = /data/3306/mysql.sock
[mysqld]
user = mysql
port = 3306
socket = /data/3306/mysql.sock
basedir = /application/mysql
datadir = /data/3306/data
log-bin = /data/3306/mysql-bin
server-id = 6 # server id 不能相同
skip_name_resolve = 0 # 跳过域名解析参数
[mysqld_safe]
log-error=/data/3306/mysql_3306.err
pid-file=/data/3306/mysqld.pid

slave 配置文件说明:

[root@db02 ~]# cat /data/3307/my.cnf
[client]
port = 3307
socket = /data/3307/mysql.sock
[mysqld]
user = mysql
port = 3307
socket = /data/3307/mysql.sock
basedir = /application/mysql
datadir = /data/3307/data
log-bin = /data/3307/mysql-bin
server-id = 7 # server id 不能相同
skip_name_resolve = 0 # 跳过域名解析参数
read_only = 1 # 从库只读 (非root用户 )
[mysqld_safe]
log-error=/data/3307/mysql_3307.err
pid-file=/data/3307/mysqld.pid

三、在主库建立复制用户

登录到主数据库中:

mysql -uroot -p123 -S /data/3306/mysql.sock

建立受权用户,注意是slave用户。

grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

四、初始化从库数据

备份主库当前数据

mysqldump -uroot -p123 -A -B -F --master-data=2 -S /data/3306/mysql.sock >/tmp/full.sql

部分参数说明:

  • -F 刷新二进制日志

  • --master-data [=#]这会致使二进制日志的位置和文件名被追加到输出中。若是等于1,则将其打印为CHANGE MASTER命令; 若是等于2,那么该命令将以注释符号为前缀。

到从库进行恢复

mysql -uroot -p123 -S /data/3307/mysql.sock

恢复备份的数据

set sql_log_bin=0;
source /tmp/full.sql

五、开启从库复制

查看备份的当前使用的文件及POS号

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

登入数据库,进行slave配置。

mysql -uroot -p123 -S /data/3307/mysql.sock
CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000012',
MASTER_LOG_POS=120;
start slave; # 启动从库复制

该配置想关说明能够经过 help 得到。

mysql> help CHANGE MASTER TO
CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com',
MASTER_USER='replication',
MASTER_PASSWORD='bigs3cret',
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;

3.2 测试主从同步

查看slave库的状态,主要查看:

Slave_IO_Running与Slave_SQL_Running是否都为Yes

主库进行操做,在从库验证

[root@db02 ~]# mysql -uroot -p123 -S /data/3306/mysql.sock
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database clsn;
Query OK, 1 row affected (0.00 sec)

在从库上能够看到该数据库已建立

[root@db02 ~]# mysql -uroot -p123 -S /data/3307/mysql.sock
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| clsn |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)

至此mysql主从复制就搭建完成

3.3 忘记数据库密码?

shell> /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-tables --skip-networking &
mysql> update user set password=password('123') where user='root' and host='localhost';
mysql> flush privileges;

3.4 主从复制状态失败的缘由?

Last_IO_Error: error reconnecting to master 'repl@10.0.0.52:3306' - retry-time: 60 retries: 1

缘由:

  • 主机没启动,或者宕机,检查主库的状态。

  • 网络通讯问题,使用ping命令进行检查;或使用mysql命令进行shell端登录测试

  • 防火墙,selinux(务必检查)

  • 复制用户和密码、端口号、地址有问题,使用mysql命令进行shell端登录测试。

  • mysql自动解析,会将链接的IP解析成主机名(skip-name-resolve = 0)写入my.cnf文件便可。

  • 从库IO异常关闭,经过show slave status \G 进行查看。

4、MySQL主从复制常见问题

4.1 从库binlog落后主库binlog?

从库记录的已经主库已经给我传送的binlog事件的坐标,通常在繁忙的生产环境下会落后于主库

show master status\G --- 主
show slave status \G --- 从
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 729

落后太远的缘由:

  • 硬件条件有关的,机器磁盘IO性能不足。

  • 主要仍是网络问题,网络传输的性能。

  • 主库存放二进制日志的存储性能过低,建议binlog日志存咋SSD中。

  • 主库DUMP线程太繁忙,主要发生在一主多从的环境下。

  • 从库IO线程太忙

  • 人为控制(delay节点、延时节点 )

4.2 主库update,从库迟迟的没有更新

特殊状况日志已经传过来了,数据并无同步

通常状况:

  • 没开启SQL线程

  • 传的东西有问题(你要作的事情,我提早已经作了,不想重复作了,而后他就死了)

  • SQL线程忙

  • 人为控制了【delay(从库)节点、延时节点,通常生产设置为3-6小时之间,能够保证过去3-6小时之间的误操做,能够避免】

4.3 主从复制延时配置(从库配置)

中止从库复制

mysql>stop slave;
Query OK, 0 rows affected (0.01 sec)

修改延时参数,MASTER_DELAY,单位位S (秒)。

mysql>CHANGE MASTER TO MASTER_DELAY = 30;
Query OK, 0 rows affected (0.07 sec)

启动从库复制

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

查看配置是否生效

mysql> show slave status \G
……
SQL_Delay: 30

4.4 从库安全配置(其余用户只读)

修改my.cnf配置文件,添加只读参数

read_only = 1 ====> 控制普通用户
innodb_read_only = 1 ====> 控制root用户,正常状况不要加

添加完成后重启数据库

mysql> show variables like '%read_only%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_read_only | OFF |
| read_only | ON |
| tx_read_only | OFF |
+------------------+-------+
3 rows in set (0.00 sec)

延时从库: delay节点、延时节点

4.5 主从复制故障及解决(跳过错误)

命令行设置

stop slave; #<==临时中止同步开关。
set global sql_slave_skip_counter = 1 ; #<==将同步指针向下移动一个,若是屡次不一样步,能够重复操做。
start slave;

在配置文件修改,设置要跳过的pos

/etc/my.cnf
slave-skip-errors = 1032,1062,1007

在mysql中能够跳过某些错误,可是最好的解决办法,从新搭建主从复制。

4.6 延时节点概念 --> SQL线程延时?

Last_SQL_Errno: 0
Last_SQL_Error:

缘由:

  • 主库作操做的对象,在从库不存在

  • 主库作操做的对象属性不一致

  • 主库作操做的对象,从库已经存在

……

4.7 Slave_*_Running:?

  • Slave_IO_Running I/O 线程正在运行、未运行仍是正在运行但还没有链接到主服务器。可能值分别为Yes、No 或 Connecting。

  • Slave_SQL_Running SQL线程当前正在运行、未运行,可能值分别为Yes、No

  • 主服务器日志坐标:Master_Log_File 和 Read_Master_Log_Pos 标识主服务器二进制日志中 I/O 线程已经传输的最近事件的坐标。

  • 若是Master_Log_File和Read_Master_Log_Pos 的值远远落后于主服务器上的那些值,这表示主服务器与从属服务器之间事件的网络传输可能存在延迟。

4.8 中继日志坐标

Relay_Log_File 和 Relay_Log_Pos 列标识从属服务器中继日志中 SQL 线程已经执行的最近事件的坐标。

这些坐标对应于 Relay_Master_Log_File 和 Exec_Master_Log_Pos 列标识的主服务器二进制日志中的坐标。

若是 Relay_Master_Log_File 和 Exec_Master_Log_Pos 列的输出远远落后于 Master_Log_File 和Read_Master_Log_Pos 列(表示 I/O 线程的坐标)

这表示 SQL 线程(而不是 I/O 线程)中存在延迟。即,它表示复制日志事件快于执行这些事件。

4.9 单一主从须要改变的地方

从库的做用

一、至关于实时备份

二、使用从库备份

三、一主多从应对读多的业务需求

若是,从库只作备份服务器用,那么主库的压力会不减反增。由于,全部的业务都在主库实现,读和写,dump线程读取并投递binlog

解决方案:

  • 可不能够挪走一部分读业务到从库,读写分离

  • 一主多从应对读多的业务需求,一旦发展成这个架构,dump线程投递binlog的压力更大

  • 多级主从,采用中间库缓解主库dump的压力,会出现中间库瓶颈的问题,选择blackhole引擎,看性能与安全的权衡

  • 双主模型:缓解,数据一致性难保证

  • 环状复制


【推荐阅读

[技术]:分布式 RPC 框架性能大比拼

[技术]:咱们公司使用了 6 年的分布式锁,非常牛逼啊!

[技术]:细思极恐 - 你真的会写Java吗

[技术]:提高10倍生产力:IDEA远程一键部署SpringBoot到Docker

[技术]:用了这么久 IDEA ,你居然不知道有个功能叫自动补全!


640?wx_fmt=jpeg

相关文章
相关标签/搜索