博客

B+树的叶子节点到底是双向链表还是单向链表

May 14, 2023
后端开发, 数据库
Mysql, 数据库

前言 #

刚使用mysql的前几年,没有深入地了解mysql的内部实现,关于B+树的叶子节点的了解仅仅是:B+树的叶子节点按照自增id的大小自左至右排序,新增的元素排在右边。 后来突然某一天在网上看到一篇文章,说B+树的叶子节点是双向链表,这让我很是疑惑,因为我一直以为B+树的叶子节点是单向链表,这篇文章是不是写错了呢?然而这片 文章也仅仅是提了一句,并没有详细论述,当时我也没有深入研究,只是在心里泛起疑问:如果是单向链表,那平时业务中经常有按主键id或者时间排序,把最新的排在最前面,是怎么回事?。 后来随着对mysql的深入学习,发现B+树的叶子节点其实是双向链表+单向链表,这篇文章就是为了解答这个疑问。

...

InnoDB的Buffer Pool

May 7, 2023
后端开发, 数据库
Mysql

什么是Buffer Pool #

Buffer Pool(缓冲池),是InnoDB存储引擎在Mysql启动时向操作系统申请的一片连续的内存,是为了缓存磁盘中的页。 相关配置项:

innodb_buffer_pool_size = 134217728

Buffer Pool的组成 #

  • 缓冲页 Buffer Pool的内存被划分为若干个页,页面大小与InnoDB表空间使用的页面大小一致,默认是16KB。我们称其为缓冲页。
  • 控制块 为了更好地管理缓冲页,InnoDB为每个缓冲页都创建了一些控制信息,含有缓冲页的表空间编号、页号、地址、链表节点信息等。我们称其为控制块。
  • 碎片 控制块和缓冲页之间的空间。可能没有。
innodb_buffer_pool_size并不包含控制块占用的内存空间大小,所以实际申请的内存空间会比innodb_buffer_pool_size大一些。

free链表的管理 #

InnoDB向操作系统申请内存空间后,把它划分成若干对控制块和缓冲页,并没有真实的磁盘页倍缓存到Buffer中,之后随着程序的原型,才会有 磁盘上的页被缓存到Buffer Pool中。

...

索引合并导致锁超时

May 7, 2023
后端开发, 数据库
数据库

本文示例数据表版本:mysql8.0.32。隔离级别:读已提交。

什么是索引合并? #

索引合并指将多个索引的扫描结果合并起来,作为最终的扫描结果。 下面举例说明:

初始化表:

CREATE TABLE `t8` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `a` int NOT NULL DEFAULT '0',
  `b` int NOT NULL DEFAULT '0',
  `c` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_a` (`a`),
  KEY `idx_b` (`b`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

初始化数据:

...

mysql5.x自增id被重置问题

May 5, 2023
Mysql, 数据库
Mysql, 自增id

问题描述 #

mysql版本:5.6。 引擎:InnoDB。

内网环境,测试一个旧业务时,发现自增id很小,此业务已上线很久,自增id应该很大了,于是怀疑是不是自增id被重置了。 经过和运维同事沟通,判断这是mysql自身的问题:重启之后,自增id被重置了。

...

Redis事务执行失败经历1

May 4, 2023
Redis
Redis

报错信息 #

在开发调试过程中,遇到了redis事务执行失败的问题,报错信息如下:

EXECABORT Transaction discarded because of previous errors.

开发语言:go。 使用redis-client:go-redis。 调用方式:TxPipeline,即管道事务。 redis版本:4.0。

...