第一章 MySQL架构与历史

高性能MySQL(第3版) 学习笔记

1.1 MySQL逻辑架构

image

MySQL的逻辑架构图共分为三层:

  • 第一层:服务层为客户端提供连接、授权认证、安全等
  • 第二层:核心服务层,包括查询解析、分析、优化、缓存以及所有的内置函数,所有跨存储引擎的功能都在这层实现:存储过程、触发器、视图等。
  • 第三层:存储引擎负责数据的存储和提取,通过api和核心服务层通信(第二层),各存储引擎之间不会相互通信,而是简单的响应上层服务的请求。

1.1.1 连接管理与安全

image
  1. 每个连接操作都在服务器进程中的某一个线程中完成
  2. 服务器会缓存线程,不需要为每一个新建连接创建或销毁线程

服务器进程中有类似线程池的概念,以提高处理的性能

image
  1. 客户端连接服务器时,对身份进行认证确认身份,包括用户名、密码、主机地址等。还可以使用SSL的证书认证
  2. 身份认证通过连接成功后,还会验证是否㕛执行某个特定查询的权限

1.1.2 优化与执行

image

SQL语句解析详解

1.2 并发控制

无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制问题。此次只讨论MySQL在两个层面的并发控制:服务器层 存储引擎层

1.2.1 读写锁

处理并发控制,有两种类型的锁通来解决问题。

  • 共享锁(shared lock) 也叫 读锁(read lock)
  • 排他锁(exclusive lock) 也叫 写锁(write lock)
  • 读锁:是共享的,或者说是相互不阻塞的。多个客户端在同一时刻可以同时读取同一个资源,而互不干扰。
  • 写锁:是排他的,一个写锁会阻塞其他的写锁和读锁

1.2.2 锁粒度

提高资源并发性的一种方式就是减少锁定资源的范围,缩小锁的粒度,只对修改的数据进行锁定。锁的粒度越小,并发性能越高,同时服务器越消耗资源。

锁策略:就是在锁的开销和数据安全性之间寻求平衡,这种平衡也会影响到性能。

MySQL提供了多种锁选择。每种存储引擎都可以实现自己的锁策略和锁粒度。其中最重要的两种锁策略:

  • 表锁(table lock):是MySQL中最重要的锁策略,并且开销最小。它会锁定整张表,一个用户在对表进行写操作,需要先获得锁,会阻塞其他用户的读/写操作。只有没有写锁时,其他读取的用户才能获取读锁,读锁之间互不阻塞。
  • 行级锁(row lock):行级锁可以最大程度支持并发处理,同时也带来了最大的锁开销。行级锁只在存储引擎层(InnoDB/XtraDB)实现,而服务层没有实现。服务器层完全不了解存储引擎中的锁实现。

1.3 事务

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

1.3.1 事务的四个基本要素:ACID

  • 原子性 (atomicity):一个事务必须是一个不可分割的最小工作单元,整个事务的所有操作要么全部成功,要么全部失败回滚
  • 一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性状态
  • 隔离性(isolation):一个事务所做的修改在最终提交前,对其他事务是不可见的。
  • 持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库

1.3.2 隔离级别

SQL标准中定义了四种隔离级别。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

  • READ UNCOMMITTED(未提交读):事务中的修改,即使没有提交,对其他事务也都是可见的。
  • READ COMMITTED(提交读):大多数数据库的默认隔离级别(MySQL除外)。一个事务开始时,只能看见已经提交的事务所做的修改。也就是说,一个事务从开始到提交前,所做的任何修改对其他事务不可见。也叫作不可重复读。
  • REPEATABLE READ(可重复读):是MySQL的默认事务隔离级别。解决了脏读问题。保证在同一事务中多次读取同样的记录结果是一致。但无法解决幻读的问题。
  • SERIALIZABLE(可串行化):是最高的隔离级别。通过强制事务串行执行,避免了幻读的问题。它会在读取的每一行数据上都加锁,会导致大量的锁竞争和超时。实际中使用很少,除非特殊情况必须采用除外。

幻读:指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。

脏读:事务可以读取未提交的数据

InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。

1.3.3 死锁

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

  • 多个事务试图以不同顺序锁定资源时,就会产生死锁。
  • 多个事务同时锁定同一资源时,也会产生死锁。

死锁处理机制:

  • 死锁检测机制
  • 死锁超时机制

1.3.4 事务日志

事务日志可以提高事务的效率。存储引擎在修改表的数据时只需要修改其内存拷贝,再把修改行为记录到持久的硬盘的事务日志中,而不用每次都将数据本身持久到磁盘。
事务日志持久后,内存中被修改的数据在后台慢慢刷回到磁盘。通常称之为 预写式日志(Write-Ahead Logging)

1.3.5 MySQL中的事务

MySQL提供了两种事务型存储引擎:InnoDB和NDB Cluster。

自动提交(AUTOCOMMIT)

默认采用自动提交(AUTOCOMMIT)模式。

查看当前的自动提交设置:

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set

1或者ON表示启用,0或者OFF表示禁用。当AUTOCOMMIT=0时;所有的查询都在一个事务中,可以显示的执行COMMIT提交或者ROLLBACK回滚。

设置当前会话的事务为手动提交:

mysql> set autocommit =0; //设置autocommit =0;关闭自动提交事务
Query OK, 0 rows affected

mysql> show variables like 'autocommit';//再次查看,发现已经变化
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set

设置MySQL全局级别的AUTOCOMMIT:

mysql> select @@global.autocommit;//查看全局的设置,发现是自动提交
+---------------------+
| @@global.autocommit |
+---------------------+
|                   1 |
+---------------------+

最有效且省事的方法:
在MySQL的配置文件中设置,然后重启mysql服务

[mysqld]
init_connect='SET autocommit=0'

==在事务中混合使用存储引擎==

==MySQL服务器层不管理事务,事务是有下层的存储引擎实现的。所以在同一个事务中,使用多种存储引擎是不可靠的。==

1.4 多版本并发控制(MVCC)

http://www.cnblogs.com/chenpingzhao/p/5065316.html

1.5 MySQL的存储引擎

MySQL将每个数据库(也成为schema)保存为数据目录下的一个子目录。数据库中的每个表至少对应数据库目录中的一个文件(也可能是多个,取决于存储引擎)。
因此,所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。在大多数Unix中数据库名和表名对大小写敏感,而在Windows中对大小写不敏感。一个显著的例外情况是Mac OS X,它基于Unix但使用默认文件系统类型(HFS+),对大小写不敏感。然而,Mac OS X也支持UFS卷,该卷对大小写敏感,就像Unix一样

变量lower_case_file_system说明是否数据目录所在的文件系统对文件名的大小写敏感。ON说明对文件名的大小写不敏感,OFF表示敏感。

在Linux中查看:

mysql> show variables like 'lower%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| lower_case_file_system | OFF   |
| lower_case_table_names | 0     |
+------------------------+-------+
2 rows in set

在windows中查看:

mysql> show variables like 'lower%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| lower_case_file_system | ON    |
| lower_case_table_names | 1     |
+------------------------+-------+
2 rows in set

你可能感兴趣的:(第一章 MySQL架构与历史)