MySQL简介

2020-06-26  本文已影响0人  天空_2ca8

一 简介

    mysql是一个开源的数据库系统软件。

二 MySQL的逻辑架构

    MySQL的逻辑架构图如下:

  MySQL逻辑架构可以分为三层:

  第一层:连接/线程处理,负责连接处理、授权认证、安全等(不是MySQL所独有的)

  第二层:服务器核心功能层。负责查询、解析、优化、缓存以及所有内置函数(例如,日期、时间、数学和加密函数),所以跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。

  第三层:存储引擎层。存储引擎负责MySQL中数据的存储和提取。

三 锁

    为了解决MySQL并发操作中出现的竞争条件,MySQL引入了锁的机制。

    1.读锁

    读锁是共享的,或者说是相互不阻塞的。多个客户端在同一时刻可以同时读取一个资源,而互不干扰。

    2.写锁

    写锁是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,这是出于安全策略的考虑,只有这样,才能确保在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。

    3.使用锁的策略

    所谓的锁策略,就是在锁的开销和数据的安全性之间寻求平衡,这种平衡也会关乎到性能。MySQL主要实现了两种锁机制,一种在MySQL服务器层实现,另一种在存储引擎实现。

    (1)表锁

    表锁是MySQL中最基本的锁策略,并且是开销最小的策略。表锁会锁定整张表。一个用户在对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。表锁是在MySQL服务器层实现的

    (2)行级锁

      行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,比如InnoDB就实现了行级锁。

    4.死锁

    死锁指的是两个或多个事务在同一资源上相互占用,并请求锁定对方所占用的资源,从而导致恶性循环的现象。

    解决办法:InnoDB处理死锁的方法是,将持有最少行级排他锁的事务进行回滚。

    5.使用锁的建议

    除了禁用AUTOCOMMIT变量外,不要使用LOCK TABLES,而是依靠InnoDB隐式的行级锁。锁只有在事务执行COMMIT或者ROLLBACK的时候才会释放,并且所有锁是在同一时刻释放。

四 事务

    1.事务的定义

    事务就是一组原子性的SQL操作,或者说一个独立的工作单元。事务内的语句,要么全部执行成功,要么全部执行失败。

    2.事务的四大特征(ACID)

    (1)原子性

    一个事务必须被视为一个不可分割的最小工作单元,整个事务中所有操作要么全部提交成功,要么全部失败回滚,不可能着只执行其中的一部分

    (2)一致性

    在事务开始之前,结束之后,数据都必须保持一致状态,必须保证数据库的完整性

    (3)隔离性

    数据库允许多个并发事务同时对数据操作,隔离性保证各个事务相互独立,一个事务所做的修改在最终提交之前,对其他事务是不可见的。

    (4)持久性

    一旦事务提交,则其所做的修改就会永久保存到数据库中。此时,即使系统崩溃,修改的数据也不会丢失。

五 隔离级别

    在SQL标准中定义了四种隔离级别,每一级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的,较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

    注意:隔离级别是由存储引擎实现的。

    1.不同隔离级别中可能会出现的问题

    (1)脏读:一个事务读取到另一个事务未提交的数据

    (2)不可重复读:一个事务执行两次同样的查询,可能会得到不一样的结果(内容可能改变了)

    (3)幻读:一个事务执行两次同样的查询,得到不同的记录数(一般是多了几行)

    2.隔离级别

    (1)READ UNCOMMITTED(未提交读)

    在READ UNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。

    (2)READ COMMITTED(提交读)

    一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读,因为执行两次同样的查询,可能会得到不一样的结果。大多数数据库系统的默认隔离级别都是提交读(但MySQL不是)。

    (3)REPEATABLE READ(可重复读)

    REPEATABLE READ解决了脏读的问题,该级别保证在同一个事务中多次读取同样的记录的结果是一样的。可重复读是MySQL的默认事务隔离级别。

    (4)SERIALIZABLE(可串行化)

    SERIALIZEZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题。可串行化会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。

    3.使用SQL开始一个事务

    START TRANSACTION;// 开始事务

    SELECT。。。;

    UPDATE。。。;

    COMMIT;//事务执行成功提交

    4.事务日志

  (1) 事务日志的定义

  事务日志是一个与数据库文件分开的文件,它存储对数据库进行的所有修改,并全部记录插入、更新、提交、删除、回退和数据库模式变化。

  (2) 事务日志工作原理

  存储引擎修改表时只修改其内存的拷贝,再把该修改行为记录到事务日志中,最后再慢慢刷回磁盘,所以称之为预写式日志,修改数据需要写两次磁盘。

  注意:事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式比起直接写磁盘要快的多。

  5.自动提交

  (1)自动提交的定义

  MySQL默认采用自动提交(AUTOCOMMIT)模式,也就是说,如果不是显示地开始一个事务,则每个查询都被当做一个事务执行提交操作。

  (2)AUTOCOMMIT变量

  值为1或ON表示启用自动提交,0或OFF表示禁用。

  (3)AUTOCOMMIT被禁用时事务的执行方式

  在这种情况下,所有的查询都是在一个事务,直到显示地执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时又开始了另一个新事务。

  6.设置隔离级别

  SET TRANSACTION ISOLACTION LEVEL

六 多版本并发控制(MVCC)

    1.MVCC的定义

    可以将MVCC看作是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。

    2.MVCC的实现

    (1)原理

    MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

    (2)实现方式

    InnoDB的MVCC,是通过在每行记录后面保持着两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。这两个时间本质上是系统版本号,每开始一个新的事务,系统版本号都会递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。具体操作如下:

    SELECT

    InnoDB会根据以下两个条件检查每行记录:

    a.InnoDB只查找版本号小于当前事务版本的数据行(行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。

    b.行的删除版本要么是未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

    只有同时符合上述两个条件的记录,才能返回作为查询的结果。

    INSERT

    InnoDB为新插入的每一行保存当前系统版本号作为行版本号。

    DELETE

    InnoDB为删除的每一行保存当前系统版本号作为删除标识。

    UPDATE

    InnoDB更新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

    3.MVCC的优点和缺点

    优点:使大多数读操作都不用加锁,使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。

    缺点:每行记录都需要额外的空间,需要做更多的行检查工作,以及一些额外的维护工作

  注意:MVCC只能用于提交读和可重复读这两个隔离级别。

七 InnoDB

    InnoDB是MySQL的默认事务型引擎,也是最重要,使用最广泛的引擎。它用来处理大量的短期事务,短期事务大部分情况是正常提交的,很少被回滚。如果使用InnoDB,MySQL的所有操作(INSERT,DELETE,UPDATE,SELECT等)都是事务。

上一篇下一篇

猜你喜欢

热点阅读