Mysql学习
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
一、概览
1、Server架构
A、初始化模块:在Server启动时对系统进行初始化操作;buffer、cache结构的初始化和内存空间清空、系统变量的初始化设定、各种存储引擎的初始化设置等;
B、核心API:提供一些底层操作功能的优化实现,如底层数据结构的实现、特殊算法的实现,字符串&数字处理等、格式化输出、内存管理等;
C、网络交互模块:抽象出底层网络交互所使用的接口api,实现底层网络数据的接收与发送;
D、Client&Server交互协议模块;
E、用户模块:用户的登录连接权限控制与授权管理;
F、访问控制模块:实时监控访问者的动作,根据用户模块中不同用户的权限,控制用户对数据的访问;
G、连接管理、连接线程、线程管理:
连接管理:监听和接受对Mysql Server的请求,转发到线程管理模块;
连接线程:负责server与client的通信,接受client的命令请求,传递Server端结果信息;
线程管理:维护这些连接线程,如创建、线程cache等;
H、Query解析与转发:连接线程直接将query传递给该模块,该模块将query进行语义和语法分析,然后按不同的操作类型进行分类,分发给对应模块进行处理。
I、Query Cache:将客户端提交的select类query请求的返回结果集cache到内存中,与该query的hash值做对应。与该query的hash值做对应。该query所取数据的基表发生任何数据变化之后,该cache自动失效。适用于读写比例非常高的应用系统,但对内存消耗较大。
J、Query优化器:根据query语句和数据库中的统计信息,在一系列算法的基础上进行分析,得出最优策略,告诉后面的程序如何获取该query语句的结果;
K、表变更管理模块:完成一些DML和DDL的query,如update、delete、insert、create/alter table等语句的处理;
L、表维护模块:表的状态检查、错误恢复、优化、分析;
M、表管理器:维护表定义文件(*.frm文件)以及表结构信息、table级别的锁管理;
N、系统状态管理模块:负责在客户端请求系统状态的时候,将各种状态数据返回给用户,eg:show status等;
O、日志记录模块:系统级别的日志记录,如error log、binary log、slow query log等;
P、复制模块:分为Master和slave两部分,Master主要负责在replication环境中读取Master端的binary日志,以及与slave端的i/o线程交互工作;slave主要是两个线程,一个负责从Master请求和接收binary日志,并写入本地relay log中的i/o线程;一个负责从relay log中读取相关日志事件,并解析成可以在slave端正确执行的命令,执行该命令会得到与Master端完全相同的结果命令,将该命令交给slave执行的SQL线程。
Q、存储引擎接口模块:抽象类,将各种数据抽象处理,实现可插拔存储引擎。
工作流程
初始化:
执行启动命令后,初始化模块从配置文件中读取参数,初始化系统;同时各个存储引擎也被启动,并进行各自的初始化工作;
连接管理模块启动处理客户端连接请求的监听程序;
客户端请求:
使用Client&Server模块定义的协议,连接管理模块将连接请求转发给线程管理模块,请求一个连接线程;
线程管理模块 通知连接线程模块,需要建立连接;
连接线程模块接到连接请求后,首先通过调用用户模块进行授权检查;
通过授权检查后,连接线程模块检查当前连接线程池中是否有cache空闲连接线程,如果有,取出一个与客户端请求连接上,如果没有,建立一个新的连接线程。
query处理:
连接线程模块将收到的query语句转给Query解析和转发模块,该模块先对query进行基本的语义和语法解析,然后根据命令类型不同,有些会直接处理,有些会分发给其他模块处理
1)如果是一个Query类型的请求,query解析器首先分析看是不是一个select,如果是,则查询缓存模块,看Query cache中是否已存在;
A、如果有,直接返回给连接线程模块,然后通过CS模块将数据传输给客户端;
B、如果未被cache,转发给query优化模块;
2)如果是DML或者DDL语句,转发给表变更管理模块,再分别由insert、delete、update、create、alter处理器负责不同的DML和DDL处理;
3)如果是更新统计信息、检测、修复、整理类,转发给表维护模块;
4)如果是复制相关,转发给复制模块;
。。。。
各模块接收到分发过来的请求,会先通过访问控制模块检查连接用户是否有访问目标表及目标字段的权限,如果有再调用表管理模块请求相应的表,获取对应的锁;
表管理模块首先查看该表是否已经存在于table cache中,如果已经打开则直接进行锁相关的处理,否则,需要打开表文件获取锁,然后将打开的表交给表变更模块;
表变更模块获取表后,会根据表的meta信息,判断表的存储引擎类型和相关信息,根据存储引擎类型,提交请求给存储引擎接口模块,调用对应的存储引擎实现模块进行相应处理;
处理完成(成功或者失败)后,将处理结果(resultSet或者是状态标识)通过连接线程模块返回给客户端;
连接线程模块进行相应的清理工作,等待请求,直到客户端断开连接;
如果在处理过程中,数据库中的数据发生了变化,且打开了binlog功能,相关的处理模块还会调用日志模块将相应的变更语句以更新事件的形式记录到指定的二进制日志文件中;
在各模块处理过程中,各自的核心运算处理依赖核心API模块,如内存管理、文件i/o、数字和字符串处理等;
mysql官方文档
https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html#order-by-filesort
2、物理存储
日志文件:
binary log & binary log index:将所有修改数据库的query以二进制形式记录到日志文件中,包括所执行的时间、消耗的资源、以及相关的事物信息,所以binlog是事物安全的;index记录的是所有binary log的绝对路径,保证mysql各线程能顺利找到需要的binary log文件;
query log:记录所有query,包括select,一般慎用;
slow query log:记录执行时间较长的query,采用简单文本格式,记录执行时刻,消耗的时间,执行用户,连接主机等相关信息。
error log:
innodb redo log:redo日志中记录了innodb所做的所有物理变更和事物信息,通过在线redo日志和记录在表空间中的udo信息保证indo的事物安全性;
想要保证事物的原子性,需要在发生异常时,对已经执行的操作进行回滚,在innodb中,所有事物进行的修改都会先记录到这个redo log中,然后再对数据库进行写入;
回滚日志除了能再发生错误时或者用户执行rollback时提供回滚相关的信息,还能在系统发生崩溃、数据库进程被直接杀死后,当用户再次重启数据库进程时,能够立刻通过查询回滚日志将之前未完成的事物进行回滚,所以需要先写回滚日志再持久化到磁盘上。
数据文件:
.frm文件:与表相关的元数据信息,包括表结构定义信息等,每个表一个,官方说明:https://dev.mysql.com/doc/internals/en/frm-file-format.html
.idb/.ibdata文件:innodb专有,存储表数据:
.idb:独享表空间,每表一个;
ibdata:共享表空间,多表一个或多个;
.MYD文件:MyISAM专有,表数据,每一个表一个;
.MYI文件:MyISAM专有,表索引信息,每个表一个;
Replication文件
master.info:存放于slave端的数据目录下,保存master的主机地址、连接用户、连接密码、连接端口、当前日志位置、已经读取到的日志位置等信息;
relay log和relay log index;
relay-log.info:
其他
- system config file
- pid file
- socket file
二、存储引擎
存储引擎是数据库服务器的组件,负责在物理服务器层面上维护的基本数据进行实际操作。MySQL自5.1起引入插件式存储引擎体系结构,支持将存储引擎加载到正在运行的MySQL服务器中,允许数据用户为特定的应用需求选择专门的存储引擎,在存储级别上提供了标准的管理的支持服务集合,将应用程序与存储引擎的底层实现隔离开来。MySQL自5.5.5版本以后,Innodb为MySQL的默认存储引擎。
各种存储引擎使用比较 show engines;
https://www.cnblogs.com/chenwenlong/articles/1939744.html
(-)Innodb
1、架构
2、索引实现
A、Innodb索引实现
1)Innodb的数据文件本身就是索引文件
2)辅助索引(secondary index):数据只存主键;
c)特点:灾难恢复性好;支持4种级别的事务,默认事务的隔离级别是Repeatable Read,事务支持是通过MVCC多版本并发控制来提供的;使用行级锁,并发性能高;数据的物理组织形式是簇表,数据按主键来组织,即主键索引和数据是在一起的(参考B+树);实现缓冲管理,能缓存索引也能缓存数据;支持外键;支持热备份
B、MyISAM索引实现
1)使用B+树作为索引结构,叶子节点的data域存放的是数据记录地址;
2)配合锁,实现操作系统下的复制备份,迁移;数据紧凑存储,可以获得更快的索引和更快的全表扫描性能;支持全文索引;使用表级锁并发性差;主机宕机后,表容易损坏,灾难恢复性不佳;无事务支持;只缓存索引,数据缓存利用操作系统缓冲缓冲区实现的,引发过多系统调用,性能不佳
OLTP与OLAP
1、OLTP(on-line transction processing)
主要是执行基本的日常事物处理;
特点:
A、实时性要求高;
B、数据量不是很大,生产库上的数据量一般不会太大,而且会及时做出相应的数据处理与转移;
C、交易一般是确定;
D、高并发,且满足ACID原则;
2、OLAP(on-line analytical processing)
是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,典型的应用是复杂的报表系统;
特点:
A、实时性要求不高;
B、数据量大;
C、查询一般是动态的,自定义的,维度概念在OLAP中非常重要。
三、事务
事物是并发控制的基本单位,是一个序列操作,要么都执行,要么都不执行。
1、原子性(atomic)
undo log (回滚日志):
想要保证事物的原子性,需要在异常发生时对已经执行的操作进行回滚,在mysql中,通过undo log实现,所有事物进行的修改都会先记录到这个undo log中,然后再对数据库中对应进行操作。
并行事物的原子性可能引发(cascading Rollback)级联回滚,
2、持久性(consistency)
3、隔离性(isolated)
4、一致性(durable)
四、索引
五、表设计规范
(一)范式
(二)分库分表
(三)其他建议
六、master slave replication过程;各种常见存储的replication过程比较,比如redis、kafka
七、主从切换 HA
八、Benchmark
其他
(一)分库分表:https://my.oschina.net/stephenzhang/blog/650225
1、海量数据存储与访问是系统设计的瓶颈问题,解决问题:
分库分表:分库降低了单点机器的负载;分表提高了数据操作的效率;
负载均衡策略:降低单台机器的访问负载,降低空压机的可能性;
集群方案:解决了数据库空压机带来的单点数据库不能访问的问题;
读写分离策略:最大限度提高了应用中读取数据的速度与并发量;
2、分库分表要解决的问题
事物问题:
方案一:使用分布式事物
优点:交由数据管理,简单有效;
缺点:性能代价高,特别是shard越来越多的时候;
方案二:由应用程序和数据库共同控制
原理:将跨多个数据库的分布式分布式事物拆成多个仅处于单个数据库上面的小事物,并通过应用程序来总控各个小事物;
优点:性能上有优势
缺点:需要应用程序在事物处理上做灵活设计
跨节点;
跨节点Join:
方案:普遍做法是分两次查询实现,在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据;
跨节点的COUNT、Order by、Group by以及聚合函数的问题,各节点上得到结果后在应用程序中进行合并,但如果结果集很大,对应用程序内存的消耗是个问题;
事物:
分布式事物:https://www.geek-share.com/detail/2549275102.html
基于两阶段提交,最大限度地保证了跨数据库操作的原子性,是分布式系统下最严格的事物实现方式;
是系统水平伸缩的死敌,基于两阶段提交的分布式事物在提交事物时需要在多个节点之间进行协调,最大限度的推后了提交事物的时间点,客观上严延长了事物的执行时间,会导致事物在访问共享资源时发生冲突和死锁的概率增高,随着数据库节点的增多,这种趋势会越来越严重。
事物补偿:对性能要求很高,但对一致性要求不高的系统,往往不可求系统的实时一致性,只要在一个允许的时间周期内达到最终一致性即可,此时可以通过补偿机制实现。不同于事物在执行过程中立即回滚的方式,事物补偿是一种事后检查并补救的措施,它只期望在一个容许时间周期内得到最终一致的结果就可以了。常用的事物补偿实现方式有,对数据进行对账检查;基于日志进行对比;定期同标准数据来源进行同步等。
ID问题:无法依赖数据库自身的主键生成机制,常见的生成策略:
UUID:简单,但比较长,建立索引和基于索引进行查询时都存在性能问题;
在数据库中维护一个sequence表:简单,但任何插入时候都需要访问该表,该表容易成为系统性能瓶颈,且存在单点问题;
snowflake雪花模型;
跨shard的排序分页:
如果是前台应用提供分页, 限定用户只能看前n页,如果需要看后面的分页可以可以缩小查找范围重新查询;
如果是后台批处理任务要求分批获取数据,可以加大page size,注意一般离线走备库,避免冲击主库;
有些分页查询可以考虑走大数据平台。
路由透明:
分库的逻辑应该尽量与业务逻辑无关,所以要尽量保证分库对应用代码透明,分库逻辑尽量在数据访问层处理。对于单库查询,则该SQL只需访问特定库就行,此时应该由DAL层自动路由到特定库,当库二次分裂时,也只要修改mod因子,应用代码不受影响;对于简单的多库查询,DAL负责汇总各个数据库的返回记录,此时仍对上层应用程序透明
- MySql学习之Join查询
- MySQL学习笔记(四)_排序查询
- MySql 学习笔记三:常用SQL优化
- MySQL学习笔记一
- MySQL学习笔记19:系统信息函数
- MySQL学习笔记之七 查询、修改和删除
- MyBatis学习(一)、MyBatis简介与配置MyBatis+Spring+MySql
- MySQL EXPLAIN 命令详解学习
- mysql学习-基本语句
- 数据库(Mysql)背后的数据结构-学习
- MySQL学习笔记(五)_函数基本概念and字符函数
- mysql 学习记录(十四)--模式
- Mysql学习笔记十二——数据类型
- (大数据工程师学习路径)第五步 MySQL参考手册中文版----MySQL函数和操作符
- python开发学习-day09(队列、多路IO阻塞、堡垒机模块、mysql操作模块)
- mysql 5.0存储过程学习总结
- mysql学习系列:Error:1005错误之errno:105
- MySQL学习总结(1)
- MySQL学习(7)varchar
- MYSQL学习笔记-常见表约束