MySQL逻辑架构整体分为三层,最上层为客户端,并非MySQL独有,诸如:连接处理,授权认证,安全等功能均在这一层处理
MySQL大多数核心服务均在中间这一层,包括查询解析,分析优化,缓存,内置函数,所有的跨存储引擎功能也在这一层实现:存储过程,触发器,视图等。
最下层为存储引擎,负责MySQL中的数据存储和提取
连接层(客户端/服务端通信协议)
SQL层
存储引擎层(类似于linux中的文件)
负责根据SQL层的执行结果,从磁盘上拿数据,返回给客户端
MyISAM引擎特点:
使用场景:
只读(或者写较少时),表较小
InnoDB引擎特点
备份:备份的时候备份业务数据库和mysql数据库(因为mysql数据库中有用户及权限设置)
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 500 |
+-----------------+-------+
1 row in set (0.00 sec)
mysql> set global max_connections =2000;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 2000 |
+-----------------+-------+
1 row in set (0.00 sec)
# 也可在配置文件中修改
[root@server ~]# vim /etc/my.cnf
服务器状态变量:分全局和会话两种
状态变量(只读):用于保存mysqld运行中的统计数据变量,不可更改
show global status;
show [session] status;
SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置
常见MODE:
索引:索引是排序的快速查找的特殊数据结构,定义作为查找条件的字段,又称为key,索引通过存储引擎实现,加快查询速度
索引的优点是可以提高检索数据的速度,这是创建索引的最主要的原因;对于有依赖关系的子表和父表之间的;联合查询时,可以提高查询速度;使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。
索引的缺点是创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;索引需要占用物理空间,每一个索引要占一定的物理空间;增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了
优点
缺点:
索引类型:
B+tree索引:按顺序储存,每一个叶子节点到根节点的举例是相同的;左前缀索引,适合查询范围类的索引;
B-TREE
B+TREE
页面搜索严禁做模糊或者全模糊,如果需要择走搜索引擎来解决
说明:索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引
可以使用B+TREE索引的查询类型
B+TREE索引的限制
类型:
- 读锁:共享锁,也成为S锁,只读不可写(包括当前事务),多个读互不阻塞
- 写锁:独占锁,排它锁,也成为X锁,写锁会阻塞其他事务(不包括当前事务)的的读和写
- S锁和S锁是兼容的,X锁和其他锁都不兼容
- 例:事务 T1 获取了一个行 r1 的 S 锁,另外事务 T2 可以立即获得行 r1 的 S 锁,此时 T1 和 T2 共同获得行 r1 的 S 锁,此种情况称为锁兼容,但是另外一个事务 T2 此时如果想获得行 r1 的 X 锁,则必须等待 T1 对行 r1 锁的释放,此种情况也称为锁冲突
锁粒度:
- 表级锁:MyISAM
- 行级锁:InnoDB
实现
- 存储引擎:自行实现其锁策略和锁粒度
- 服务器级:实现了锁、表级锁、用户可显示请求
分类:
- 隐式锁:由于存储引擎自动施加锁
- 显式锁:用户手动请求
锁策略:在锁粒度以及数据安全性寻求的平衡机制
简介:事务Transactios:一组原子性的sql语句,或一个独立工作单元
事务日志:记录事务信息,实现undo,redo故障恢复功能
begin
说明:在5.5 以上的版本,不需要手工begin,只要你执行的是一个DML,会自动在前面加一个begin命令。
commit:提交事务
完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。
rollback :回滚事务
将内存中,已执行过的操作,回滚回去
注意:只有事务型存储引擎中的DML语句方能支持此类操作
自动提交:
set autocommit={1|0} 默认未1,未0时设为非自动提交,为0可以提高数据库性能
死锁:
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态
开始事务流程:
1、检查autocommit是否为关闭状态
select @@autocommit;
或者:
show variables like 'autocommit';
2、开启事务,并结束事务
begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
rollback;
begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
commit;
对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含 3 个隐藏列
多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。
如果不考虑隔离性,可能会引发如下问题:
# 这是非常危险的,假设A向B转帐100元,对应sql语句如下所示
1. update account set money=money+100 where name=‘b’;
2. update account set money=money-100 where name=‘a’;
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加读锁 |
---|---|---|---|---|
读未提交 | 可以出现 | 可以出现 | 可以出现 | 否 |
读提交 | 不允许出现 | 可以出现 | 可以出现 | 否 |
可重复读 | 不允许出现 | 不允许出现 | 可以出现 | 否 |
序列化 | 不允许出现 | 不允许出现 | 不允许出现 | 是 |
数据库共定义了四种隔离级别:
MVCC和事务的隔离级别:
MVCC(多版本并发控制机制)只在READ COMMITTED和REPEATABLE READ两个隔离级别下工作。其
他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前
事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁