- mvcc
- 参考链接:大厂最爱问的MVCC,到底是个啥?
- MVCC,即Multi-Version Concurrency Control (多版本并发控制)。它是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
- 通俗的讲,
- 数据库中同时存在多个版本的数据,并不是整个数据库的多个版本,而是某一条记录的多个版本同时存在,在某个事务对其进行操作的时候,需要查看这一条记录的隐藏列事务版本id,比对事务id并根据事物隔离级别去判断读取哪个版本的数据。
- 数据库隔离级别读已提交、可重复读 都是基于MVCC实现的,相对于加锁简单粗暴的方式,它用更好的方式去处理读写冲突,能有效提高数据库并发性能。
- 关键知识点
- 事务版本号
- 事务每次开启前,都会从数据库获得一个自增长的事务ID,可以从事务ID判断事务的执行先后顺序。这就是事务版本号。
- 隐式字段
- 对于InnoDB存储引擎,每一行记录都有两个隐藏列trx_id、roll_pointer,如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列row_id。
- 事务版本号
-
-
- undo log
- undo log,回滚日志,用于记录数据被修改前的信息。在表记录修改之前,会先把数据拷贝到undo log里,如果事务回滚,即可以通过undo log来还原数据。
- 可以这样认为,当delete一条记录时,undo log 中会记录一条对应的insert记录,当update一条记录时,它记录一条对应相反的update记录。
- undo log有什么用途呢?
- undo log
-
-
-
-
-
- 事务回滚时,保证原子性和一致性。
- 用于MVCC快照读。
-
-
-
-
-
- 版本链
- 多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针(roll_pointer),连成一个链表,这个链表就称为版本链
- 流程
- 假设现在有一张core_user表,表里面有一条数据,id为1,名字为孙权:
- 现在开启一个事务A:对core_user表执行update core_user set name ="曹操" where id=1,会进行如下流程操作
- 首先获得一个事务ID=100
- 把core_user表修改前的数据,拷贝到undo log
- 修改core_user表中,id=1的数据,名字改为曹操
- 把修改后的数据事务Id=101改成当前事务版本号,并把roll_pointer指向undo log数据地址。
- 快照读和当前读
- 快照读
- 读取的是记录数据的可见版本(有旧的版本)。不加锁,普通的select语句都是快照读,如:select * from core_user where id > 2
- 当前读
- 读取的是记录数据的最新版本,显式加锁的都是当前读
- select * from core_user where id > 2 for update;
- select * from account where id>2 lock in share mode;
- 快照读
- Read View
- Read View是什么呢? 它就是事务执行SQL语句时,产生的读视图。实际上在innodb中,每个SQL语句执行前都会得到一个Read View。
- Read View有什么用呢? 它主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据~
- 版本链
- MVCC 实现原理
- 获取事务自己的版本号,即事务ID
- 获取Read View
- 查询得到的数据,然后Read View中的事务版本号进行比较。
- 如果不符合Read View的可见性规则, 即就需要Undo log中历史快照;
- 最后返回符合规则的数据
- InnoDB 实现MVCC,是通过Read View+ Undo Log 实现的,Undo Log 保存了历史快照,Read View可见性规则帮助判断当前版本的数据是否可见。
-
- int(1)、int(10)区别
- INT(1) 和 INT(10)本身没有区别,但是加上(M)值后,会有显示宽度的设置
- M的值与int(M)所占多少存储空间没有任何关系,int(1)、int(10)、int(11) 在磁盘上都是占用 4 btyes 的存储空间。
- 与int类型的字段能存储的数据最大最小值也没有任何关系,int类型的字段能存储的数据上限还是2147483647(有符号型)和4294967295(无符号型)
- 组合索引创建规则,检索规则
- 最左前缀
- 事务隔离级别可重复读
- 是通过MVCC,进行版本控制,查看数据权限。是否可以查看已提交、未提交的数据
- Mysql主从
- 主从延迟
- 主从配置不一致,会导致主从延迟
- 慢SQL,阻塞SQL执行
- 大批量数据写入,触发刷脏页
- 主从延迟
- binlog 监听
- Canal
- 高可用基于 ZK
- 存储引擎 - innodb 与 mysiam
- mysiam 不支持事物、不支持行锁
- innodb 没有存储总行数
- innodb 支持读写并发,写不阻塞读(MVCC)。
- 聚簇索引和非聚簇索引的区别
- innodb 聚簇索引,叶子结点,寸了数据,不需要回表
- innodb 非主键索引,普通索引,如果查询的字段不包含在索引树上,也需要回表。非聚簇索引
- mysiam 非聚簇索引,需要回表查询
- innodb 聚簇索引,叶子结点,寸了数据,不需要回表
- 使用行锁的条件
- 回表
- 索引类型分为主键索引和非主键索引。
主键索引的叶子节点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引(clustered index)。
-
- 非主键索引的叶子节点内容是主键的值。在InnoDB里,非主键索引也被称为二级索引(secondary index)。
- 索引失效的场景
- 优化器选错索引
- 采样基数,预估扫描行数较多
- 在回表操作较多和 直接在主键上查找更快上,进行判断
- 是否有order by
- 选错索引解决办法
- force index 强制走索引
- 重新分析基数 analyze table tableName;
- 修改sql,引导走索引
- 删除索引(有些索引,真的是没有必要存在的索引)
- 优化器选错索引
- sql优化
-
- 慢SQL日志
- explian
- profile
- 外部工具
- soar
- SQL 执行过程
- 客户建立连接
- 连接器:管理连接,权限验证
- 分析器:词法分析,语法分析
- 查询缓存:如果有,则直接返回
- 优化器:执行计划生成,索引选择
- 执行器:操作引擎,返回结果
- 客户建立连接
- 事务的特性
- ACID
- 原子性
- 一致性
- 隔离性
- 持久性
- ACID
- 事务的隔离级别
- 读未提交
- 一个事务还未提交,它所做的变更就可以被别的事务看到
- 读已提交
- 一个事务提交之后,它所做的变更才可以被别的事务看到
- 可重复读
- 一个事务执行过程中看到的数据是一致的。未提交的更改对其他事务是不可见的
- 串性化
- 对应一个记录会加读写锁,出现冲突的时候,后访问的事务必须等前一个事务执行完成才能继续执行
- 读未提交
- 事务并发存在的问题
- 脏读
- 不可重复读
- 幻读
- 事务嵌套
- 考察 MVCC
- 事务隔离级别
- 事务并发存在的问题
- B+Tree
- Mysql是一种关系型数据库,区间访问是常见的一种情况,B+树叶节点增加的链指针,加强了区间访问性,可使用在范围区间查询等
- B+树的高度一般为2-4层,所以查找记录时最多只需要2-4次IO,相对二叉平衡树已经大大降低了。
- 除了B+tree,还有那些索引
- B+tree
- 全文索引
- HASH索引
- group by之后order by失效的原因
- 通俗解释:
- 因为group by 和 order by 一起使用时,会先使用group by 分组,并取出分组后的第一条数据,所以后面的order by 排序时根据取出来的第一条数据来排序的,但是第一条数据不一定是分组里面的最大数据
- 官方解释:
- mysql5.7版本 order by 如果没有加limit 就会失效(半链接优化子查询)
- 查看链接:MySQL :: MySQL 5.7 Reference Manual :: 8.2.2.1 Optimizing Subqueries, Derived Tables, and View References with Semijoin Transformations
- 通俗解释:
参考链接:
我为人人,人人为我,美美与共, 天下大同。