MySQL
(一)请你说一下MySQL存储引擎和区别
1、Innodb引擎
(1)定义
- 事务型存储引擎。是MySQL的默认存储引擎,支持行级锁定、MVCC多版本控制、非锁定读、事务、外健等特性。
- 对事务的支持,让MySQL成为更加完善的数据库管理系统系统,行级锁定使InnoDB可以支持更大的并发数。
(2) InnoDB存储引擎对ACID的实现方式
- 利用回滚日志(undo log) 和 重做日志(redo log) 两种表实现事务,并实现 MVCC (多版本并发控制);
- 在执行事务的每条SQL时,会先将数据原值写入undo log 中, 然后执行SQL对数据进行修改,最后将修改后的值写入redo log中。
- redo log 重做日志包括两部分:1 是内存中的重做日志缓冲 ;2 是重做日志文件。在事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务commit操作完成才算完成。
- 当一个事务中的所有SQL都执行成功后,会将redo log 缓存中的数据刷入磁盘,然后提交。
- 如果发生回滚,会根据undo log 恢复数据。
(3) 灾难恢复性好/掉电怎么恢复
- InnoDB 通过 commit、rollback、crash-recovery 来保障数据的安全。
- 具体来说,crash-recovery 就是指如果服务器因为硬件或软件的问题而崩溃,不管当时数据是怎样的状态,在重启 MySQL 后,InnoDB 都会自动恢复到发生崩溃之前的状态,并回到用户离开的地方。
- 在数据库的安装位置找到my.cnf文件。设置innodb_force_recovery 的值。重新运行 service mysql start,启动成功。
2、 MyISAM引擎
(1)定义
- MyISAM支持表级锁定,并不支持事务,比较适合大量的select和insert操作。
3、 区别:
- MyISAM是非事务安全的,而InnoDB是事务安全的
- MyISAM锁的粒度是表级的,而InnoDB支持行级锁
- MyISAM支持全文类型索引,而InnoDB不支持全文索引
- MyISAM相对简单,效率上要优于InnoDB,小型应用可以考虑使用MyISAM
- MyISAM表保存成文件形式,跨平台使用更加方便
- 应用场景:
- MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果再应用中执行大量select操作,应该选择MyISAM
- InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB
(二)锁
1、 意义
- 数据库是通过加锁,来实现事务的隔离性的。
- 锁机制用于管理对共享资源的并发访问。串行化隔离级别就是加锁实现的。
2、 粒度
- 行锁:作用在数据行上,锁的粒度比较小
- 表锁:作用在整张数据表上,锁的粒度比较大
3、 分类
(1)记录锁
- 共享锁(S Lock):允许事务读一行数据
- 排他锁(X Lock):允许事务删除或更新一行数据
- 兼容性
(2) 间隙锁
- 关闭间隙锁的2种方式:
(1)将事务隔离级别变为read committed
(2)将参数innodb_locks_unsafe_for_binlog设置为1 - 在上述配置下,除了外键和唯一性检查依然需要间隙锁,其余情况仅适用行锁进行锁定。
(3) 临建锁
- 主要是阻止多个事务将记录插入到同一个范围内,从而避免幻读。
- 当查询的索引是唯一索引的时候,InnoDB会将临键锁优化成记录锁,从而提高并发。
(4) 意向锁
- 意向共享锁(intention shared lock, IS),它预示着,事务有意向对表中的某些行加共享S锁
- 意向排它锁(intention exclusive lock, IX),它预示着,事务有意向对表中的某些行加排它X锁
(5) 乐观锁
-
乐观锁:不上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作.两个实现方法
-
CAS机制(compare and swap)
3个操作数:读写的内存位置V,比较的预期值A,拟写入的新值B
过程:if V装的值==A:则把该位置V的值更新为B;else:自旋等待,一直重试
如何保证原子性:CAS由CPU支持,硬件层面保证 -
版本号机制(实际情况可以选择时间戳表示版本号)
在数据中增加一个字段version;每当数据被修改,版本号加1;
当某个线程查询数据时,将该数据的版本号一起查出来;
当该线程更新数据时,判断当前版本号与之前读取的版本号是否一致,如果一致才进行操作。
(6) 悲观锁
- 悲观锁:操作数据时直接把数据锁住,期间任何人不能修改
- 实现 :对于mysql可以使用排它锁
4、 缺点
- 频繁的加锁,导致读数据时,没办法修改,修改数据时,没办法读取,大大降低了数据库性能。
- 如何解决加锁后的性能问题的?——MVCC多版本并发控制