mysql笔记(一)

mysql逻辑架构

每个虚线框为一层,总共三层。

第一层,服务层(为客户端服务):为请求做连接处理,授权认证,安全等。

第二层,核心层:大多数mysql的核心服务功能都在这一层,包括查询解析,分析,优化,缓存,提供内建函数;存储过程,触发器,视图。

第三层,存储引擎层,不光做存储和提取数据,而且针对特殊数据引擎还要做事务处理。

mysql笔记(一)

锁力度


表锁:

      表锁是mysql中最基本的锁策略,并且是开销最小的策略。表锁会锁住整张表。一个用户对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有当没有写锁时,其他读取的用户才能获得读锁,读锁是不相互阻塞的。另外,写锁比读锁有更高的优先级,一个写锁可能会被插入到读锁队列的前面。

尽管存储引擎可以管理自己的锁,mysql本身还是会使用各种有效的表锁来实现不同的目的。


行锁:

      行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,mysql服务器层没有实现行级锁。mysql服务层完全不了解存储引擎中锁的实现。

mysql多版本并发控制:

mysql的大多数事务性存储引擎实现的都不是简单的行级锁。他们一般都同时实现了多版本并发控制(MVCC).

可以认为mvcc是行级锁的一个变种,但是它在很多情况下避免了加锁操作。使大多数的读操作可以不用加锁,写操作也只锁定必要的行。不同的存储引擎的MVCC实现是不同的。典型的有乐观并发控制和悲观并发控制。

MVCC全称Mutli Version Concurreny Control,并不是MySql独有的,Oracle,PostgreSQL等都在使用。

MVCC并没有简单地使用行锁,而是使用“行级别锁”(row-levellocking)。


下面通过innodb的简化版本来说明MVCC是如何工作的。

在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空)。这里的版本号并不是实际的时间值,而是系统版本号。每开始 个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。


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

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


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

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

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

UPDATE:InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当系统的版本号为原来的行作为删除标识。

保存这两个额外系统版本号,使大多数操作都可以不用加锁。这样设计使得计数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。


参考:https://www.cnblogs.com/baochuan/archive/2012/03/15/2397536.html

参考文献:《高性能的mysql》