四、带着问题学习MySql_框架_事务隔离级别_innodb_B-tree_B+Tree

    MySql最重要的、与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理及其他系统任务和数据的存储/提取相分离。这种处理和存储分离的设计可以在使用时,根据性能、特性,以及其他需求来选择数据存储的方式。
1、MySql服务器的架构是什么?
  
MySql服务器的逻辑架构图如下:
    1)客户端连接/线程处理层:包含连接处理、授权认证、安全等
2)解析器、查询缓存层:查询解析、分析优化、缓存、及内置函数所有跨存储引擎的功能都在这一层实现(存储过程、触发器、视图等)
3)优化器:包含存储引擎,其负责MySql中数据的存储和提取,服务器通过API与存储引擎进行通信。但是存储引擎不会解析SQL。
优化器并不关心表使用的是什么存储引擎,但是存储引擎对于优化查询是有影响的,优化器会请求存储引擎提供内容或某个具体操作的开销信息,以及表数据的统计信息。
4)存储引擎:数据和索引统计信息由存储引擎实现,不同的存储引擎可能会存储不同的统计信息。例如:Archive引擎,则根本就没有存储任何统计信息。

2、MySql查询执行过程?
  
当向MySQL 发送给一个请求的时候,MySQL的处理过程如下图:
  
  1)客户端发送一条查询给服务器;
  2)服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段;
  3)服务器端进行SQL解析并创建内部数据结构(解析树)、对数据结构进行各种优化(包括重写查询、决定表的读取顺序,以及选择合适的索引。用户可以通过特殊的关键字提示(hint)优化器,影响它的角色过程)、预处理、再由优化器生成对应的执行计划;
  4)MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询;
  5)经结果返回给客户端;
3、MySql如何进行并发控制?读锁(共享锁)、写锁(排它锁);
1)服务器层:不支持行锁,仅支持表锁;
a.mysql服务器层没有实现行级锁,并且完全不了解存储引擎中的锁实现;
b.服务器会为Alter Table之类的语句使用表锁,而忽略存储引擎的锁机制;
另外:
服务器层是不管理事务的,事务是由下层的存储引擎实现的。
mysql 支持的lock tables 和unlock tables 语句是在服务层实现的,但是这和存储引擎无关,并不能代替事务处理。如果应该需要用到事务,还是应该选择事务型存储引擎。
2)存储引擎层:每种MySql存储引擎都可以实现自己的锁策略和锁粒度,同时支持行锁和表锁;
a.表锁:
b.行级锁:可以最大程度上支持并发,但是锁开销也是最大的。
InnoDB和XtraDB 都实现了行级锁,行级锁只在存储引擎层实现,而MySql服务层没有实现,服务器层完全不了解存储引擎中的锁实现。
mysql 的存储引擎并不是简单的实现了行级锁,基于性能的考虑,实现了多版本并发控制(mvcc),这使得在很多情况下避免了加锁操作,因此开销更低。InnoDB 的mvcc 是通过在每行记录后保存两个隐藏的列来实现的。这两个列一个是保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并是不实际的时间,而是系统版本号。每开始一个新事物,系统版本号都会自动增加,事物开始时刻的系统版本号会作为事物的版本号,用来和查询到的每行记录的版本号进行比较。
mvcc 只在 repetable read 和read committed 两个隔离级别下工作,其他两个隔离级别都和mvcc不兼容,因为read uncommitted 总是读取最新的数据行,而不是符合当前事物版本的数据行。而serializable 则会对所有读取到的行都加锁。
4、事务特性:
1)原子性
2)一致性
3)隔离性
4)持久性
mysql提供了两种事务型的存储引擎:innodb、NDB cluster 这也就需要更强的CPU处理能力、更大的内存和更多的磁盘空间。如想进一步了每种特性及并发控制在隔离机制中的使用请移步!
5、mysql的事务隔离级别:
1) READ UNCOMMITTED(读取未提交的数据)
  这是最不安全的一种级别,查询语句在无锁的情况下运行,就读取到别的未提交的数据,造成脏读,如果未提交的那个事务数据全部回滚了,而之前读取了这个事务的数据即是脏数据,这种数据不一致性读造成的危害是可想而知的。
2) READ COMMITTED(读取已提交的数据)
  一个事务只能读取数据库中已经提交过的数据,解决了脏读问题,但不能重复读,即一个事务内的两次查询返回的数据是不一样的。如第一次查询金额是100,第二次去查询可能就是50了,这就是不可重复读取。
3) REPEATABLE READ(可重复读取数据,这也是Mysql默认的隔离级别)
  一个事务内的两次无锁查询返回的数据都是一样的,但别的事务的新增数据也能读取到。比如另一个事务插入了一条数据并提交,这个事务第二次去读取的时候发现多了一条之前查询数据列表里面不存在的数据,这时候就是传说的中幻读了。这个级别避免了不可重复读取,但不能避免幻读的问题。
4) SERIALIZABLE(可串行化读)
  这是效率最低最耗费资源的一个事务级别,和可重复读类似,但在自动提交模式关闭情况下可串行化读会给每个查询加上共享锁和排他锁,意味着所有的读操作之间不阻塞,但读操作会阻塞别的事务的写操作,写操作也阻塞读操作。
   备注:spring的五种事务隔离级别?七种事务传播机制?事务失效原因及解决,请移步!
6、mysql 如何解决死锁问题?
innodb处理死锁的方式是:将持有最少行级排他锁的事务进行回滚。
7、mysql是如何提高事务的执行效率的?
使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把修改行为记录到持久在硬盘上的事务日志中,事务日志持久之后,内存中修改的数据在后台可慢慢的刷回到磁盘。这种方式也称为预写式日志,修改数据需要写两次磁盘。
8、mysql 默认的事务提交方式?
mysql 默认采用自动提交模式,也就是说,如果不是显示的开启一个事务,则每个查询都被当做一个事务执行提交操作。
show variables like 'AUTOCOMMIT';
show AUTOCOMMIT 1;1-启用;0-禁用 自动提交
set session transaction isolation level read committed;
9、站在文件系统的角度谈谈mysql中的表示如何创建的?
在文件系统中,mysql 将每个数据库(schema),保存为数据目录下的一个子目录。创建表时,mysql会在数据库子目录下创建一个和表同名的.frm文件用来保存表的定义,表的定义规则是在mysql服务层统一处理的。
show table status like 't_user';
10、谈谈对innodb存储引擎的认识?
1)Innodb 的数据存储在表空间,表空间由一系列的数据文件组成,innodb可以将表的数据和索引存放在单独的文件中,也可以使用裸机设备作为表空间的存储介质,但是闲杂的文件系统使得裸机设备不再是必要的选择。
2)Innodb采用mvcc支持高并发,并实现了四个标准的隔离级别,其默认级别是repeatable read(可重复读),并通过间隙锁策略防止幻读的出现。间隙锁使得innodb不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。
3)innodb表是基于聚簇索引建立的,聚簇索引对主键查询有很高的性能,不过它的二级索引中必须包含主键列,所以如果主键列很大的话,其他的所有索引都会很大。
4)innodb内部做了很多优化,包括从磁盘读数据时才用的可预测性预读,能够自动在内存中创建hash索引以加速读操作的自适应哈希索引。以及能够加速插入操作的插入缓冲区
5)通过一些工具和机制支持真正的热备份。
11、谈谈myisam存储引擎?
1)mysql 5.1版本之前myisam是默认的存储引擎,其特性是全文索引、压缩、空间函数,但是不支持事务和行级锁,
2)会将表存储在两个文件中:数据文件和索引文件,分别以.myd和.myi为扩展名。
3)支持表锁
4)blob和text字段也可以基于其前500个字符创建索引。也支持全文索引,这是一种基于分词创建的索引,可以支持复杂查询。
5)压缩表支持索引,但是索引是只读的。
12、mysql 为什么创建的表要避免过多的字段?
因为mysql 的存储引擎API工作时,需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列转换成行数据结构的操作代码是非常高的。
13、mysql的表关联有没有数量限制?
有的限制最多不能超过61张表,经验法则如果希望执行的速度快且并发性好,单个查询最好在12个表以内做关联。
14、mysql的基准测试工具及测试指标?
1)工具:sysbench。主要有如下两种测试策略:
a.针对整个系统的整体测试
b.单独测试mysql
2)测试指标:
吞吐量、并发量、响应时间、可扩展性
15、如何加快alter table 操作的速度?
mysql 执行大部分修改表结构的操作方法是用新的表结构创建一个空表,然后从旧表中查出所有数据插入新表,然后删除旧表,这个操作可能需要花费很长时间,如果内存不足而表又很大,而且有很多索引的情况下尤其如此。
mysql 5.1 以及更新版本包含一些类型的“在线”操作支持,这个功能不需要在整个操作过程中锁表。5.5 版本也支持通过排序来建索引,这使得建索引更快,并且有一个紧凑的索引布局。具体可通过如下两种方式提高alter table 的操作速度:
a.先在一台不提供服务的机器上执行alter table 操作,然后和提供服务的主库进行切换。
b.通过影子拷贝:用要求的表结构创建一张和源表无关的新表,然后通过重命名和删除表操作交换两张表。也可以借助一些工具如:facebook 数据库运维团队开发的online schema change工具
b.通过修改.frm文件来修改表结构,不推荐,不受官方支持
16、二叉树、平衡二叉树、B-Tree、B+Tree的含义、数据结构及使用?
  请移步!
细水长流,打磨濡染,渐趋极致,才是一个人最好的状态。
原文地址:https://www.cnblogs.com/jiarui-zjb/p/14347949.html