MySQL 主从,5 分钟带你掌握

MySQL 主从,5 分钟带你掌握,第1张

MySQL 主从一直是面试常客,里面的知识点虽然基础,但是能回答全的同学不多。

比如楼哥之前面试小米,就被问到过主从复制的原理,以及主从延迟的解决方案,因为回答的非常不错,给面试官留下非常好的印象。你之前面试,有遇到过哪些 MySQL 主从的问题呢?

所谓 MySQL 主从,就是建立两个完全一样的数据,一个是主库,一个是从库, 主库对外提供读写的 *** 作,从库对外提供读的 *** 作 ,下面是一主一从模式:

对于数据库单机部署,在 4 核 8G 的机器上运行 MySQL 5.7 时,大概可以支撑 500 的 TPS 和 10000 的 QPS, 当遇到一些活动时,查询流量骤然,就需要进行主从分离。

大部分系统的访问模型是读多写少,读写请求量的差距可能达到几个数量级,所以我们可以通过一主多从的方式, 主库只负责写入和部分核心逻辑的查询,多个从库只负责查询,提升查询性能,降低主库压力。

MySQL 主从还能做到服务高可用,当主库宕机时,从库可以切成主库,保证服务的高可用,然后主库也可以做数据的容灾备份。

整体场景总结如下:

MySQL 的主从复制是依赖于 binlog 的,也就是记录 MySQL 上的所有变化并以二进制形式保存在磁盘上二进制日志文件。

主从复制就是将 binlog 中的数据从主库传输到从库上,一般这个过程是异步的,即主库上的 *** 作不会等待 binlog 同步的完成。

详细流程如下:

当主库和从库数据同步时,突然中断怎么办?因为主库与从库之间维持了一个长链接,主库内部有一个线程,专门服务于从库的这个长链接的。

对于下面的情况,假如主库执行如下 SQL,其中 a 和 create_time 都是索引:

我们知道,数据选择了 a 索引和选择 create_time 索引,最后 limit 1 出来的数据一般是不一样的。

所以就会存在这种情况:在 binlog = statement 格式时,主库在执行这条 SQL 时,使用的是索引 a,而从库在执行这条 SQL 时,使用了索引 create_time,最后主从数据不一致了。

那么我们改如何解决呢?

可以把 binlog 格式修改为 row,row 格式的 binlog 日志记录的不是 SQL 原文,而是两个 event:Table_map 和 Delete_rows。

Table_map event 说明要 *** 作的表,Delete_rows event用于定义要删除的行为,记录删除的具体行数。 row 格式的 binlog 记录的就是要删除的主键 ID 信息,因此不会出现主从不一致的问题。

但是如果 SQL 删除 10 万行数据,使用 row 格式就会很占空间的,10 万条数据都在 binlog 里面,写 binlog 的时候也很耗 IO。但是 statement 格式的 binlog 可能会导致数据不一致。

设计 MySQL 的大叔想了一个折中的方案,mixed 格式的 binlog,其实就是 row 和 statement 格式混合使用, 当 MySQL 判断可能数据不一致时,就用 row 格式,否则使用就用 statement 格式。

有时候我们遇到从数据库中获取不到信息的诡异问题时,会纠结于代码中是否有一些逻辑会把之前写入的内容删除,但是你又会发现,过了一段时间再去查询时又可以读到数据了,这基本上就是主从延迟在作怪。

主从延迟,其实就是“从库回放” 完成的时间,与 “主库写 binlog” 完成时间的差值, 会导致从库查询的数据,和主库的不一致

谈到 MySQL 数据库主从同步延迟原理,得从 MySQL 的主从复制原理说起:

总结一下主从延迟的主要原因 :主从延迟主要是出现在 “relay log 回放” 这一步,当主库的 TPS 并发较高,产生的 DDL 数量超过从库一个 SQL 线程所能承受的范围,那么延时就产生了,当然还有就是可能与从库的大型 query 语句产生了锁等待。

我们一般会把从库落后的时间作为一个重点的数据库指标做监控和报警,正常的时间是在毫秒级别,一旦落后的时间达到了秒级别就需要告警了。

解决该问题的方法,除了缩短主从延迟的时间,还有一些其它的方法,基本原理都是尽量不查询从库。

具体解决方案如下:

在实际应用场景中,对于一些非常核心的场景,比如库存,支付订单等,需要直接查询从库,其它非核心场景,就不要去查主库了。

两台机器 A 和 B,A 为主库,负责读写,B 为从库,负责读数据。

如果 A 库发生故障,B 库成为主库负责读写,修复故障后,A 成为从库,主库 B 同步数据到从库 A。

一台主库多台从库,A 为主库,负责读写,B、C、D为从库,负责读数据。

如果 A 库发生故障,B 库成为主库负责读写,C、D负责读,修复故障后,A 也成为从库,主库 B 同步数据到从库 A。

1.在主数据库服务器为从服务器添加一个拥有权限访问主库的用户:

GRANT REPLICATION SLAVE ON *.* TO ' test'@'%' IDENTIFIED BY 'test'

(%表示允许所有IP,可设置指定从服务器IP)

添加用户后:

可在从服务器上用mysql -h127.0.0.1 -utest -ptest来测试是否有权限访问主数据库

2.在主据库配置文件加上:

#master config

server-id = 1

log-bin = mysql-bin

3.在从服务器数据库配置文件:

server-id = 2

master-host = 10.0.0.199

master-user = test

master-password = test

replicate-do-db = test

master-port = 3306

log-bin = mysql-bin

如果你的一切配置顺利

你在从服务器上输入命令:show slave status\G

成功情况:

Slave_IO_Running:yes

Slave_SQL_Running:yes

在主服务器上输入show master status

主从数据库同步 可以参考如下:

一、概述

  MySQL从3.23.15版本以后提供数据库复制(replication)功能,利用该功能可以实现两个数据库同步、主从模式、互相备份模式的功能。本文档主要阐述了如何在linux系统中利用mysql的replication进行双机热备的配置。

二、环境

*** 作系统:Linux 2.6.23.1-42.fc8 # SMP(不安装XEN)

Mysql版本:5.0.45-4.fc8

设备环境:PC(或者虚拟机)两台

三、配置

数据库同步复制功能的设置都在MySQL的配置文件中体现,MySQL的配置文件(一般是my.cnf):在本环境下为/etc/my.cnf。

3.1 设置环境:

IP的设置:

A主机 IP:10.10.0.119

Mask:255.255.0.0

B主机 IP:10.10.8.112

Mask:255.255.0.0

在IP设置完成以后,需要确定两主机的防火墙确实已经关闭。可以使用命令service iptables status查看防火墙状态。如果防火墙状态为仍在运行。使用service iptables stop来停用防火墙。如果想启动关闭防火墙,可以使用setup命令来禁用或定制。

最终以两台主机可以相互ping通为佳。

3.2 配置A主(master) B从(slave)模式

3.2.1 配置A 为master

 、增加一个用户同步使用的帐号:

GRANT FILE ON *.* TO ‘backup’@'10.10.8.112' IDENTIFIED BY ‘1234’

GRANTREPLICATION SLAVE ON *.* TO ‘backup’@'10.10.8.112' IDENTIFIED BY ‘1234’

赋予10.10.8.112也就是Slave机器有File权限,只赋予Slave机器有File权限还不行,还要给它REPLICATION SLAVE的权限才可以。

、增加一个数据库作为同步数据库:

create database test

、创建一个表结构:

create table mytest (username varchar(20),password varchar(20))

、修改配置文件:

修改A的/etc/my.cnf文件,在my.cnf配置项中加入下面配置:

server-id = 1 #Server标识

log-bin

binlog-do-db=test #指定需要日志的数据库

、重起数据库服务:

service mysqld restart

查看server-id:

show variable like ‘server_id’;

实例:

mysql>show variables like 'server_id'

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| server_id | 1 |

+---------------+-------+

1 row in set (0.00 sec)

、用show master status/G命令看日志情况。

正常为:

mysql>show master status/G

*************************** 1. row ***************************

File: mysqld-bin.000002

Position: 198

Binlog_Do_DB: test,test

Binlog_Ignore_DB:

1 row in set (0.08 sec)

3.2.2 配置B 为slave

、增加一个数据库作为同步数据库:

create database test

、创建一个表结构:

create table mytest (username varchar(20),password varchar(20))

、修改配置文件:

修改B的/etc/my.cnf文件,在my.cnf配置项中加入下面配置:

server-id=2

master-host=10.10. 0.119

master-user=backup#同步用户帐号

master-password=1234

master-port=3306

master-connect-retry=60 #预设重试间隔秒

replicate-do-db=test#告诉slave只做backup数据库的更新

、重起数据库服务:

service mysqld restart

查看server-id:

show variables like ‘server_id’;

实例:

mysql>show variables like 'server_id'

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| server_id | 2 |

+---------------+-------+

1 row in set (0.00 sec)

、用show slave status/G命令看日志情况。

正常为:

mysql>show slave status/G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 10.10.0.119

Master_User: backup

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysqld-bin.000001

Read_Master_Log_Pos: 98

Relay_Log_File: mysqld-relay-bin.000003

Relay_Log_Pos: 236

Relay_Master_Log_File: mysqld-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB: test,test

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 98

Relay_Log_Space: 236

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 0

1 row in set (0.01 sec)

3.2.3 验证配置

分别使用insert, delete , update在A主机进行增删改查数据库;查看B主机的数据库是否与A主机一致;若一致,则配置成功。

3.3双机互备模式

如果在A主机加入slave设置,在B主机加入master设置,则可以做B->A的同步。

、在A主机的配置文件中 mysqld配置项加入以下设置:

master-host=10.10.8.112

master-user=backup

master-password=1234

replicate-do-db=test

master-connect-retry=10

、在B的配置文件中 mysqld配置项加入以下设置:

log-bin

binlog-do-db=test

注意:当有错误产生时,*.err日志文件同步的线程退出,当纠正错误后,要让同步机制进行工作,运行slave start。

重起A、B机器,则可以实现双向的热备份。

四、常见问题及解决

、Slave机器的权限问题,不但要给slave机器File权限,还要给它REPLICATION SLAVE的权限。

、在修改完Slave机器/etc/my.cnf之后,slave机器的mysql服务启动之前,记得要删除掉master.info

、在show master status或着show slave status不正常时,看看.err是怎样说的。

、Slave上Mysql的Replication工作有两个线程, I/O thread和SQL thread。I/O的作用是从master 3306端口上把它的binlog取过来(master在被修改了任何内容之后,就会把修改了什么写到自己的binlog等待slave更新),然后写到本地的relay-log,而SQL thread则是去读本地的relay-log,再把它转换成本Mysql所能理解的语句,于是同步就这样一步一步的完成.决定I/O thread的是/var/lib/mysql/master.info,而决定SQL thread的是/var/lib/mysql/relay-log.info.

、启动slave,命令用start slave;重新启动用restart slave


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7320372.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-04
下一篇 2023-04-04

发表评论

登录后才能评论

评论列表(0条)

保存