1. 存储引擎概述

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。

  1. 相当于Linux文件系统,只不过比文件系统强大
  2. 1、文件系统:
  3. 1.1 操作系统组织和存取数据的一种机制。
  4. 1.2 文件系统是一种软件。
  5. 2、文件系统类型:ext2 3 4 xfs 数据
  6. 2.1 不管使用什么文件系统,数据内容不会变化
  7. 2.2 不同的是,存储空间、大小、速度。
  8. 3MySQL引擎:
  9. 3.1 可以理解为,MySQL的“文件系统”,只不过功能更加强大。
  10. 4MySQL引擎功能:
  11. 4.1 除了可以提供基本的存取功能,还有更多功能事务功能、锁定、备份和恢复、优化以及特殊功能

总之,存储引擎的各项特性就是为了保障数据库的安全和性能设计结构。

存储引擎作用:

实现系统以访问和更改数据库中存储的数据。

2. MySQL自带的存储引擎类型

  1. MySQL 提供以下存储引擎:
  2. InnoDB
  3. MyISAM
  4. MEMORY
  5. ARCHIVE
  6. FEDERATED
  7. EXAMPLE
  8. BLACKHOLE
  9. MERGE
  10. NDBCLUSTER
  11. CSV
  12. 还可以使用第三方存储引擎:
  13. MySQL当中插件式的存储引擎类型
  14. MySQL的两个分支
  15. perconaDB
  16. mariaDB
  1. #查看当前MySQL支持的存储引擎类型
  2. mysql> show engines
  3. #查看innodb的表有哪些
  4. mysql> select table_schema,table_name,engine from information_schema.tables where engine='innodb';
  5. #查看myisam的表有哪些
  6. mysql> select table_schema,table_name,engine from information_schema.tables where engine='myisam';

2.1 innodb和myisam区别

InnoDB是一个事务型的存储引擎,有行级锁定和外键约束,适用于以下的场合

  1. 更新多的表,适合处理多重并发的更新请求。
  2. 支持事务。
  3. 可以从灾难中恢复(通过bin-log日志等)。
  4. 外键约束。只有他支持外键。
  5. 支持自动增加列属性auto_increment。

MyIsam 存储引擎独立于操作系统

  1. 不支持事务,但是并不代表着有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。
  2. 不支持外键。
  3. 查询速度很快。如果数据库insert和update的操作比较多的话采用表锁效率低(建议使用innodb)。
  4. 对表进行加锁。

物理上的区别:

  1. InnoDB
  2. #进入word目录
  3. [root@db01 world]# cd /application/mysql/data/world/
  4. #查看所有city的文件
  5. [root@db01 world]# ll city.*
  6. -rw-rw---- 1 mysql mysql 8710 Aug 14 16:23 city.frm
  7. -rw-rw---- 1 mysql mysql 688128 Aug 14 16:23 city.ibd
  8. MyIsam:
  9. #进入mysql目录
  10. [root@db01~l]# cd /application/mysql/data/mysql
  11. #查看所有user的文件
  12. [root@db01 mysql]# ll user.*
  13. -rw-rw---- 1 mysql mysql 10684 Mar 6 2017 user.frm
  14. -rw-rw---- 1 mysql mysql 960 Aug 14 01:15 user.MYD
  15. -rw-rw---- 1 mysql mysql 2048 Aug 14 01:15 user.MYI
  16. frm文件用于存储表的定义
  17. ibd文件用于存储表的数据,索引。
  18. MYD文件用于存储表的数据
  19. MYI文件,存储的是索引

2.2 innodb的核心特性

  1. 1、事务(Transaction
  2. 2MVCCMulti-Version Concurrency Control多版本并发控制)
  3. 3、行级锁(Row-level Lock)
  4. 4Crash Safe Recovery(自动故障恢复)
  5. 5、支持热备份(Hot Backup)

2.3 查看存储引擎

1)使用 SELECT 确认会话存储引擎

  1. #查询默认存储引擎
  2. SELECT @@default_storage_engine;

2)使用 SHOW 确认每个表的存储引擎

  1. #查看表的存储引擎
  2. mysql> show create table qq\G
  3. mysql> show create table like 'CountryLanguage'\G

3)使用 INFORMATION_SCHEMA 确认每个表的存储引擎

  1. #查看表的存储引擎
  2. SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLESWHERE TABLE_NAME = 'City'AND TABLE_SCHEMA = 'world'\G

2.4. 存储引擎的设置

1)在启动配置文件中设置服务器存储引擎

  1. #在配置文件my.ini的[mysqld]标签下添加
  2. [mysqld]
  3. default-storage-engine=InnoDB
  4. 重启服务,数据库默认的引擎修改为InnoDB

2)使用 SET 命令为当前客户机会话设置

  1. #在MySQL命令行中临时设置
  2. SET @@storage_engine=InnoDB

3)在建表的时候指定

  1. #建表的时候指定存储引擎
  2. create table mytbl(
  3. id int primary key,
  4. name varchar(50)
  5. )type=InnoDB;
  1. 建表后更改
    1. alter table table_name type = InnoDB;

    3. 表空间(Tablespace)

  1. 5.5版本以后出现共享表空间概念
  2. 表空间的管理模式的出现是为了数据库的存储更容易扩展
  3. 5.6版本中默认的是独立表空间

3.1 共享表空间

  1. 需要将所有数据存储到同一个表空间中 ,管理比较混乱
  2. 5.5版本出现的管理模式,也是默认的管理模式。
  3. 5.6版本以,共享表空间保留,只用来存储:数据字典信息,undo,临时表。
  4. 5.7 版本,临时表被独立出来了
  5. 8.0版本,undo也被独立出去了

3.1.1 查看共享表空间
  1. #物理查看
  2. [root@db01 ~]# ll /application/mysql/data/
  3. -rw-rw---- 1 mysql mysql 79691776 Aug 14 16:23 ibdata1
  4. #命令行查看
  5. mysql> show variables like '%path%';
  6. innodb_data_file_path =bdata1:12M:autoextend

3.1.2 共享表空间设置
  1. #编辑配置文件
  2. [root@db01 ~]# vim /etc/my.cnf
  3. [mysqld]
  4. innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend

3.2 独立表空间

对于用户自主创建的表,会采用此种模式,每个表由一个独立的表空间进行管理

3.2.1 查看独立表空间
  1. #物理查看
  2. [root@db01 ~]# ll /application/mysql/data/world/
  3. -rw-rw---- 1 mysql mysql 688128 Aug 14 16:23 city.ibd
  4. #命令行查看
  5. mysql> show variables like '%per_table%';
  6. innodb_file_per_table=ON

4. 事务

4.1 什么是事务

  1. 一组数据操作执行步骤,这些步骤被视为一个工作单元:
  2. 1)用于对多个语句进行分组
  3. 2)可以在多个客户机并发访问同一个表中的数据时使用

所有步骤都成功或都失败
1)如果所有步骤正常,则执行
2)如果步骤出现错误或不完整,则取消

4.2 事务的ACID特性

  1. Atomic(原子性)
  2. 所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态。
  3. Consistent(一致性)
  4. 如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。
  5. Isolated(隔离性)
  6. 事务之间不相互影响。
  7. Durable(持久性)
  8. 事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

4.3 事务的生命周期

  1. 开始:
  2. begin
  3. 说明:在5.5 以上的版本,不需要手工begin,只要你执行的是一个DML,会自动在前面加一个begin命令。
  4. 结束:
  5. commit:提交事务
  6. 完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。
  7. rollback :回滚事务
  8. 将内存中,已执行过的操作,回滚回去
  1. 成功事务:
  2. mysql> begin;
  3. mysql> insert into qq values('000','大佬',99,'1',now());
  4. mysql> commit;
  5. 事务回滚:
  6. mysql> begin;
  7. mysql> insert into qq values('999','大哥',100,'1',now());
  8. mysql> rollback;
  1. 一个成功事务的生命周期
  2. begin;
  3. sql1
  4. sql2
  5. sql3
  6. ...
  7. commit;
  8. 一个失败事务的生命周期
  9. begin;
  10. sql1
  11. sql2
  12. sql3
  13. ...
  14. rollback;

4.4 自动提交

  1. #查看自动提交
  2. mysql> show variables like 'autocommit';
  3. #临时关闭
  4. mysql> set autocommit=0;
  5. #永久关闭
  6. mysql> set global autocommit=0;
  7. [root@db01 ~]# vim /etc/my.cnf
  8. [mysqld]
  9. autocommit=0
  10. 注:
  11. 不管自动提交是否打开,一般在有事务需求的MySQL中,将其关闭
  12. 不管有没有事务需求,我们一般也都建议设置为0,可以很大程度上提高数据库性能

4.5 事务的控制语句

START TRANSACTION(或 BEGIN):显式开始一个新事务
SAVEPOINT:分配事务过程中的一个位置,以供将来引用
COMMIT:永久记录当前事务所做的更改
ROLLBACK:取消当前事务所做的更改
ROLLBACK TO SAVEPOINT:取消在 savepoint 之后执行的更改
RELEASE SAVEPOINT:删除 savepoint 标识符
SET AUTOCOMMIT:为当前连接禁用或启用默认 autocommit 模式

4.6 事务隐式提交情况

1.现在版本在开启事务时,不需要手工begin,只要你输入的是DML语句,就会自动开启事务。
2.有些情况下事务会被隐式提交

例如:
在事务运行期间,手工执行begin的时候会自动提交上个事务
在事务运行期间,加入DDL、DCL操作会自动提交上个事务
在事务运行期间,执行锁定语句(lock tables、unlock tables)
load data infile
select for update
在autocommit=1的时候

4.7 事务日志redo和undo

innodb事务日志包括redo log和undo log。

redo log是重做日志,在事务ACID过程中,实现的是“D”持久化的作用。

undo log是回滚操作,在事务ACID过程中,实现的是“A”原子性的作用。当然CI的特性也和undo有关

4.7.1 redo log

redo log包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。

redo工作过程

  1. #执行步骤
  2. update t1 set num=2 where num=1;

1)首先将t1表中num=1的行所在数据页加载到内存中redo log buffer
2)MySQL实例在内存中将num=1的数据页改成num=2
3)num=1变成num=2的变化过程会记录到redo内存区域,也就是redo log file中

  1. #提交事务执行步骤
  2. commit;

1)当敲下commit命令的瞬间,MySQL会将redo log buffer写入磁盘区域redo log file
2)当写入成功之后,commit返回ok

  1. #redo log存储位置
  2. [root@db01 data]# ll /application/mysql/data/
  3. -rw-rw---- 1 mysql mysql 50331648 Aug 15 06:34 ib_logfile0
  4. -rw-rw---- 1 mysql mysql 50331648 Mar 6 2017 ib_logfile1

4.7.2 undo log

undo log有两个作用:提供回滚和多个行版本控制(MVCC)。

在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。

当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

  1. 在事务ACID过程中,实现的是“A 原子性的作用
  2. 另外CI也依赖于Undo
  3. rolback时,将数据恢复到修改之前的状态
  4. CSR实现的是,将redo当中记录的未提交的时候进行回滚.
  5. undo提供快照技术,保存事务修改之前的数据状态.保证了MVCC,隔离性,mysqldump的热备
  1. #undo log存储位置
  2. [root@db01 data]# ll /application/mysql/data/
  3. -rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata1
  4. -rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata2

4.8 事务中的锁

“锁”的作用是什么?

在事务ACID过程中,“锁”和“隔离级别”一起来实现“I”隔离性和”C” 一致性 (redo也有参与).

共享锁:共享锁也称为读锁,读锁允许多个连接可以同一时刻并发的读取同一资源,互不干扰

排他锁:排他锁也称为写锁,一个写锁会阻塞其他的写锁或读锁,保证同一时刻只有一个连接可以写入数据,同时防止其他用户对这个数据的读写

悲观锁:行级锁定(行锁):多事务操作时,数据只有一个人可以修改.

乐观锁: 多事务操作时,数据可以同时被修改,谁先提交,谁就修改成功.谁先提交谁为准)

锁的粒度
MyIsam:低并发锁(表级锁)
Innodb:高并发锁(行级锁)

4.9 多版本并发控制(MVCC):

1)只阻塞修改类操作(排他锁),不阻塞查询类操作(共享锁)
2)乐观锁的机制(谁先提交谁为准)

4.10 事务的隔离级别

四种隔离级别:

READ UNCOMMITTED(独立提交)未提交读:
一个事务可以读到另外一个事务未提交的数据。

READ COMMITTED 提交读:

在一个事务修改数据过程中,如果事务还没提交,其他事务不能读该数据。

REPEATABLE READ 可重复读:
在同一个事务内的查询都是事务开始时刻一致的
InnoDB 的默认级别

SERIALIZABLE 串行化:
将一个事务的结果与其他事务完全隔离

脏读、不可重复读、幻读

1.脏读:
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

2.不可重复读:
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)

例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

3.幻读:
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

  1. √: 可能出现 ×: 不会出现
事务隔离级别 脏读 不可重复读 幻读
未提交读:READ UNCOMMITTED
提交读:READ COMMITTED ×
重复读:REPEATABLE READ × ×
串行化:SERIALIZABLE × × ×
  1. #查看隔离级别
  2. mysql> show variables like '%iso%';
  3. #修改隔离级别为RU
  4. [mysqld]
  5. transaction_isolation=read-uncommit
  6. mysql> use oldboy
  7. mysql> select * from stu;
  8. mysql> insert into stu(id,name,sex,money) values(2,'li4','f',123);
  9. #修改隔离级别为RC
  10. vim /etc/my.cnf
  11. [mysqld]
  12. transaction_isolation=read-commit