存储引擎:
mysql当中数据用各中不同的技术存储在文件中,每一种技术都使用的是不同的存储机制,索引技巧 索引水平,以及最终提供的不同功能和能力,这些就是我们说的引擎。
功能:
- mysql将数据存储在文件系统中的一种方式和格式
- 存储引擎负责执行实际的数据i/o操作(读写操作)
- 存储引擎介于数据和文件系统之间,数据会先保存到存储引擎,在按照存储引擎的格式保存到文件系统
Mysql存储引擎的分类:
- INNODB:5.5之后mysql的默认存储引擎,又叫做事务性速记引擎,支持ACID事务,支持行锁,锁表,写入和查询性能比较好
- MYISAM:5.5之间的默认存储引擎,插入数据的性能较高,查询速度也很优秀,但是不支持事务
- Memory:所有数据都保存在内存的存储引擎,插入数据,更新数据速度都比较快,但是占用内存空间比较大,会占用和数据成正比的内存空间,mysql一旦重启,数据就会丢失
- CSV:由逗号分隔数据的存储引擎,他会在数据库的子目录里为每个数据创建一个csv的文件,就是一种普通的文本文件,每个数据行都占用文本行,csv不支持索引
- Archive:非常适合大量的独立的,历史数据的引擎,不需要被经常读取,插入的速度很快,查询的效率比较低
- Blackhole:黑洞引擎,写入的任何数据都会消失
MYISAM和INNODB分析对比:
MYISAM:不支持事务,不支持外键,只支持全文索引,数据文件和索引文件是分开的,访问速度快
适合场景:查询和插入数据为主得到应用
在磁盘上有三个文件:
文件名和表名相同,但是扩展名不同:
.frm 存储的表结果
.MYD 数据文件
.MYI 索引文件
查看引擎:
配置文件修改引擎(这种方式只对新建的表有效)
修改存储引擎·:
方法1:
方法2:
通过修改 /etc/my.cnf 配置文件,指定默认存储引擎并重启服务
方法3:
创表时创建
查看数据库内容:
MYISAM的特点:
- 表级锁定,更新数据时,整个都将锁定
- 数据库在读写过程中相互阻塞
MYISAM支持的存储格式:
- 静态表,固定长度表,静态表式MYISAM的默认存储格式,静态表中字段都是非可变字段,每一个记录都是固定长度,存储快,方便缓存,故障容易恢复,缺点是占用空间比较多
- 动态表,动态表可以支持包含可变字段,记录的长度是不固定的,优点是占用空间少,频繁更新数据,删除记录,会产生碎片,需要定期清理(命令:myisamchk -r),出现故障恢复比较困难
- 压缩表:myisamchk工具创建的,占据的空间非常小,每条记录都是单独压缩的
INNODB:
支持4个事务的隔离级别,5.5之后是mysql的默认存储引擎
读写阻塞和隔离级别相关。
支持高效的缓存索引以及缓存数据
表以主键以簇的方式存储btree
支持外键约束,5.5之后INNODB也可以支持全文索引
支持行锁定,也可以支持表锁定(全表扫描)
- 使用like模糊查询,会进行全表扫描,锁定整个表
- 对没有创建索引的字段进行增,删,改,也会进行全表扫描,锁定整个表
- 使用索引,进行增,删,改,则是行级锁定
INNODB的特点:
- 不保存表的行数,统计表的行数,会扫描一遍整个表来计算有多少行
- 自增长,INNODB中必须包含只有该字段的索引
- Delete清空表,一行一行删,速度比较 truncate(推荐使用)
适用场景:
- 业务需要事务的支持
- 论坛,微博,对数据一致性比较高的场景
- 访问量和并发量比较高的场景,INNODB支持缓存,减少后台服务器的压力
三个文件:
表名.frm(表结构文件)
表名.ibd(即是索引文件,又是索引文件)
db.opt:(表的属性文件)
创表时指定引擎:
INNODB行锁和索引的关系 以及表锁 排查锁 死锁
INNODB锁行:
如果是主键呢
如果说使用的ID字段是主键INNODB对主键使用聚簇索引,锁定整行的记录,其他行不受影响
解决方法,一边commit提交即可
INNODB锁表:
要对一个非索引键进行操作
如果其他行呢,也不能执行
只是写入被锁定,对查没有影响
解决方式,commit即可
锁表小结:当一个事务对非索引列进行操作,因为因为要 全表扫描过滤,所有整张比表都会被锁死,唯有可查
排他锁:
里面的事务一提交,外面的就结束了,可以继续操作
For update 排他锁
死锁:
事务之间相互等待对方资源,最后形成一个环路造成的
- 发生死锁时,数据库会自动选择一个事务作为受害者,然后先解除死锁,再进行回滚
- 一旦发生死锁,会选择一个事务作为死锁的牺牲品,直接终止其中一个事务,但是不会自动回滚
总结:
索引,锁行
非索引,锁表
排他锁,一个事务在操作,另一个事务无法执行,只能查,排他锁只能加一个,排他锁也叫悲观锁,乐观锁(补充)不会有任何提示,只是数据不能写入,数据提交更新时,进行校验,发生冲突,数据不生效而已,没有其他的报错或者卡顿
死锁,会自动选择一个事务作为牺牲品,结束死锁
演示要求:
- 存储引擎只能时INNODB
- Mysql默认隔离级别即可
如何尽可能的避免死锁:
- 业务的逻辑必须要合理,以固定的顺序访问表和行
- 如果事务的类型比较复杂,要进行拆分,在业务允许的情况下,把大的事务拆小,分次执行
- 在同一事务中,尽可能的一次性锁定所有需要的资源,可以减少死锁的概率
- 隔离级别,read commit。可以避免死锁
- 添加合理的索引,可以减少死锁的概率