MySQL架构优化实战系列2:主从复制同步与查询性能调优

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

一、主从复制同步部署

 

1、概念


  • 主从复制:2台以上mysql服务器, 做负载均衡, 主服务器负责增删改 , 从服务器负责查询

  • 同步原理:mysql开启bin-log日志,主服务器所有的增删改操作会记录到bin-log日志;然后主服务器把bin-log日志发送 给 从服务器 , 从服务器重放bin-log日志 确保数据同步


2、开启bin-log日志


  • 配置 my.cnf 文件 并重启 mysql


[root@localhost etc]# vim /etc/my.cnf

 

 

[root@localhost etc]# service mysql restart


  • 开启之后 mysql-bin对应的文件 已经出现


[root@localhost var]# cd /usr/local/mysql/var && ll



  • 通过 show master status 命令查看 最新一个binlog日志 及开始行数


mysql> show master status;



  • 查看binlog日志内容 可见 最新一行日志在位置107


$ /usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/var/mysql-bin.000001



  • 测试删除数据 可见 binlog文件新增日志内容




3、bin-log日志相关命令


  • flush logs


新建一个binlog日志,增删改日志在新文件中插入,新的日志end-log-positon 是107行,107行记录了mysql内部日志。



  • reset master


清空所有bin-log日志 只保留 mysql-bin.000001 文件


  • mysqlbinlog


查看bin-log日志/usr/local/mysql/bin/mysqlbinlog/usr/local/mysql/var/mysql-bin.00001


  • show binlog events 查看binlog记录事件



  • mysqlbinlog mysql -uroot -psmudge smudge_database



重放bin-log日志、恢复数据:其实就是再把日志中的sql语句执行一边而已。(注意:select 语句 和delete语句 不可以放在一起重放 因为你最后还是得不到数据)


恢复原理就是:执行之前的insert语句,或者之前的update语句 
如果你的单纯的delete物理删除,别想恢复了,因为再次执行的还是delete语句


4、create 创建用户 + grant用户授权


  • 主服务器查看用户密码


mysql> select host,user,password from mysql.user;



  • 添加主服务器用户密码


CREATE USER 'kang'@'192.168.206.132' IDENTIFIED BY 'smudge';


创建用户kang 可以在ip为192.168.206.132主机上访问数据库



给用户kang授权所有的库的权限



5、主服务器配置


主服务器ip:192.168.206.128


  • 配置主服务器my.cnf 文件


vim /etc/my.cnf



  • 配置之后刷新binlog文件


flush logs with read lock 确保获得一致性快照,等待主从binlog日志同步完毕达到数据一致


  • 或者使用mysqldump备份sql 文件


将主服务器一致都是sql文件备份,传递到从服务器

mysqldump -uroot -psmudge smudge -l -F > '/home/smudge.sql'


-l 是指锁表 防止新数据插入

-F 是刷新 生成一个新的binlog日志


(如果你数据库中有merge表 容易会提示Unable to open underlying table which is differently defined or ofnon-MyISAM type ordoesn't exist when using LOCK TABLES )



  • 使用scp隧道传输命令 传递文件


scp /home/smudge.sql 192.168.206.132:/home



6、从服务器配置


  • 恢复一部分主服务器备份的数据


新建smudge库



mysql导入sql文件


[root@localhost ~]# mysql -uroot -psmudge smudge < /home/smudge.sql


  • 配置从服务器my.cnf文件


vim /etc/my.cnf


其中用户名和密码就是上述我们在主服务器添加的信息



(如果你的mysql版本5.1(mysql>status查看)之前的,配置这4项,启动之后就不必使用change master 命令 进行主动同步)


保存并重启mysql


  • 查看主服务器master binlog文



  • 启动slave进程,开启主从同步


因为我的mysql版本是5.7的, 所以我使用change master命令



  • show slave status 查看从服务器状态



表明同步功能已经开启


7、从服务器常用命令


start slave 启动复制线程

stop slave 停止复制线程

show master logs 查看主数据库日志 

change master to master_host ,master_user 动态切换主数据库

show processlist 查看运行进程 (主动服务器都适用)


8、常见错误排错


  • show slave status 检查主动状态


20 数值为NO

21 数值为NULL


表明同步出现了故障,可能是slave服务器执行了写操作或者从服务器重启有事务回滚操作。


  • 解决


从服务器: stop slave 关闭复制线程

主服务器:show master status 查看最新二进制文件和位置偏移量

从服务器执行:change master to master_host ...
master_log_file='mysql-bin.000005',master_log_pos=759 命令


二、查询性能优化


1、查询执行基础知识


  • mysql执行查询过程


  客户端将查询发送到服务器
② 服务器检查查询缓存 如果找到了就从缓存返回结果 否则进行下一步
③ 服务器解析,预处理和优化查询,生成执行计划
④ 执行引擎调用存储引擎api执行查询
⑤ 服务器将结果发送回客户端



  • mysql客户端/服务器协议


该协议是半双工通信,可以发送或接收数据,但是不能同时发送和接收决定了mysql的沟通简单又快捷;


缺点:无法进行流程控制,一旦一方发送消息,另一方在发送回复之前必须提取完整的消息,就像抛球游戏,任意时间,只有某一方有球,而且有球在手上,否则就不能把球抛出去(发送消息)


  • mysql客户端发送/服务器响应


可以设定max_packet_size这个参数控制客户端发送的数据包(一旦发送数据包,唯一做的就是等待结果)


服务器发送的响应由多个数据包组成, 客户端必须完整接收结果,即使只需要几行数据,也得等到全部接收 然后丢掉,或者强制断开连接。(这两个方法好挫,所以我们使用limit子句呀!!)


也可以理解,客户端从服务器 "拉" 数据 ,实际是服务器产生数据 "推"到客户端, 客户端不能说不要 是必须全部装着!


常用的Mysql类库 其实是从客户端提取数据 缓存到array(内存)中,然后进行 foreach 处理。


但是对于庞大的结果集装载在内存中需要很长时间,如果不缓存,使用较少的内存并且可以尽快工作,但是应用程序和类库交互时候,服务器端的锁和资源都是被锁定的。


  • 查询状态
     

每个mysql连接都是mysql服务器的一个线程 任意一个给定的时间都有一个状态来标识正在发生的事情。


使用 show full processlist 命令查看 


 

mysql中一共有12个状态:休眠、查询、锁定、分析和统计、拷贝到磁盘上的临时表、排序结果、发送数据,通过这些状态 知道 "球在谁手上"。


  • 查询缓存


解析一个查询,如果开启了缓存,mysql会检查查询缓存,发现缓存匹配,返回缓存之前,检查查询的权限。


2、优化数据访问


查询性能低下最基本的原因是访问了太多的数据,分析两方面:


① 查明应用程序是否获取超过需要的数据 通常意味着访问了过多的行或列

    查明mysql服务器是否分析了超过需要的行


  • 向服务器请求了不需要的数据


一般请求不需要的数据,再丢掉他们,造成服务器额外的负担,增加网络开销,消耗了内存和cpu。


典型的错误:

① 提取超过需要的行 => 添加 limit 10 控制获取行数
② 多表联接提取所有列 => select fruit.* from fruit left join fruit_juice where
.....
③ 提取所有的列 => select id,name... from fruit ... (有时提取超过需要的数据便于复用)

 

  • mysql检查了太多数据


简单的开销指标:执行时间、检查的行数、返回的行数
 

以上三个指标写入了慢查询日志 可以使用 mysqlsla工具进行日志分析:


① 执行时间:执行时间只是参考 不可一概而论 因为执行时间 和服务器当时负载有关

② 检查和返回的行:理想情况下返回的行和检查的行一样,但是显示基本不可能 比如联接查询

  检查的行和访问类型: 使用explain sq语句,观察typ列



typ列:(访问速度依次递增)


① 全表扫描(full table scan)
② 索引扫描(index scan)
③ 范围扫描(range scan)
④ 唯一索引查找(unique index lookup)
⑤ 常量(constant)


可见type列为index即sql语句,基于索引扫描:


rows列为12731,即扫描了12731行 extra列为using index,即使用索引过滤不需要的行


mysql会在3种情况下使用where子句,从最好到最坏依次是:


① 对索引查找应用where子句来消除不匹配的行 这发生在存储层
② 使用覆盖索引(extra 列 "using index") 避免访问行 从索引取得数据过滤不匹配的行 这发生在服务层不需要从表中读取行
③ 从表中检索出数据 过滤不匹配的行(extra:using where)


如果发现访问数据行数很大,尝试以下措施:


① 使用覆盖索引 ,存储了数据 存储引擎不会读取完整的行
② 更改架构使用汇总表
③ 重写复杂的查询 让mysql优化器优化执行它


3、重构查询的方式


优化有问题的查询,其实也可以找到替代方案,提供更高的效率。


  • 复杂查询和多个查询


mysql一般服务器可以每秒50000个查询,常规情况下,使用尽可能少的查询 有时候分解查询得到更高的效率。


  • 缩短查询


分治法,查询本质上不变,每次执行一小部分,以减少受影响的行数。比如清理陈旧的数据,每次清理1000条:

delete from message where create < date_sub(now(),inteval 3 month)  

limit 1000


防止长时间锁住很多行的数据。


  • 分解联接


把一个多表联接分解成多个单个查询 然后在应用程序实现联接操作



第一眼看上去比较浪费,因为增加了查询数量,但是有重大的性能优势:


① 缓存效率高,应用程序直接缓存了表 类似第一个查询直接跳过

② 对于myisam表来说 每个表一个查询有效利用表锁 查询锁住表的时间缩短

③ 应用程端进行联接更方便扩展数据库

④ 使用in() 避免联表查询id排序的耗费

⑤ 减少多余行的访问 , 意味着每行数据只访问一次 避免联接查询的非正则化的架构带来的反复访问同一行的弊端


分解联接应用场景:


① 可以缓存早期查询的大量的数据

② 使用了多个myisam表(mysiam表锁 并发时候 一条sql锁住多个表 所以要分解)

③ 数据分布在不同的服务器上

④ 对于大表使用in() 替换联接

    一个联接引用了同一个表很多次


  • 提取随机行



  • 分组查询


  • 外键


只有Innodb引擎支持外键,myisam可以添加外键但是没有效果。


主表添加主键id,从表添加外键id引用主表的id。


表student


表student_extend


为student_extend添加外键,外键指向student表中的id列,在delete时触发外键。


表student数据


表student_extend数据


删除表student一条数据,则外键表就会触发外键,删除对应数据:


delete from student where id = 2;



  • 优化联合查询



  • 优化max() min()


其中 name 没有索引。



对一个表同时进行select和update。

本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2016-06-24

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
安全 关系型数据库 MySQL
如何将数据从MySQL同步到其他系统
【10月更文挑战第17天】如何将数据从MySQL同步到其他系统
218 0
|
2月前
|
SQL 关系型数据库 MySQL
mysql主从复制概述和配置
【10月更文挑战第22天】MySQL 主从复制是一种将主服务器的数据复制到一个或多个从服务器的技术,实现读写分离,提高系统性能和可用性。主服务器记录变更日志,从服务器通过 I/O 和 SQL 线程读取并应用这些变更。适用于读写分离、数据备份和恢复、数据分析等场景。配置步骤包括修改配置文件、创建复制用户、配置从服务器连接主服务器并启动复制进程。
|
2月前
|
监控 关系型数据库 MySQL
深入了解MySQL主从复制:构建高效稳定的数据同步架构
深入了解MySQL主从复制:构建高效稳定的数据同步架构
130 1
|
1月前
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
2月前
|
存储 关系型数据库 MySQL
MySQL主从复制原理和使用
本文介绍了MySQL主从复制的基本概念、原理及其实现方法,详细讲解了一主两从的架构设计,以及三种常见的复制模式(全同步、异步、半同步)的特点与适用场景。此外,文章还提供了Spring Boot环境下配置主从复制的具体代码示例,包括数据源配置、上下文切换、路由实现及切面编程等内容,帮助读者理解如何在实际项目中实现数据库的读写分离。
MySQL主从复制原理和使用
|
2月前
|
SQL 关系型数据库 MySQL
Mysql中搭建主从复制原理和配置
主从复制在数据库管理中广泛应用,主要优点包括提高性能、实现高可用性、数据备份及灾难恢复。通过读写分离、从服务器接管、实时备份和地理分布等机制,有效增强系统的稳定性和数据安全性。主从复制涉及I/O线程和SQL线程,前者负责日志传输,后者负责日志应用,确保数据同步。配置过程中需开启二进制日志、设置唯一服务器ID,并创建复制用户,通过CHANGE MASTER TO命令配置从服务器连接主服务器,实现数据同步。实验部分展示了如何在两台CentOS 7服务器上配置MySQL 5.7主从复制,包括关闭防火墙、配置静态IP、设置域名解析、配置主从服务器、启动复制及验证同步效果。
Mysql中搭建主从复制原理和配置
|
2月前
|
SQL 存储 关系型数据库
Mysql主从同步 清理二进制日志的技巧
Mysql主从同步 清理二进制日志的技巧
31 1
|
3月前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
364 11
|
2月前
|
安全 数据安全/隐私保护 UED
优化用户体验:前后端分离架构下Python WebSocket实时通信的性能考量
在当今互联网技术的迅猛发展中,前后端分离架构已然成为主流趋势,它不仅提升了开发效率,也优化了用户体验。然而,在这种架构模式下,如何实现高效的实时通信,特别是利用WebSocket协议,成为了提升用户体验的关键。本文将探讨在前后端分离架构中,使用Python进行WebSocket实时通信时的性能考量,以及与传统轮询方式的比较。
71 2
|
26天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。