MySQL主从多种架构部署及常见错误问题解析

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介:

本文的主要内容有mysql复制原理,mysql一主多从、双主架构的示例解读,以及mysql在主从复制架构实践中的常见错误问题和解决方法。


一 mysql复制原理

1 原理解读

    mysql的复制(replication)是异步复制,即从一个mysql实列或端口(Master)复制到另一个mysql实列的或端口(slave);复制操作由3个进程完成,其中2个(SQL进程和I/O进程)在Slave上,另一个在Master上;要实现复制,必须打开Master端的二进制日志(log-bin),log-bin记录着整个数据对的操作信息,所有slave从master端获取该更新的日志,将其传送到本地并写到本地文件中,然后在读取本地文件内容执行日志中记录的更新操作;slave上已经完整拷贝master数据后,就可以连接到master上然后等待处理更新了。如果master当机或者slave连接断开,slave会定期尝试连接到master上直到能重连并且等待更新.重试的时间间隔由--master-connect-retry选项来控制,它的默认值是60秒。每个slave都记录了它关闭时的日志位置,msater也不知道有多少个slave连接上来或者哪个slave从什么时候开始更新。


2 数据同步实现步骤

    (1)mysql的同步功能由三个线程来实现,master上一个,slave上两个;

    (2)slave启动时,I/O线程连接到mater上,请求master发送二进制日志中的语句;

    (3)mater建立一个I/O线程,把日志内容发送到salve上;

    (4)slave上的I/O线程读取master上的binlog dump发送的语句,并且记录到中继日志relay logs;

    (5)slave开启SQL线程,读取中继日志,然后执行这些语句来更新数据

    slave上开启两个线程很有用:把读日志和执行日志分作两个线程任务处理,执行任务慢的话,读日志的任务不会跟着慢下来,而且读日志任务常常很快就完成,执行任务的sql线程往往需要很久。


二 一主多从架构部署示例及常见故障解决


    1 实验环境分配

        192.168.1.2    master.test.com    

        192.168.1.3    slave1.test.com

        192.168.1.4    slave2.test.com


    2 创建主从复制账号,限定账户在指定服务器登录

在master上创建用户

> grant replication salve on *.* to 'slave1'@'192.168.1.3' identified by '123456';

>grant replication salve on *.* to 'slave2'@'192.168.1.4' identified by '123456';

>flush privileges;


    3 备份已有数据,并复制数据到从节点(如果都是新数据库,可以略去此步)

>flush tables with read lock;

>show matser status;

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

| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB 

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

| mysql-bin.000001|   106      | test               |          

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

tar zcvf /tmp/mysql.tar.gz /var/lib/mysql/

rsync -zrvz --delete /tmp/mysql.tar.gz 192.168.1.3:/tmp/

rsync -zrvz --delete /tmp/mysql.tar.gz 192.168.1.4:/tmp/


    3 解锁

>unlock tables;

Query OK, 0 rows affected (0.00 sec)


    4 配置master服务器,修改mysql的主配置文件

vim /etc/my.cnf

[mysqld] 

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

symbolic-links=0


#### Master ####

server-id                 = 1

log-bin                   = mysql-bin

log-bin-index            = mysql-bin.index

relay-log                = mysql-relay

relay-log-index         = mysql-relay.index

expire-logs-days         = 10

max-binlog-size          = 100M

log-slave-updates        = 1

binlog-do-db             = test

replicate-do-db          = test

binlog-ignore-db         = mysql

replicate-ignore-db     = mysql

如果需要备份多个数据库,那么应该写多行

binlog-do-db=test1

binlog-do-db=test2

replicate-do-db=test1

replicate-do-db=test2

修改完成后重启mysql

/etc/init.d/mysqld restart


    5 配置slave服务器,修改两个从服务器的配置文件,并重启服务(注意修改server-id)

vim /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

symbolic-links=0

server-id = 2


    6 在两个slave上配置开启同步

> CHANGE MASTER TO

    ->   MASTER_HOST='192.168.1.2',

    ->   MASTER_USER='salve1', # 在104 上面改成slave2

    ->   MASTER_PASSWORD='123456',

    ->   MASTER_PORT=3306,

    ->   MASTER_LOG_FILE='mysql-bin.000001',

    ->   MASTER_LOG_POS=106,

    ->   MASTER_CONNECT_RETRY=10;

Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)


mysql> SHOW SLAVE STATUS\G;

            .............

            Slave_IO_Running: Yes

            Slave_SQL_Running: Yes


    7 查看主数据库的状态

>show matser status;        ##查看主数据库状态

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

| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB 

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

| mysql-bin.000001|   106      | test               |          

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

>show processlist;        ##查看复制进程状态


    8 测试验证

验证方法:在主数据库上创建数据库和在test下创建表,到从数据查看数据是否已经同步。

注意:新建的数据库不会同步,因为数据库的更新只设置了test数据库。


    9 故障排除

从服务器上show slave status\G;查看slave状态

Slave_IO_Running,为No,则说明IO_THREAD没有启动,请执行: start slave io_thread;

Slave_SQL_Running为No.则复制出错,查看Last_error字段排除错误后执行: start slave sql_thread;



三 双主互为主备部署解析


    1 实验环境准备      

        192.168.1.2    master1.test.com    

        192.168.1.3    master2.test.com

        和一主多从的步骤是一样的,只是同样的步骤执行2次而已


    2 双主配置

    在masterA上新建一个账户,用户masterB同步数据

masterA操作

> GRANT REPLICATION SLAVE ON *.* TO 'master'@'192.168.1..%' IDENTIFIED BY '123456';   

> FLUSH PRIVILEGES;

> FLUSH TABLES WITH READ LOCK;

 mysqldump -uroot -p123456 --databases test >/tmp/testA.sql

 scp /tmp/testA.sql 192.168.1.103:/tmp

> UNLOCK TABLES;

Query OK, 0 rows affected (0.00 sec)


masterB:上同样的建立复制到账户,并导入数据

mysql> GRANT REPLICATION SLAVE ON *.* TO 'master'@'192.168.1.%' IDENTIFIED BY '123456';mysql> FLUSH TABLES WITH READ LOCK;

mysqldump -uroot -p123456 --databases test >/tmp/testB.sql

scp /tmp/testB.sql 192.168.1.102:/tmp/

# 分别在master1 和 master2上分别导入对方的数据.但是存在一个问题: 因为存在主键冲突的情况,导出数据的时候,不要把主键给导出来了;如果是一方没有数据,那就直接导入数据就好了,不过也要跳过主键;

mysql -uroot -p123456 </tmp/testA.sql 

mysql -uroot -p123456 </tmp/testB.sql 


     3 修改master1和master2 的配置文件 ,只是server-id 不同

master1:的配置文件

vim /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql

#datadir=/mysqldata

socket=/var/lib/mysql/mysql.sock

user=mysql

symbolic-links=0


#### Master ####


server-id                = 1

log-bin                  = mysql-bin

log-bin-index            = mysql-bin.index

relay-log                = mysql-relay

relay-log-index          = mysql-relay.index

expire-logs-days         = 10

max-binlog-size          = 100M

log-slave-updates        = 1

binlog-do-db             = test

replicate-do-db          = test

binlog-ignore-db         = mysql

replicate-ignore-db     = mysql

sync-binlog              = 1

auto-increment-increment = 2

auto-increment-offset   = 1



# master2:的配置文件


 vim /etc/my.cnf 

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

symbolic-links=0


### Master ####


[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

symbolic-links=0


server-id                = 2

log-bin                  = mysql-bin

log-bin-index            = mysql-bin.index

relay-log                = mysql-relay

relay-log-index          = mysql-relay.index

expire-logs-days         = 10

max-binlog-size          = 100M

log-slave-updates

skip-slave-start

slave-skip-errors        = all


binlog-do-db             = test

replicate-do-db          = test

binlog-ignore-db         = mysql

replicate-ignore-db     = mysql


sync-binlog             = 1

auto-increment-increment = 2

auto-increment-offset   = 2


    4 分别在master1和master2上获取File和Position位置

master1:

>flush tables with read lock;

>show matser status;

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

| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB 

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

| mysql-bin.000002|   106      | test               |       mysql   

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

>unlock tables;

master2:

>flush tables with read lock;

>show matser status;

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

| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB 

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

| mysql-bin.000003|   106      | test               |          mysql

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

>unlock tables;


    5 配置主从,分别在master1和 master2上配置对方的从

master1上:

> CHANGE MASTER TO

    ->   MASTER_HOST='192.168.1.3',

    ->   MASTER_USER='master', 

    ->   MASTER_PASSWORD='123456',

    ->   MASTER_PORT=3306,

    ->   MASTER_LOG_FILE='mysql-bin.000003',

    ->   MASTER_LOG_POS=106,

    ->   MASTER_CONNECT_RETRY=10;

Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

master2上:

> CHANGE MASTER TO

    ->   MASTER_HOST='192.168.1.2',

    ->   MASTER_USER='master', 

    ->   MASTER_PASSWORD='123456',

    ->   MASTER_PORT=3306,

    ->   MASTER_LOG_FILE='mysql-bin.000002',

    ->   MASTER_LOG_POS=106,

    ->   MASTER_CONNECT_RETRY=10;

Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

用>show processlist查看进程状态

    6 测试,在其中一个数据库test中创建新表,插入数据,在另一个数据库中查看是否同步。



四 主从复制中常见的故障及解决方法



1 从服务器上show slave status\G;查看slave状态为NO

Slave_IO_Running,为No,则说明IO_THREAD没有启动,请执行: start slave io_thread;

Slave_SQL_Running为No.则复制出错,查看Last_error字段排除错误后执行: start slave sql_thread;


2 主服务器宕机了,如何把从服务器提升会主服务器

在一主多从的环境中,必须选择数据最新的从服务器做新的主服务器,以保证数据的完整可靠。在一主两从的环境中,Server1宕机后,等到Server1和Server2把宕机前同步到的日志都执行完,比较Master_Log_File和Read_Master_Log_Pos就可以判断出谁快谁慢,因为Server2从 Server1同步的数据(1589)比Server3从Server1同步的数据(1293)新,所以应该提升Server2为新的主服务器。


主从复制突然停止了,该怎么处理

复制错误多半是因为日志错误引起的,所以首先要搞清楚是主日志错误还是中继日志错误,从错误信息里就能判断,如果不能判断,则使用下面的mysqlbinlog命令:

shell> mysqlbinlog <MASTER_BINLOG_FILE> > /dev/null

shell> mysqlbinlog <SLAVE_BINLOG_FILE> > /dev/null

# 如果没有错误,则不会有任何输出,反之如果有错误,则会显示出来.

如果是主日志错误,则需要在从服务器设置SET GLOBAL sql_slave_skip_counter

mysql> SET GLOBAL sql_slave_skip_counter = 1;

mysql> START SLAVE;

注:如果有多个错误,可能需要执行多次(提醒:主从服务器数据可能因此不一致)

如果是中继日志错误,只要在从服务器使用CHANGE MASTER TO即可,系统会抛弃当前的中继日志,重新下载。

mysql> CHANGE MASTER TO

MASTER_LOG_FILE=’<Relay_Master_Log_File>’,

MASTER_LOG_POS=<Exec_Master_Log_Pos>;

mysql> START SLAVE;


    另外,不同的应用环境系统总会出现各种各样的错误,处理错误的最重要依据是根据日志中错误信息分析定位故障所在,建议在出现故障时候,不要忙着百度谷歌找答案,先去日志上看看,大部分的应用故障都会有相应的日志输出,通过日志分析错误是基本的”救火之道“。
















本文转自super李导51CTO博客,原文链接: http://blog.51cto.com/superleedo/1897681,如需转载请自行联系原作者

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
9月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
10月前
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
496 3
|
6月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
345 9
|
7月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
184 2
|
8月前
|
关系型数据库 MySQL 分布式数据库
Super MySQL|揭秘PolarDB全异步执行架构,高并发场景性能利器
阿里云瑶池旗下的云原生数据库PolarDB MySQL版设计了基于协程的全异步执行架构,实现鉴权、事务提交、锁等待等核心逻辑的异步化执行,这是业界首个真正意义上实现全异步执行架构的MySQL数据库产品,显著提升了PolarDB MySQL的高并发处理能力,其中通用写入性能提升超过70%,长尾延迟降低60%以上。
|
7月前
|
存储 SQL 关系型数据库
MySQL 核心知识与性能优化全解析
我整理的这份内容涵盖了 MySQL 诸多核心知识。包括查询语句的书写与执行顺序,多表查询的连接方式及内、外连接的区别。还讲了 CHAR 和 VARCHAR 的差异,索引的类型、底层结构、聚簇与非聚簇之分,以及回表查询、覆盖索引、左前缀原则和索引失效情形,还有建索引的取舍。对比了 MyISAM 和 InnoDB 存储引擎的不同,提及性能优化的多方面方法,以及超大分页处理、慢查询定位与分析等,最后提到了锁和分库分表可参考相关资料。
177 0
|
10月前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。
|
8月前
|
关系型数据库 MySQL
MySQL字符串拼接方法全解析
本文介绍了四种常用的字符串处理函数及其用法。方法一:CONCAT,用于基础拼接,参数含NULL时返回NULL;方法二:CONCAT_WS,带分隔符拼接,自动忽略NULL值;方法三:GROUP_CONCAT,适用于分组拼接,支持去重、排序和自定义分隔符;方法四:算术运算符拼接,仅适用于数值类型,字符串会尝试转为数值处理。通过示例展示了各函数的特点与应用场景。
|
10月前
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
5月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
448 158

推荐镜像

更多