存储引擎
索引
锁
日志
索引存在哪?
mac电脑/usr/local/mysql
win C:/programdata/mysql
innodb引擎索引和数据存在一起 ,.idb文件
MyISAM引擎索引和数据分开存储,.MYI文件存索引,.MYD存数据
B+数特点:
非叶子节点有冗余叶子节点数据
叶子节点从小到大排序
叶子节点有指针
只有叶子节点存数据
https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
为什么innodb必须有主键?
如果没有,innodb会默认创建虚拟主键,普通索引使用这个虚拟主键造成性能开销
为什么主键要整型自增?
整型比较最快,自增对树结构旋转调整开销最小,从右边加入
MVCC设计思想:multi-version concurrency control
数据库性能和安全的平衡
MySQL在读和写的操作中,对读的性能做了并发性保障,让读都是快照读。对于写,进行版本控制,如果真实数据比快照版本新,那么写之前要更新快照,这样可以提高读性能,和写的安全。
事务:
原子性:多条sql在一个事务中要么都成功,要么都失败
一致性:事务提交前和回滚后的数据是一样的
持久性:持久性是指一旦事务成功提交后,只要修改的数据都会进行持久化,不会因为异常、宕机而造成数据错误或丢失
隔离性:多个事务并发访问,一套隔离机制,让不同隔离级别产生不同并发效果。
隔离性:
读未提交:A事务会读B事务未commit的修改,脏读
读已提交:A事务会读B事务commit的修改,有重复读问题
可重复读:同一个事务的读取结果一样,有幻读问题
串行化:不允许其他事物进行,锁表
幻读:一个事务里多次查询,结果集个数不一样。通过间隙锁解决
在RR的隔离级别下,Innodb使用MVCC和next-key locks解决幻读,MVCC解决的是普通读(快照读)的幻读,next-key locks解决的是当前读情况下的幻读,因为给间隙也枷锁了,所以没法插入数据。select…for update
在快照读读情况下,mysql通过mvcc来避免幻读。
在当前读读情况下,mysql通过next-key来避免幻读。
select * from t where a=1;属于快照读
select * from t where a=1 lock in share mode;属于当前读
锁
读锁:共享锁、shared locks、S锁,比如select … lock in share mode
写锁:排他锁、exclusive locks、X锁,比如:select…for update,insert,update,delete
select:不加锁
只有S和S锁不冲突,X和任何锁都冲突
日志
bin_log
归档日志(二进制日志)
binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。
binlog 的主要使用场景有两个,分别是 主从复制 和 数据恢复 。
undo_log
保证事务的原子性,日志路径参数=innodb_undo_directory,一般在mysql默认数据目录datadir
实现事务的原子性
undo log可以用于实现事务的原子性, 如果事务处理过程出现一些特殊情况,比如sql错误等等情况,就要执行回滚(rollback)操作,mysql就可以利用undo log将数据恢复到事务开始之前
实现多版本并发控制(MVCC)
Undo Log 在 MySQL InnoDB 存储引擎中用来实现多版本并发控制,事务没提交之前,undo日志可以作为高并发情况下,其它并发事务进行快照读
redo_log
是保证事务的持久性
前面的学习,我们知道undo log是用于回滚的日志记录,是属于逻辑日志,而本博客介绍的redo log是一种物理日志,只要用于预防系统冗机等特殊情况,出现这种情况时,重启mysql会读取redo log,从而实现某些数据未写入磁盘的数据写到磁盘进行持久保存