目录
一、MySQL 事物
1、事务的概念
2、 事务的ACID特点
(1)原子性
(2)一致性
(3) 隔离性
(4)事务之间的相互影响
(5) Mysql及事物隔离级别
(6)持久性
二:事务命令
1、 查询全局事务隔离级别
2、 查询会话事务隔离级别(只对当前连接有效)
3、 设置全局事务隔离级别
4、 设置会话事务隔离级别
5、 事务控制语句
6、案例
(1)创建表
(2)测试提交事务
(3) 测试回滚事务
(4) 测试多点回滚
7、 使用set设置控制事务
三:存储引擎
1、概念介绍
2、MySQL常用的存储引擎
四:MyISAM
1、MyISAM的特点介绍
2、 MyISAM表支持3种不同的存储格式
(1)静态(固定长度)表
(2)动态表
(3)压缩表
3、MyISAM适用的生产场景举例
五:InnoDB
1、InnoDB特点介绍
2、InnoDB适用生产场景分析
3、企业选择存储引擎依据
4、索引的支持
5、事务处理的支持
六: 存储引擎命令
1、查看系统支持的存储引擎
2、 查看表使用的存储引擎
方法一:
方法二:
3、 修改存储引擎
(1)方法一:通过alter table修改
(2) 方法二:通过修改/etc/my.cnf 配置文件,指定默认存储引擎并重启服务
(3) 方法三:通过create table 创建表时指定存储引擎
4、死锁演示
避免死锁的解决方案 :
总结
说白了,所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
ACID,是指在可靠数据库管理系统(DBMS) 中,事务(transaction)应该具有的四个特性:原子性(Atomicity) 、一致性 (Consistency)、隔离性(Isolation) 、持久性(Durability) 。这是可靠数据库所应具备的几个特性。
原子性:指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
事务是一个完整的操作,事务的各元素是不可分的。
事务中的所有元素必须作为一个整体提交或回滚。
如果事务中的任何元素失败,则整个事务将失败。
案例:
A给B转帐100元钱的时候只执行了扣款语句,就提交了,此时如果突然断电,A账号已经发生了扣款,B账号却没收到加款,在生活中就会引起纠纷。这种情况就需要事务的原子性来保证事务要么都执行,要么就都不执行。
一致性:指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。.
当事务完成时,数据必须处于一致状态。
在事务开始前,数据库中存储的数据处于一致状态。
在正在进行的事务中,数据可能处于不一致的状态。
当事务成功完成时,数据必须再次回到已知的一致状态。
案例:
对银行转帐事务,不管事务成功还是失败,应该保证事务结束后表中A和B的存款总额跟事务执行前一致。
隔离性:指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。
修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据
(1)脏读:一个事务读取了另一个事务未提交的数据,而这个数据是有可能回滚的。
(2)不可重复读:一个事务内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。
(3)幻读:一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,操作前一个事务的用户会发现表中还有没有修改的数据行,就好象发生了幻觉一样。
(4)丢失更新:两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。
MySQL事务支持如下四种隔离,用以控制事务所做的修改,并将修改通告至其它并发的事务:
(1)未提交读(Read Uncommitted):
允许脏读,即允许一个事务可以看到其他事务未提交的修改。
(2)提交读(Read Committed):
允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。
(3)可重复读(Repeated Read): ---mysql默认的隔离级别
确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果,不管其他事务是否提交这些修改。
(4)串行读(Serializable): ---相当于锁表
完全串行化的读,将一个事务与其他事务完全地隔离。每次读都需要获得表级共享锁,读写相互都会阻塞。
mysql默认的事务处理级别是 repeatable read,而Oracle和SQL Server是read committed
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
指不管系统是否发生故障,事务处理的结果都是永久的。
一旦事务被提交,事务的效果会被永久地保留在数据库中。
总结:在事务管理中,原子性是基础,隔离性是手段,一致性是目的,持久性是结果。
show global variables like '%isolation%';
SELECT @@global.tx_isolation;
show session variables like '%isolation%';
SELECT @@session.tx_isolation;
SELECT @@tx_isolation;
set global transaction isolation level read committed;
set session transaction isolation level read committed;
BEGIN或START TRANSACTION:显式地开启一个事务。
COMMIT或COMMITWORK:提交事务,并使已对数据库进行的所有修改变为永久性的。
ROLLBACK或ROLLBACK WORK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
SAVEPOINT S1:使用 SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多SAVEPOINT;“S1”代表回滚点名称。
ROLLBACK TO [SAVEPOINT] S1:把事务回滚到标记点。
#创建表
use xyw;
create table account (
id int(10) primary key not null,
name varchar(40),
money double
);
insert into account values(1,'A',1000);
insert into account values(2,'B',1000);
begin;
update account set money= money - 100 where name='A';
commit;
quit
mysql -u root -p
use xyw;
select * from account;
begin;
update account set money= money + 100 where name='A';
rollback;
quit
mysql -u root -p
use xyw;
select * from account;
begin; .
update account set money= money + 100 where name='A';
SAVEPOINT S1;
update account set money= money + 100 where name='B';
SAVEPOINT S2;
insert into account values(3,'C',1200);
select * from account;
ROLLBACK TO S1;
select * from account;
SET AUTOCOMMIT=0; #禁止自动提交
SET AUTOCOMMIT=1; #开启自动提交,Mysq1默认为1
SHOW VARIABLES LIKE 'AUTOCOMMIT'; #查看Mysql中的AUTOCOMMIT值
如果没有开启自动提交,当前会话连接的mysql的所有操作都会当成一个事务直到你输入rollback或commit;当前事务才算结束。当前事务结束前新的mysql连接时无法读取到任何当前会话的操作结果。
如果开起了自动提交,mysql 会把每个sql语句当成一个事务,然后自动的commit。
当然无论开启与否,begin; commit|rollback; 都是独立的事务。
定义:MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在MySQL中称为存储引擎
■存储引擎是MySQL将数据存储在文件系统中的存储方式或者存储格式
●MyISAM
●InnoDB
MySQL数据库中的组件,负责执行实际的数据I/O操作
MySQL系统中,存储引擎处于文件系统之上,在数据保存到数据文件之前会传输到存储引擎,之后按照各个存储引擎的存储格式进行存储
1、MyISAM不支持事务,也不支持外键约束,只支持全文索引,数据文件和索引文件是分开保存的访问速度快,对事务完整性没有要求
2、MyISAM适合查询、插入为主的应用MyISAM在磁盘上存储成三个文件,文件名和表名都相同,但是扩展名分别为
.frm文件存储表结构的定义
数据文件的扩展名为.MYD (MYData)
索引文件的扩展名是.MYI (MYIndex)
3、表级锁定形式,数据在更新时锁定整个表
4、数据库在读写过程中相互阻塞
会在数据写入的过程阻塞用户数据的读取
也会在数据读取的过程中阻塞用户的数据写入
5、数据单独写入或读取,速度过程较快且占用资源相对少
6、MyIAM支持的存储格式
静态表
动态表
压缩表
静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固定长度的。
这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;
缺点是占用的空间通常比动态表多。
动态表包含可变字段,记录不是固定长度的。
这样存储的优点是占用空间较少,但是频繁的更新、删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk -r命令来改善性能,并且出现故障的时候恢复相对比较困难。
压缩表由myisamchk工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支。
1、公司业务不需要事务的支持
2、单方面读取或写入数据比较多的业务
3、MyISAM存储引擎数据读写都比较频繁场景不适合
4、使用读写并发访问相对较低的业务
5、数据修改相对较少的业务
6、对数据业务一致性要求不是非常高的业务
7、服务器硬件资源相对比较差
1、支持事务, 支持4个事务隔离级别
MySQL从5.5.5版本开始,默认的存储引擎为InnoDB
2、读写阻塞与事务隔离级别相关
3、能非常高效的缓存索引和数据
4、表与主键以簇的方式存储
5、支持分区、表空间,类似oracle数据库
6、支持外键约束,5.5前不支持全文索引,5.5后支持全文索引
7、对硬件资源要求还是比较高的场合
8、行级锁定,但是全表扫描仍然会是表级锁定,如
update table set a=1 where user like "%zhang%";
9、InnoDB中不保存表的行数,如'select count(*) from table;'时InnoDB需要扫描一遍整个表来计算有多少行,
但是MyISAM只要简单的读出保存好的行数即可。需要注意的是当count(*)语句包含where条件时MyISAM也需要扫描整个表
10、对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立组合索引
11、清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM则会重建表
1、业务需要事务的支持
2、行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成
3、业务数据更新较为频繁的场景,如:论坛,微博等
4、业务数据一致性要求较高,如:银行业务
5、硬件设备内存较大,利用InnoDB较好的缓存能力来提高内存利用率,减少磁盘IO的压力
1、需要考虑每个存储引擎提供了哪些不同的核心功能及应用场景
2、支持的字段和数据类型
(1)所有引|擎都支持通用的数据类型
(2)但不是所有的引擎都支持其它的字段类型,如二进制对象
3、锁定类型:不同的存储引擎支持不同级别的锁定
表锁定: MyISAM支持
行锁定: InnoDB支持
建立索引在搜索和恢复数据库中的数据时能显著提高性能
不同的存储引擎提供不同的制作索引的技术
有些存储引擎根本不支持索引
提高在向表中更新和插入信息期间的可靠性
可根据企业业务是否要支持事务选择存储引擎
show engines;
show table status from 库名 where name='表名'\G
use 库名;
show create table 表名;
use 库名;
alter table 表名 engine=MyISAM;
vim /etc/my.cnf
[mysqld]
default-storage-engine=INNODB
systemctl restart mysql.service
注意:此方法只对修改了配置文件并重启mysql服务后新创建的表有效,已经存在的表不会有变更。
use 库名;
create table 表名 (字段1 数据类型,...) engine=MyISAM;
行锁如果使用不当会导致死锁(死锁一般是事务相互等待对方释放资源,最后形成环路造成的)
务A | 事务B |
---|---|
begin; | begin; |
delete from student where id=2;#事务结束前,id=2的行会被锁定 | |
select * from t1 where id=1 for update; #加排他锁,模拟并发情况,锁定id=1的行 | |
elete from t1 where id=1; #死锁产生 | |
update t1 set name='abc' where id=2; #死锁产生。因为会话1中id=5的行还在删除过程中,该行已被锁定 | |
rollback; #回滚,结束事务。id=5的行被解锁 | |
update t1 set name='abc' where id=2; #成功更新数据 |
1.使用更合理的业务逻辑,以固定的顺序访问表和行。
2、大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
3、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
4、降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。
5、为表添加合理的索引。如果不使用索引将会为表的每一行记录添加上锁,死锁的概率大大增加。
事务
事务是一种机制。就是一组操作序列(包含1个或者多个操作命令),事务会把所有操作命令看作一个整体向系统提交或撤销操作,所有操作命令要么都执行,要么都不执行事务的ACID特性:
原子性:事务管理的基础。把事务中的所有操作看作是一个不可分割的工作单元,要么都执行,要么都不执行
一致性:事务管理的目的。保证事务开始前和事务结束后数据的完整和一致
隔离性:事务管理的手段。使多个事务并发操作同一个表数据时,每个事务都有各自的独立数据空间,可通过隔离级别解决不同的一致性问题
持久性:事务管理的结果。当事务被提交以后,事务中的操作命令修改的结果会被持久保存,且不会被回滚在多个事务并发操作同一个表数据时,不同的隔离级别可能会出现的一致性问题:
脏读 一个事务可以看到另一个事务没有提交的修改数据
不可重复读 在一个事务里的两次查询会看到数据不一致的情况,这种情况可能因为两次查询过程中间有其它事务修改了数据并已提交
幻读 在一个事务里的两次查询会看到数据不一致的情况(可能是发现之前没有的数据),这种情况可能因为两次查询过程中间有其它事务插入了新的数据并已提交
丢失更新 一个事务修改数据并提交可能会覆盖另一个事务修改和提交的数据隔离级别:
未提交读 Read Uncommitted RU 允许 脏读 不可重复读 幻读
提交读 Read Committed RC 不允许 脏读 允许 不可重复读 幻读
可重复读 Repeatable Read RR 不允许 脏读 不可重复读 有条件的允许(Innodb不允许) 幻读
串行读 Serializable 都不允许 (相当于表级锁定,会影响数据库读写效率和性能)查看隔离级别
show global variables like '%isolation%';
show session variables like '%isolation%';设置隔离级别
set global transaction isolation level read committed;
set session transaction isolation level read committed;事务管理操作
begin;
.... insert into update XX set delete from
savepoint XX;
rollback to XX;
commit; rollback;自动事务提交
set autocommit=0|1;
show variables like 'autocommit';
存储引擎
存储引擎 是MySQL数据库中的组件,负责执行实际的数据I/O操作,工作在文件系统之上,数据库的数据会先传输到存储引擎,会按照存储引擎的格式保存到文件系统中常用的存储引擎: MyISAM InnoDB
MyISAM:不支持事务、外键约束,只支持表级锁定,适合单独的查询或插入操作,读写并发能力较弱,支持全文索引,资源占用较小,数据文件(.MYD)和索引文件(.MYI)是分开存储的。
推荐使用场景:适用于不需要事务处理,单独的查询或者插入数据的业务场景
InnoDB:支持事务、外键约束,支持行级锁定(在全表扫描时仍然会表级锁定),读写并发能力较好,支持全文索引(5.5版本以后的),缓存能力较好可以减少磁盘IO的压力,数据文件也是索引文件。
推荐使用场景:适用于需要事务的支持,一致性要求较高,数据会频繁更新,高并发读写的业务场景存储引擎管理
alter table 表名 engine=MyISAM|InnoDB 针对于已经存在的表vim /etc/my.cnf 修改mysql配置文件设置新建表的默认存储引擎
[mysqld]
default-storage-engine=MyISAM|InnoDBcreate table 表名 (....) engine=MyISAM|InnoDB 新建表时指定存储引擎
查看存储引擎
show create table 表名;
show table status from 库名 where name='表名';show engines;