Mysql高级知识概括
- Mysql简介
- MysqlLinux版本的安装
- Mysql配置文件
- Mysql逻辑架构介绍
- Mysql存储引擎
- 慢查询日志
- 批量数据脚本
- 全局查询日志
- Mysql锁机制
- 主重复制与读写分离
- Mysql分区
Mysql简介
简介:
高级MySQL:
- mysql内核
- sql优化工程师
- mysql服务器的优化
- 查询语句优化
- 主重复制
- 软硬件升级
- 容灾备份
- sql编程
完整的mysql优化需要很深的功底,大公司甚至有专门的DBA写上述
MysqlLinux版本的安装
Mysql配置文件
二进制日志log-bin:
错误日志log-error:
- 默认是关闭的,记录严重的警告和错误信息,每次启动和关闭的详细信息等.
查询日志log:
- 默认关闭,记录查询的sql语句,如果开启会减低mysql的整体性能,因为记录日志也是需要消耗系统资源的(对应下面介绍的慢查询日志)
数据文件:
- 两系统:
windows:D:\ProgramFiles\MySQL\MySQLServer5.5\data目录下可以挑选很多库
linux:看看当前系统中的全部库后再进去,默认路径:/var/lib/mysql
- frm文件:
存放表结构
- myd文件:
存放表数据
- myi文件:
存放表索引
如何配置:
- windows:
my.ini文件
- Linux:
/etc/my.cnf文件
Mysql逻辑架构介绍
- 1、Connectors
指的是不同语言中与SQL的交互
- 2、 Management Serveices & Utilities:
系统管理和控制工具
- 3、 Connection Pool: 连接池
管理缓冲用户连接,线程处理等需要缓存的需求。
负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,
接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。
- 4、 SQL Interface: SQL接口。
接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
- 5、 Parser: 解析器。
SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本。
在 MySQL中我们习惯将所有 Client 端发送给 Server 端的命令都称为 query ,在 MySQL Server 里面,连接线程接收到客户端的一个 Query 后,会直接将该 query 传递给专门负责将各种 Query 进行分类然后转发给各个对应的处理模块。
主要功能:
a . 将SQL语句进行语义和语法的分析,分解成数据结构,然后按照不同的操作类型进行分类,然后做出针对性的转发到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。
b. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的
- 6 、Optimizer: 查询优化器。
SQL语句在查询之前会使用查询优化器对查询进行优化。就是优化客户端请求的 query(sql语句) ,根据客户端请求的 query 语句,和数据库中的一些统计信息,在一系列算法的基础上进行分析,得出一个最优的策略,告诉后面的程序如何取得这个 query 语句的结果
他使用的是“选取-投影-联接”策略进行查询。
用一个例子就可以理解: select uid,name from user where gender = 1;
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤
这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤
将这两个查询条件联接起来生成最终查询结果
- 7、 Cache和Buffer: 查询缓存。
他的主要功能是将客户端提交 给MySQL 的 Select 类 query 请求的返回结果集 cache 到内存中,与该 query 的一个 hash 值 做一个对应。该 Query 所取数据的基表发生任何数据的变化之后, MySQL 会自动使该 query 的Cache 失效。在读写比例非常高的应用系统中, Query Cache 对性能的提高是非常显著的。当然它对内存的消耗也是非常大的。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等
- 8 、存储引擎接口
存储引擎接口模块可以说是 MySQL 数据库中最有特色的一点了。目前各种数据库产品中,基本上只有 MySQL 可以实现其底层数据存储引擎的插件式管理。这个模块实际上只是 一个抽象类,但正是因为它成功地将各种数据处理高度抽象化,才成就了今天 MySQL 可插拔存储引擎的特色。
从图2还可以看出,MySQL区别于其他数据库的最重要的特点就是其插件式的表存储引擎。MySQL插件式的存储引擎架构提供了一系列标准的管理和服务支持,这些标准与存储引擎本身无关,可能是每个数据库系统本身都必需的,如SQL分析器和优化器等,而存储引擎是底层物理结构的实现,每个存储引擎开发者都可以按照自己的意愿来进行开发。
注意:存储引擎是基于表的,而不是数据库。
Mysql存储引擎
查看命令:
MyISAM和InnoDB:
阿里巴巴,淘宝用哪个:
慢查询日志
慢查询日志是什么:
慢查询日志说明:
查看是否开启及如何开启:
开启慢查询日志后,什么样的SQL参会记录到慢查询里面?
查看当前多少秒算慢:
SHOW VARIABLES LIKE ‘long_query_time%’;
设置慢的阙值时间:
为什么设置后看不出变化?
- ①需要重新连接或者新开一个回话才能看到修改值。 SHOW VARIABLES LIKE ‘long_query_time%’;
- ②show global variables like ‘long_query_time’;
记录慢SQL并后续分析:
查询当前系统中有多少条慢查询记录:
日志分析工具mysqldumpshow:
- 查看mysqldumpshow的帮助信息:
- 工作常用参考:
批量数据脚本
全局查询日志
注意:
- 永远不要在生产环境开启这个功能。
- 一般在测试环境中使用此功能。
Mysql锁机制
概述:
锁的分类:
- 从数据操作的类型(读、写)分:
①读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响
②写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
- 从对数据操作的颗粒度:
①表锁
②行锁
表锁(偏读):
- 特点:
偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发最低
行锁(偏写):
- 特点:偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
- 无索引或索引失效时行锁升级为表锁。(因为Innodb引擎是根据索引来实现行锁的,如果不存在索引,那么就不能对此行加record lock,而mysql为了防止错误,只好全部锁定了。)
- 间隙锁危害
- 面试题:常考如何锁定一行。
- 结论:
- 触发机制:
innodb的行锁是根据索引触发,如果没有相关的索引,那行锁将会退化成表锁(即锁定整个表里的行)。而锁锁定的是索引即索引树里面的数据库字段的值。
- 链接:mysql 如何触发行锁_MySQL的锁到底有多少内容?
- 优化建议:
①尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
②合理设计索引,尽量缩小锁的范围
③尽可能较少检索条件,避免间隙锁
④尽量控制事务大小,减少锁定资源量和时间长度
⑤尽可能低级别事务隔离
页锁:
- 开销和加锁时间界于表锁和行锁之间:会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
主重复制与读写分离
复制的基本原理:
底层主要依靠二进制日志文件(binary log)
。
- 复制的基本原则:
①每个slave只有一个master
②每个slave只能有一个唯一的服务器ID
③每个master可以有多个salve
- 复制最大问题:延时
- 一主一从常见配置:
①mysql版本一致且后台以服务运行
②主从都配置在【mysqld】结点下,都是小写
- 步骤:
①主机修改my.ini配置文件
②从机修改my.cnf配置文件
③主机从机都关闭防火墙
④在Windows主机上简历账户并授权slave
⑤在Linux从机上配置需要复制的主机
⑥主机新建库、新建表、insert记录,从机复制
⑦如何停止从服务复制功能:stop slave;
主从复制的作用:
- 一是
确保数据安全;做数据的热备
,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据的丢失。
①数据分为主表和历史表
,历史表是容灾备份表
。
- 二是提升I/O性能;随着日常生产中业务量越来越大,I/O访问频率越来越高,单机无法满足,此时做多库的存储,有效降低磁盘I/O访问的频率,提高了单个设备的I/O性能。
- 三是读写分离,使数据库能支持更大的并发;在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。
读写分离:
-
MySQL读写分离是指让master处理写操作,让slave处理读操作,非常适用于读操作量比较大的场景,可减轻master的压力。
-
使用mysql-proxy实现mysql的读写分离,mysql-proxy实际上是作为后端mysql主从服务器的代理,它直接接受客户端的请求,对SQL语句进行分析,判断出是读操作还是写操作,然后分发至对应的mysql服务器上。
-
mysql-proxy是官方提供的mysql中间件产品可以实现负载平衡,读写分离,failover等
-
MySQL Proxy就是这么一个中间层代理,简单的说,MySQL Proxy就是一个连接池,负责将前台应用的连接请求转发给后台的数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。
-
当然,这样proxy机器可能成为单点失效,但完全可以使用多个proxy机器做为冗余,在应用服务器的连接池配置中配置到多个proxy的连接参数即可。
MySQL架构演进:从主从复制到分库分表:
-
背景:
①业务飞速发展导致数据规模急速膨胀,单机的数据库已经无法满足互联网业务的发展。
②传统的将数据集中存储单一数据结节的方案,在容量、性能、可用性和可维护性方面已经难以满足互联网海量数据的场景。
<1>从容量方面考虑,单机数据库容量有限,难以扩容。
<2>从性能方面来说,由于关系型数据库大多数采用B+树类型索引,在数据量超过一定的阈值后,索引的深度增加导致对磁盘的随机IO次数增加,进而导致性能问题。
<3>从可用性方面来说,服务通常设计成无状态的,这必然导致系统的存储压力都集中在数据库层面,而单一的数据节点,或者简单的主从架构,已经越来越难以承担。
<4>从运维角度来看,当数据都集中在一个节点上时,数据备份和恢复的时间成本也随之数据量上升变得不可控。同时数据丢失导致影响的范围也会被放大。
-
解决:
①主从复制:高可用,读写分离读写分离:提高性能,1主N从,让读不成为系统瓶颈。
②分库:垂直方向提高系统性能。
③分表:水平方向提高系统性能。
④分区:水平方向提高性能。
-
例子:比如订单表,往往是系统瓶颈,那么可以把订单表专门用一台服务器(分库),采用主从复制,在数据库出错时尽快恢复,设置利用HA机制实时把从变成主。性能还不够,就多搞几个从服务器,读数据从从服务器读取。实现读写分离。要是还不够,可以把奇数用户放一个表,偶数用户放一个表。还可以把3个月前的订单放一个表。或者利用分区功能,按用户id对N取模,放N个分区里。以上方式都是在不改变数据库既有技术↓实现的性能提升,大部分应用都可以通过以上方式在传统数据库下达到性能要求。要是还不行,只能从新找出路了,如nosql,分布式数据库。
-
链接:
①聊聊MySQL架构演进:从主从复制到分库分表
②数据库主从复制,读写分离,负载均衡,分库分表分别表达的什么概念?
Mysql分区
MySQL分区表介绍:
- 分区是一种表的设计模式,正确的分区可以极大地提升数据库的查询效率,完成更高质量的SQL编程。但是如果错误地使用分区,那么分区可能带来毁灭性的的结果。
- 分区功能并不是在存储引擎层完成的,因此不只有InnoDB存储引擎支持分区,常见的存储引擎MyISAM、NDB等都支持分区。但是并不是所有的存储引擎都支持,如CSV、FEDORATED、MERGE等就不支持分区。在使用此分区功能前,应该对选择的存储引擎对分区的支持有所了解。
- MySQL数据库在5.1版本时添加了对分区的支持,分区的过程是将一个表或索引分解为多个更小、更可管理的部分。就访问数据库的应用而言,从逻辑上讲,只有一个表或一个索引,但是在物理上这个表或索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。
- MySQL数据库支持的分区类型为水平分区(指将同一个表中不同行的记录分配到不同的物理文件中),并不支持垂直分区(指将同一表中不同列的记录分配到不同的物理文件中)。此外,MySQL数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引。而全局分区是指,数据存放在各个分区中,但是所有数据的索引放在一个对象中。目前,MySQL数据库还不支持全局分区。
- 可以通过以下命令来查看当前数据库是否启用了分区功能:
show global variables like '%partition%';
MySQL分区类型:
- RANGE分区:我们介绍的第一种分区类型是RANGE分区,也是最常用的一种分区类型,基于属于一个给定连续区间的列值,把多行分配给分区。
- LIST分区:LIST分区和RANGE分区类似,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择,而非连续的。
- HASH分区:HASH分区的目的是将数据均匀地分布到预先定义的各个分区中,保证各分区的数据量大致都是一样的。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在HASH分区中,MySQL自动完成这些工作,用户所要做的只是基于将要进行哈希分区的列值指定一个列值或表达式,以及指定被分区的表将要被分隔成的分区数量。
- LINER HASH:MySQL还支持线性哈希功能,它与常规哈希的区别在于,线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则,而常规哈希使用的是求哈希函数值的模数。
- KEY分区:KEY分区和HASH分区相似,不同之处在于HASH分区使用用户定义的函数进行分区,支持字符串HASH分区,KEY分区使用MySQL数据库提供的函数进行分区,这些函数基于与PASSWORD()一样的运算法则。
- COLUMNS:在前面说了RANGE、LIST、HASH和KEY这四种分区中,分区的条件是:数据必须为整形(interger),如果不是整形,那应该需要通过函数将其转化为整形,如YEAR(),TO_DAYS(),MONTH()等函数。MySQL5.5版本开始支持COLUMNS分区,可视为RANGE分区和LIST分区的一种进化。COLUMNS分区可以直接使用非整形的数据进行分区,分区根据类型直接比较而得,不需要转化为整形。此外,RANGE COLUMNS分区可以对多个列的值进行分区。