你是否可以将所有世面上的技术都学一遍?是否都可以学精通?天下武功都学?非也。。。

普通开发者一般会学习到MySQL中的知识点:索引、锁、日志、事务、备份等,下面我漫谈一下我自己学MySQL领悟到的一些东西。仅仅是自己的感悟,有错误请指正,忘海涵!

索引

想到索引首先想到的是数据结构和算法,其实可以再扩展一下:

  • 数组也有索引的思想,通过下标转换拿到元素的真实地址然后操作内存空间,下标和地址的转换函数关系可以理解为索引寻找数据的过程,唯一索引也可以通过B+树直接定位具体一行数据的地址;
  • 索引是数据库的最底层的核心,数据库的数据存储、查找、更新、加锁都依赖它;
  • 为什么是B+树索引、而不是其它数据结构,因为磁盘寻址太慢了,B+ 的数据结果感觉是为了优化磁盘的这个最大弱点;假如未来磁盘可以内存访问速度一样且成本也足够便宜,那么可能B+树的数据解构就不再是最适合数据库了,比如现在流行的TiBD使用的索引数据结构就不是B+树,TiDB要求所有磁盘使用SSD且机器性能必须强劲才能发挥最大效率,这将会是一个趋势;
  • 常用数据库使用的什么索引呢
    • MySQL 使用B+树索引
    • Redis 使用Hash索引
    • ES 使用倒排索引
    • Hbase 的RowKey 可以理解为是hash索引
  • 数据库核心就引擎,引擎的核心就是索引

锁是不陌生,但也十分复杂,MySQL的锁就是为了互斥竞争资源的,可以从这个角度出发;

  • MDL锁:表结构是一个共享资源,因为表结构数据放在.fml 文件中,多线程访问肯定要互斥,因此有MDL锁;
  • 表锁:表的数据是放在 xxx.ibd文件中,如果多线程针对整个表做数据修改肯定需要互斥的,因此有表锁
  • 行锁:每一行数据可以多个线程修改,为了互斥肯定有行锁,这个最好理解
  • 间隙锁:一个线程在一个间隙中插入数据,另一个线程在统计这个间隙中的数据,如果不加锁数据统计结果肯定是错的;举个例子,你在书房里清理一共有多少本书,但是你儿子不断进出书房,拿走一本或放进一本,这样你会怎么办?把门先关了,锁住间歇不让放进来新书,锁住书不让拿走;锁的资源不光可以是具体资源,也可以是抽象资源
  • 锁的类型就如上面讲的,更关键的是锁的加锁规则,什么样的条件下加锁、释放锁、加锁失败后怎么办,一直不释放怎么办?
  • 学了MySQL的锁肯定要类比其它锁;比如Java程序员最熟悉的JDK中的JUC包下面的锁;比如读锁、写锁、公平锁、非公平锁;想一想,其实它们有很多共同的点;
  • 还有常用玩法通过reids 、zk、MySQL实现的分布式锁,它们怎么实现的呢?
  • 还有Java中synchronize关键字对象头的加锁:自选锁、轻量级级锁、重量级锁它们的加锁规则是什么呢?
  • 总结出来锁的核心概念:
    • 锁就是锁住共享资源,多线程访问需要互斥,或者锁进程之间访问需要互斥,或者多个XXX(反正是一个概念)之间访问需要互斥,互斥之后需要有序访问不能造成拥挤或其它意外!
    • 锁的资源可以有大有小,越小肯定越灵活,这就是锁的粒度需要小,这样才会提高并发;
    • 读锁和写锁分离其实就是遵从缩小锁的粒度这个原则;
    • 前面提了锁不管是锁物理资源,还可以锁逻辑资源;
    • 锁资源如果没抢到怎么办呢?如何处理阻塞?
    • 锁资源抢到了一直不释放怎么办?如何处理锁超时?
    • 锁的争抢规则:公平原则,非公平原则,其它原则?
    • 锁的工程实现复杂度,会不会给系统带来过多的成本,比如MySQL的行锁锁的是索引本身,不会带来太多内存开销
    • 锁也是应用层面的东西,其实它依赖操作系统实现,操作系统层面的锁是任何上层锁设计必须依赖的;
    • 操作系统的锁:互斥量、自旋锁???
    • 感觉不管什么场景下的锁,其实核心原则都没变,索引下次遇到任何组件的锁都不要怕

日志

MySQL的日志是一个非常重要的功能,系统的事务,数据的安全都是靠日志保障的;

redo 重做日志

重做日志是针对物理页的变化写的重做日志,重做日志的写入时机是内存数据页写完后再写重做日志,最后数据页再刷磁盘;内存中物理页的变化包括:

  • 数据页变化
  • 索引页变化
  • undo 数据页变化
  • changeBuffer 页变化

重做日志是一个非常经典的设计案例,为了保障数据安全,先写日志再写数据,我们举一反三看看那些组件还有类似的设计:

  • kafka分布式特性中,一个分区有多个副本,当提交数据到主分区的时候,需要写XX(可配置)份副本,当副本和主分区都写成功后这一条数据才算提交到service成功,这其实就是写数据先写副本的思想下的产物,只是这里的副本和MySQL的副本稍微变了一下;
  • Redis的AOF日志,默认每秒讲内存中的数据写一份到磁盘,当集群宕机后可以通过AOF日志迅速恢复所有数据到内存中,最多丢失一秒的数据,这个设计在我看来也是通过给数据写日志来保障数据安全的思想下的产物;
  • ZK,最流行的分布式协调选举组件,当leader发起事务选举的时候,需要超过一半的follower同意,然后整个事务才能提交,follower的同意的原则就是本地数据副本写成功了,那么一份数据多个副本写成功,且控制副本写入成功的数量,这种也是通过给数据写日志来保障数据安全的思想下的产物;只是这个组件给人的整体印象是选举协调,其实底层的原理还是要保障数据一致性,还是通过多写副本(日志)来完成,不要忘了zk 就是一个CP组件,主要保障一致性和可用性
  • ES ,数据库的存储依赖分片键来分区,每个分区设置副本,和kafka高度类似,一份数据写成必须保障XX个副本都写入成功才算成功;ES的副本分区也可以提供查询,kafka的不行,有点细微区别,同理也是副本(日志)思想下的产物
  • 总结:为了写入数据安全(或者叫数据一致性),可以通过写备份日志(或者叫写数据副本)来保障;数据一致性是一个逻辑概念,可以扩展和延伸;写日志备份/写副本也是有点区别但是思想一样;怎么写也不固定;保证数据一致性后,基于这个一致性来实现什么顶层功能这个也可以随意发挥:只为了数据一致性,通过数据一致性来做事务,通过数据一致性来实现分布式锁,通过数据一致性来做业务上的事务消息;

undo 回滚日志

MySQL的回滚日志非常有特色,他是多版本MVCC特性的实现基础。当前数据是最新版本,根据回滚段中的记录的回滚日志可以回滚到任何一个版本的数据;比如 id=1 首先修改成id=2 ,然后修改成id=3,最后修改成id=4,当前最新版本是id=4;id=3,2,1的回滚操作SQL都记录在日志中,且日志通过链表连接;如果需要回滚到id=3则用当前版本id=4加上回滚日志就能得到;如果需要回滚到id=2则用当前版本加回滚日志先回滚到id=3,再加上回滚日志回滚到id=2。这里并不是记录了每个老版本的数据,而是记录了回滚操作的操作SQL,这个很有意思。目前还没在其它组件设计中发现类似的设计思想。

changeBufer 日志

数据插入的时候,如果数据不是唯一索引,则不需要将磁盘中的数据读取到内存中判断唯一性,为了提高插入效率,则把插入的数据先写到changebuffer中,待合适的时间再把数据批量刷回磁盘;整体的设计就是为了解决磁盘读取寻址比较慢,写入寻址慢的问题;changebuffer的数据回顺序写磁盘,以此保障changebuffer中的数据不会丢,且数据页变化后会写redo log 也能保障数据不会丢;changebuffer让我想到了两个主要的设计点:

  • 保证数据安全的前提下延迟写入
  • 保证数据安全的前提下批量写入
  • 顺序写磁盘,为了保证数据安全changeBuffer本身也会顺序将数据写磁盘,顺序写速度很快

联想其它设计:

  • redo log其实也是组提交其实也是批量写,顺序写
  • kafak的日志也是批量写,顺序写
  • 一般接口数据交互为了提高效率也是批量写
  • ES的批处理接口写数据bulkProcessor也是批量写
  • Redis的pipline也是批量写
  • redis的AOF日志也是延迟批量写
  • 总结:只要写磁盘,为了提高写入效率,应用间数据交互为了提高效率都会采用顺序写、批量写、延迟写(异步写),这几乎是通用的玩法。

binlog 日志

MySQL的备份日志,如果你没选择innoDB引擎,binlog是必选的备份方式,如果你选了innoDB引擎,binlog还是必选的备份方式;binlog的核心思想就是把主库的数据变化操作的SQL都拿到从库执行一遍,这个和一般的备份数据是备份数据本身不一样,binlog是备份数据的操作指令,和undolog历史数据备份是通过指令实时回滚出来的有点相似。binlog功能是MySQL的数据高可用的重要保障,而且很方便对数据进行恢复,数据库主从设计依赖此功能,数据库读写分离也依赖此功能。

总结:

  • 说数据一致性,数据安全是程序设计中最核心的问题点一点不为过;
  • 数据安全可以通过备份实现,备份分为不同层面的备份,物理数据备份,逻辑操作指令备份
  • 备份还可以分不同的备份粒度,全局,局部
  • 备份的时机也很多,延迟,实时
  • 这突然让我想到了大学学C语言的时候老师说的程序=数据+算法,其实任何组件都首先必须考虑数据的存储(比如索引),然后考虑数据的安全性一致性(各种备份、副本),最后才是的计算逻辑。

双写缓冲日志

数据页刷脏页的时候,如果系统宕机,数据就会丢;比如数据页是16KB大小,如果写入了一半系统宕机,数据就会丢失;现在刷新脏页的时候首先在双写缓冲池中写一份,然后再刷新脏页到磁盘,如果数据页损坏可以通过双写缓冲池的数据进行页恢复;因为写双写缓冲池是内存操作非常快,且双写缓冲池本身也会批量顺序写磁盘也非常快,所以数据安全是有保障的;

总结:感觉MySQL在任何会出现数据安全问题,数据不一致问题都有策略保障-写备份;为了提高数据操作磁盘的效率,任何设计都体现了顺序写,批量写,延迟写,首先写缓冲;

简单总结学MySQL的最通俗设计点

  • 磁盘读数据慢:

    • 采用预读+缓冲池的设计提高读取效率
    • 采用changebuffer减少查询
    • 采用B+树锁提高搜索效率
  • 磁盘写入数据慢:
    • 组提交,批量写
    • 异步写,采用缓冲池,数据先写缓冲池
    • 顺序写,各种日志buffer写磁盘都是顺序写
    • 页缓存,数据首先写操作系统页缓存,减少操作磁盘,依赖操作系统的稳定性
    • 直接内存操作,提高操作磁盘的效率,减少IO操作次数
  • 为了数据一致性,安全性
    • redo log 重做日志
    • binlog 备份日志
    • 双写缓冲池
  • 为了实现事务的隔离
    • MVCC多版本数据,其实底层依赖就是undo log + redo log
    • 事务其实也依赖锁
  • 各种锁
    • MDL元数据锁
    • 表锁
    • 行锁
    • ​​​​​​​间歇锁
    • 意向读锁
    • 意向写锁

当你在做系统设计的时候,是不是会想到MySQL的某一个设计思想可以参考借鉴,如果能将它的设计思想运用到开发中这才是学MySQL最好的收获,技术永远学不完,只有学明白了底层思想,才能快速的触类旁通,这才是正道!!!

通过学MySQL学活架构设计,举一反十相关推荐

  1. 第5章 MySQL高可用架构设计

    第5章 MySQL高可用架构设计 数据库复制 复制解决了什么问题????? 非共享架构 二进制日志 binlog工具 查看日志格式 show variables like "binlog_f ...

  2. MySQL性能管理及架构设计(二):数据库结构优化、高可用架构设计、数据库索引优化...

    一.数据库结构优化(非常重要) 1.1 数据库结构优化目的 1.减少数据冗余:(数据冗余是指在数据库中存在相同的数据,或者某些数据可以由其他数据计算得到),注意,尽量减少不代表完全避免数据冗余: 2. ...

  3. MySQL性能管理及架构设计(一):什么影响了数据库查询速度、什么影响了MySQL性能...

    一.什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查 ...

  4. 唐成勇 - MySQL性能管理及架构设计

    MySQL性能管理及架构设计(一):什么影响了数据库查询速度.什么影响了MySQL性能 MySQL性能管理及架构设计(二):数据库结构优化.高可用架构设计.数据库索引优化 MySQL性能管理及架构设计 ...

  5. MySQL性能管理及架构设计(三):SQL查询优化、分库分表 - 完结篇

    上一篇:MySQL性能管理及架构设计(二):数据库结构优化.高可用架构设计.数据库索引优化 一.SQL查询优化(重要) 1.1 获取有性能问题SQL的三种方式 通过用户反馈获取存在性能问题的SQL: ...

  6. mysql性能视频教程_[视频教程] MySQL性能管理及架构设计 (完整版)

    第1章 实例和故事 决定电商11大促成败的各个关键因素. 1-1 什么决定了电商双11大促的成败 1-2 在双11大促中的数据库服务器 1-3 在大促中什么影响了数据库性能 1-4 大表带来的问题 1 ...

  7. 什么是真正的架构设计?某厂十年Java经验让我总结出了这些,不愧是我

    本文转载自:什么是真正的架构设计?某厂十年Java经验让我总结出了这些,不愧是我 一. 什么是架构和架构本质 在软件行业,对于什么是架构,都有很多的争论,每个人都有自己的理解. 此君说的架构和彼君理解 ...

  8. 高可用的“异地多活”架构设计

    前言 后台服务可以划分为两类,有状态和无状态.高可用对于无状态的应用来说是比较简单的,无状态的应用,只需要通过 F5 或者任何代理的方式就可以很好的解决.后文描述的主要是针对有状态的服务进行分析. 服 ...

  9. 得物多活架构设计之路由服务设计

    一 .背景 随着公司的业务发展,每次稳定性故障带来的影响越来越大,提供稳定的服务,保证系统的高可用已经变成了整个技术部面对的问题.基于这种背景,公司开展了多云/多活的技术项目,本人有幸参与了 &quo ...

最新文章

  1. r240显卡 linux,NV发布260.19.36正式版Linux驱动 270系列将至
  2. 方法对象java final关键字的用法
  3. LIbGDX 示例Tests详解一:AccelerometerTest
  4. jvm最大内存限制多少?
  5. java实验1_Java程序实验1
  6. eureka多了一个莫名其妙的服务_SpringCloud 服务注册与发现组件 Eureka
  7. 代码中特殊的注释技术——TODO、FIXME和XXX的用处(转)
  8. 钢琴块2电脑版_快陪练教师端电脑版下载_快陪练教师端pc版免费下载[在线教学]...
  9. 【SICP练习】102 练习2.79-2.80
  10. JAVA笔记12__字节、字符缓冲流/打印流/对象流/
  11. chrome最新Android版本,谷歌chrome浏览器安卓版下载,谷歌chrome浏览器安卓最新版本下载地址 v70.0.3538.110 - 浏览器家园...
  12. FireMonkey 做界面的一个小技巧
  13. 计算机有网络却不能上网,电脑有网络,但是浏览器不能上网怎么办
  14. Android全面解析之Window机制
  15. 研究所北航计算机录取分数线,收藏!2020年北京航空航天大学录取分数线大汇总...
  16. 基于Auto.js的淘宝抢购助手+京东双十一活动助手。亲测运行正常!
  17. 3种好用的可视化图表工具分享,快进来看!
  18. 振作起来重新开始学习java吧!!!
  19. 网吧无盘系统服务器安装,网吧网络无盘系统的安装方法
  20. 【2】SCI易中期刊推荐——遥感图像领域(中科院2区)

热门文章

  1. springboot项目实现人脸对比
  2. 机器学习 SVM感想
  3. c语言程序设计中数据类型有哪些,c语言中基本数据类型有哪些
  4. win系统中切换左alt和win键的功能
  5. 程序员,你喜欢抽哪种香烟?基于Python的数据分析哦~
  6. 微信小程序 java银行业务管理系统python php
  7. Echar line 图标前台封装JS
  8. linux(Debian11)安装后安装无线网卡等驱动
  9. 温度传感器的工作原理
  10. p116数据查询作业