当前位置: 首页 > news >正文

MySQL八股学习笔记

文章目录

  • 一、MySQL结构
    • 1.宏观结构
      • 1.1.Server层
      • 1.2.存储引擎层
    • 2.建立链接-连接器
    • 3.查询缓存
    • 4.解析SQL-解析器
        • (1)词法分析
        • (2)语法分析
    • 5.执行SQL
      • 5.1.预处理器 prepare
      • 5.2.优化器 optimize
      • 5.3.执行器 execute
        • (1)主键索引查询
        • (2)全表扫描
        • (3)索引下推
  • 二、MySQL存储
    • 1.表空间结构
    • 2.行格式
      • 2.1.记录的额外信息
        • (1)变长字段长度列表
        • (2)NULL值列表
        • (3)记录头信息
      • 2.2.记录的真实数据
        • (1)row_id
        • (2)trx_id
        • (3)roll_pointer
      • 2.3.行溢出与行类型
    • 3.数据页
      • 3.1.数据页组成
      • 3.2.页目录
        • (1)创建
        • (2)规定
  • 三、索引
    • 1.索引分类
      • 1.1.数据结构
        • (1)B+树索引
        • (2)Hash索引
        • (3)Full-text索引
      • 1.2.物理存储
        • (1)聚簇索引(主键索引)
        • (2)二级索引(辅助索引/非聚簇索引)
      • 1.3.字段特性
        • (1)主键索引
        • (2)唯一索引
        • (3)普通索引
        • (4)前缀索引
      • 1.4.字段个数
        • (1)单列索引
        • (2)联合索引
    • 2.索引创建
      • 2.1.索引缺点
      • 2.2.适用索引
      • 2.3.不适用索引
    • 3.索引优化
      • 3.1.前缀索引优化
      • 3.2.覆盖索引优化
      • 3.3.主键索引自增
      • 3.4.索引NOT NULL
      • 3.5.防止索引失效
    • 4.索引效率
    • 5.B+树
      • 5.1.特点
      • 5.2.查找
    • 6.索引失效
      • 6.1.左/左右模糊匹配
      • 6.2.函数
      • 6.3.表达式计算
      • 6.4.隐式类型转换
      • 6.5.联合索引非最左匹配
      • 6.6.WHERE中的OR
  • 四、事务
    • 1.事务特性
      • 1.1.原子性
      • 1.2.一致性
      • 1.3.隔离性
      • 1.4.持久性
    • 2.并发事务的问题
      • 2.1.脏读
      • 2.2.不可重复读
      • 2.3.幻读
    • 3.事务隔离级别
      • 3.1. 读未提交
      • 3.2.读提交
      • 3.3.可重复读
      • 3.4.串行化
    • 4.Read View
      • 4.1.Read View基础
        • (1)字段组成
        • (2)可见性划分
      • 4.2.Read View与读提交
      • 4.3.Read View与可重复读
  • 五、锁
    • 1.锁分类
      • 1.1.全局锁
      • 1.2.表级锁
        • (1)表锁
        • (2)元数据锁(MDL)
        • (3)意向锁
        • (4)AUTO-INC锁
      • 1.3.行级锁
        • (1)Record Lock
        • (2)Gap Lock
        • (3)Next-Key Lock
        • (4)插入意向锁
    • 2.行级锁实现
      • 2.1.唯一索引
        • (1)等值查询
        • (2)范围查询
      • 2.2.非唯一索引
        • (1)等值查询
        • (2)范围查询
      • 2.3.无索引
    • 3.死锁问题
      • 3.1.死锁产生
      • 3.2.死锁避免
      • 3.3.Insert加行级锁
        • (1)间隙锁情况
        • (2)唯一键冲突
  • 六、日志
    • 1.undo log 回滚日志
      • 1.1.特点
      • 1.2.特点
    • 2.buffer pool 缓存池
      • 2.1.作用
      • 2.2.缓存内容
    • 3.redo log 重做日志
      • 3.1.作用
        • (1)WAL技术
        • (2)redo log特性
        • (3)与undo log对比
        • (4)特点
      • 3.2.刷盘
        • (1)刷盘时机
        • (2)主动刷盘
      • 3.3.文件写满
    • 4.binlog 归档日志
      • 4.1.与redo log对比
        • (1)适用对象
        • (2)文件格式
        • (3)写入方式
        • (4)用途
      • 4.2.主从复制
        • (1)过程
        • (2)从库数量
        • (3)主从复制模型
      • 4.3.刷盘
    • 5.两阶段提交
      • 5.1.作用
      • 5.2.过程
      • 5.3.异常重启
      • 5.4.存在问题
      • 5.5.组提交
        • (1)flush阶段
        • (2)sync阶段
        • (3)commit阶段
  • 七、buffer pool的管理
  • 八、其他
    • 1.1.vanchar(n)中n的最大取值
    • 1.2.长连接占用内存问题
    • 1.3.回表和覆盖索引
      • (1)回表
      • (2)覆盖索引
    • 2.1.MySQL单表最大值
    • 2.2.MySQL使用"%x"一定会索引失效吗
    • 2.3.count(*)和count(1)对比
      • (1)对比
      • (2)count(*)/count(1)过程
      • (3)count(主键字段)过程
      • (4)count(字段)过程
    • 2.4.为什么采用B+树
      • (1)相比B树
      • (2)相比二叉树
      • (3)相比Hash
    • 4.1.update全局锁事故
    • 5.1.MySQL磁盘I/O优化
    • 5.2.update全过程

一、MySQL结构

在这里插入图片描述

1.宏观结构

1.1.Server层

建立连接→解析SQL→执行SQL;

包含连接器查询缓存解析器预处理器优化器执行器等。以及内置函数跨存储引擎的功能

1.2.存储引擎层

目前最常用的是InnoDB存储引擎。

2.建立链接-连接器

通过TCP进行连接,同时分为短连接(每次执行SQL都需要建立TCP连接)、长连接(减少反复建立和断开TCP连接)。

3.查询缓存

MySQL8.0之后已废弃

查询语句会优先去位于server层查询缓存(query cache)中查找缓存数据。如果命中,直接返回;如果没有命中,继续往下执行,查询结果会被存入查询缓存。

但,一个表有更新,其对应的缓存就会被清空。对于频繁更新的表,很不适用。

4.解析SQL-解析器

(1)词法分析

识别SQL语句的关键字和非关键字。

(2)语法分析

判断SQL语句是否符合语法(不负责判断字段和表是否存在),构建SQL语法树。

5.执行SQL

5.1.预处理器 prepare

  • 检查SQL语句中的字段、表是否存在。
  • select *中的*扩展为表上的所有列。

5.2.优化器 optimize

确定SQL语句的执行方案,如索引的选择。

5.3.执行器 execute

(1)主键索引查询
  • 第一次查询
    优化器选择索引类型→执行器调用函数指针read_first_record 指向InnoDB 引擎索引查询的接口→存储引擎定位→执行器判断条件符合与否,返回结果

  • 非第一次查询
    优化器选择索引类型→执行器调用函数指针read_record指向-1(访问类型const时)→执行器直接返回结果

(2)全表扫描
  • 第一次查询
    优化器选择索引类型→执行器调用函数指针read_first_record指向InnoDB 引擎全扫描的接口→存储引擎定位→执行器判断条件符合与否,逐条返回结果

  • 非第一次查询
    优化器选择索引类型→执行器调用函数指针read_record指向InnoDB 引擎全扫描的接口→存储引擎读取下一个结果,逐条返回给执行器→执行器返回读取完毕结果

(3)索引下推

在二级索引中,将原本执行器的判断工作,交给存储引擎来做。有利于减少回表操作。

二、MySQL存储

1.表空间结构

在这里插入图片描述

  • 行 row
    数据库中的记录按行存储,
  • 页 page
    数据库按页来读写,默认页大小16KB。
  • 区 extent
    表的数据量大时,索引的空间按照区分配(不再是页),每个区大小1MB(64个页)。使得索引的链表中相邻的页,实现物理位置的相邻。可以使用顺序I/O。
  • 段 segment
    • 索引段:存放B+树非叶子节点
    • 数据段:存放B+树叶子节点
    • 回滚段:存放回滚数据的区的集合

2.行格式

在这里插入图片描述

以下均为Compact行格式。

2.1.记录的额外信息

(1)变长字段长度列表

可选字段。每个1或2字节的位存储(取决于变长字段是否大于255位),存在变长字段时,如varchar,逆序存放字段的长度信息(不含NULL)。

逆序存放有利于提高CPU Cache的命中率。这是因为可以减少CPU缓存行分裂(第一个字段数据和对应变长字段长度列表,更大的可能被放在同一个CPU缓存行)和提升数据局部性(局部性原理:一个数据被访问时,其附近的数据大概率也将要被访问。提高CPU猜中下一步数据的概率)。

(2)NULL值列表

可选字段。共1或2字节的位存储(取决于可NULL的字段数),1表示为NULL,0表示不是NULL,同样位逆序存放。

(3)记录头信息
  • delete_mask :标识此条数据是否被删除。
  • next_record:下一条记录的位置。指向的是下一条记录的「记录头信息」和「真实数据」之间的位置。
  • record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录。

2.2.记录的真实数据

(1)row_id

非必需的隐藏字段,占6字节。如果表无主键,也没有唯一约束,才会添加。

(2)trx_id

事务id,必需的,占6字节。表示数据由哪个事务生成。

(3)roll_pointer

指向上一个版本的指针,必需的,占7字节。

2.3.行溢出与行类型

对于Compact行格式:真实数据处占用20个字节指向溢出页的地址。
在这里插入图片描述

对于Compressed和Dynamic行格式:真实数据处置存储20个字节的指针指向溢出页的地址。
在这里插入图片描述

3.数据页

3.1.数据页组成

在这里插入图片描述

在这里插入图片描述

3.2.页目录

在这里插入图片描述

(1)创建
  1. 将所有的记录划分成几个组,包括最小记录和最大记录;
  2. 组内最大记录的头信息中,会存储该组记录数量(上图中粉红色字段)
  3. 页目录用来存储组内最大记录的地址偏移量(槽)。
(2)规定

采用二分法检索。

  1. 第一个分组中的记录只能有 1 条记录;
  2. 最后一个分组中的记录条数范围只能在 1-8 条之间;
  3. 剩下的分组中记录条数范围只能在 4-8 条之间。

三、索引

1.索引分类

1.1.数据结构

(1)B+树索引

M叉树+双向链表的结构。非叶子节点无数据,叶子节点保存数据。本章第5节详细介绍。

(2)Hash索引

一种基于哈希表的索引。

(3)Full-text索引

使用倒排索引实现,允许全文搜索。

1.2.物理存储

InnoDB中的以下二者都使用B+树实现。

(1)聚簇索引(主键索引)

在这里插入图片描述

  • 生成
    (1)默认使用主键建立索引。
    (2)无主键时,使用不含NULL的唯一列。
    (3)都没有时,自动生成一个隐式自增id。

  • 结构
    基于B+树,非叶子结点无数据,叶子节点存数据。

(2)二级索引(辅助索引/非聚簇索引)
  • 结构
    基于B+树,非叶子结点无数据,叶子节点存主键。

1.3.字段特性

(1)主键索引

一张表只有一个,不允许空值、重复。

CREATE TABLE table_name  (....PRIMARY KEY (index_column_1) USING BTREE
);
(2)唯一索引

不允许重复,但允许空值的索引。

CREATE TABLE table_name  (....UNIQUE KEY(index_column_1,index_column_2,...) 
);
(3)普通索引

普通字段上创建。

CREATE TABLE table_name  (....INDEX(index_column_1,index_column_2,...) 
);
(4)前缀索引

前缀索引是指对字符类型字段的前几个字符建立的索引。可以建立在字段类型为 char、varchar、binary、varbinary 的列上。

CREATE TABLE table_name(column_list,INDEX(column_name(length))
); 

1.4.字段个数

(1)单列索引
(2)联合索引

通过将多个字段组合成一个索引,该索引就被称为联合索引。

CREATE INDEX index_product_no_name 
ON product(product_no, name);
  • 最左匹配原则
    假如有一个索引(a,b,c),在进行筛选时where时,要保障有a的前提下,再筛选b;有b的前提下,在筛选c(写的顺序无所谓)。否则会联合索引失效(导致了无序)。

  • 联合索引范围查询
    范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引。

比如where a>1 and b=2,b是无法用到联合索引的。

但是where a>=1 and b=2,在a=1时,b可以用到联合索引。

但是where a like 'j%' and b=2,在a='j’时(或其他相等的值时),b可以用到联合索引。其他时,b无法用到联合索引。

但是where a like '%j' and b=2,比较复杂。当联合的是主键和剩下唯一的一列时,是可以用到联合索引的。其他情况,应该是不能的(存疑)。

  • 索引区分度
    要把区分大的字段放在前边。如果区分度太小,联合索引会被优化器忽略,进行全表扫描。

  • 排序优化

select * from order 
where status = 1 
order by create_time asc

statuscreate_time建立联合索引,排序效率会更高。

2.索引创建

2.1.索引缺点

  1. 占用物理空间
  2. 创建和维护耗费时间
  3. 降低表的增删效率(B+树为了维护有序性,需要动态维护)

2.2.适用索引

  1. 字段具有唯一性
  2. 经常用where查询语句
  3. 经常用order bygroup by

2.3.不适用索引

  1. whereorder bygroup by用不到的字段
  2. 索引区分度低
  3. 数据太少时
  4. 频繁更新的字段

3.索引优化

3.1.前缀索引优化

使用前缀索引,减少索引字段大小。

但,order by无法使用前缀索引;无法吧前缀索引用作覆盖索引。

3.2.覆盖索引优化

建立联合索引的二级索引,避免/减少回表操作。

3.3.主键索引自增

每插入一条新纪录,只需要追加,不需要重新移动数据。

3.4.索引NOT NULL

NULL会导致优化器所索引选择时更加困难;
NULL占用额外物理空间(参考行格式)。

3.5.防止索引失效

避免索引失效的情况。详情见本章第6节。

4.索引效率

执行计划的参数:

possible_keys 字段表示可能用到的索引;
key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;
key_len 表示索引的长度;
rows 表示扫描的数据行数。
type 表示数据扫描类型,我们需要重点看这个。

type字段,执行效率从低到高:

All(全表扫描);
index(全索引扫描);
range(索引范围扫描);
ref(非唯一索引扫描);
eq_ref(唯一索引扫描);
const(结果只有一条的主键或唯一索引扫描)。

extra字段:

Using filesort :当查询语句中包含 group by 操作,而且无法利用索引完成排序操作的时候, 这时不得不选择相应的排序算法进行,效率是很低的。
Using temporary:使了用临时表保存中间结果,效率低。
Using index:使用了覆盖索引,避免了回表操作,效率不错。

5.B+树

在这里插入图片描述

5.1.特点

  1. 组成为M叉树+双向链表
  2. 所有节点按照索引键的大小排序
  3. 只有叶子节点才存放数据,非叶子节点仅存放目录项作为索引

5.2.查找

  1. 从根节点,先用二分法定位包含查询值的页。
  2. 非叶子节点,继续使用二分法定位包含查询值的页。
  3. 到叶子节点时,使用二分法定位槽,然后遍历槽找到对应的记录。

6.索引失效

索引失效会大幅降低查询性能。

6.1.左/左右模糊匹配

like %xx 或者 like %xx% 这两种方式都会造成索引失效。变成全表扫描。

6.2.函数

对索引使用函数,会造成索引失效。索引保存的是索引字段的原始值,而不是经过函数计算后的值。

6.3.表达式计算

对索引使用表达式计算(如where id +1 = 10),会造成索引失效。索引保存的是索引字段的原始值,而不是经过计算后的值。

6.4.隐式类型转换

MySQL在遇到字符串和数字比较时,会把字符串转为数字。相当于对索引使用了函数。

6.5.联合索引非最左匹配

参考本章1.4节。

6.6.WHERE中的OR

在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

四、事务

1.事务特性

ACID

1.1.原子性

undo log
一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。中间发现错误就回滚到事务开始前的状态。

1.2.一致性

原子性+隔离性+持久性
是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。

1.3.隔离性

MVCC(多版本并发控制)和锁机制
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

1.4.持久性

redo log
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

2.并发事务的问题

严重程度:
在这里插入图片描述

2.1.脏读

读到其他事务未提交的数据;
(未提交事务可能回滚)

2.2.不可重复读

前后读取的数据不一致;
(另一个事务在两次其读之间修改了数据)

2.3.幻读

前后读取的记录数量不一致。
(另一个事务在两次其读之间新增/删除了数据)

3.事务隔离级别

隔离水平:
在这里插入图片描述

可能发生的问题:
在这里插入图片描述

3.1. 读未提交

指一个事务还没提交时,它做的变更就能被其他事务看到;

3.2.读提交

指一个事务提交之后,它做的变更才能被其他事务看到;

  • 采用MVCC(Read View)方式实现。

3.3.可重复读

指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的(默认)。

实际上可以很大程度上避免幻读。

  • 快照读(普通 select 语句,查询)
    采用MVCC(Read View)方式解决。

  • 当前读(select … for update 等语句,查询并更新)
    采用next-key lock(记录锁+间隙锁)

3.4.串行化

会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

  • 采用读写锁方式解决。

4.Read View

4.1.Read View基础

(1)字段组成

在这里插入图片描述

  • m_ids :创建时,当前数据库中「活跃事务」的事务 id 列表。
  • min_trx_id :创建时,「活跃事务」中事务 id 最小的事务。
  • max_trx_id :创建时当前数据库中应该给下一个事务的 id 值,全局事务中最大的事务 id 值 + 1;
  • creator_trx_id :指的是创建该 Read View 的事务 id。
(2)可见性划分

与行格式的trx_id的关系:
在这里插入图片描述

  1. trx_id<min_trx_id,创建前已有,可见。
  2. trx_id>max_trx_id,创建后才有,不可见。
  3. min_trx_id<trx_id<max_trx_id时,若trx_idm_ids中,不可见;若trx_id不在m_ids中,可见。

4.2.Read View与读提交

在这里插入图片描述

当事务A提交后,事务B的Read View会重新创建。事务B会找历史中,trx_id小于其自身min_trx_id的记录。

4.3.Read View与可重复读

不论事务A是否提交,事务B的Read View都不会重新创建。事务B会找历史中,trx_id小于其自身min_trx_id的记录。

五、锁

1.锁分类

1.1.全局锁

主要用于全库逻辑备份,整个数据库都会变成只读。但是效率较低,备份期间,无法更新数据。

可以通过可重复读的隔离级别避免全局锁。备份前创建Read View,加上MCVV的支持,使得备份期间也可以进行更新操作。

1.2.表级锁

(1)表锁

颗粒度越大,会影响并发性能。

//表级别的共享锁,也就是读锁;允许自己/其他人读
lock tables t_student read;
//表级别的独占锁,也就是写锁;允许自己写
lock tables t_student write;
//解锁
unlock tables
(2)元数据锁(MDL)
  • 对一张表进行创建、读取、更改、删除操作时,加的是 MDL 读锁
  • 对一张表做结构变更操作的时候,加的是 MDL 写锁

无需显式调用,常规的读共享,写独占。但是已有读锁是,申请写锁会被阻塞,之后有新的读锁也会被阻塞(写锁优先级高)。

(3)意向锁
  • 作用:
    一个表级别的标识作用,当想给表里的部分记录共享锁/独占锁之前,需要先在表级别上加上一个意向共享锁/意向独占锁。用来告诉后续的,想加表级别锁的事务,这里以及有锁了。

  • 原因:
    由于表级别共享锁/独占锁,与行级别共享锁/独占锁存在读读共享、读写互斥、写写互斥。如果没有意向锁,想加表级别锁时,需要遍历查看表里是否有独占锁,效率会很低。

意向锁之间、意向锁与表级锁/行级锁不会发生冲突。

(4)AUTO-INC锁

对于自增表:AUTO-INC 锁是特殊的表锁机制,锁不是再一个事务提交后才释放,而是再执行完插入语句后就会立即释放。

轻量级锁:在插入数据的时候,会为被 AUTO_INCREMENT 修饰的字段加上轻量级锁,然后给该字段赋值一个自增的值,就把这个轻量级锁释放了,而不需要等待整个插入语句执行完后才释放锁。

  • innodb_autoinc_lock_mode
    • 0 采用AUTO-INC锁,语句执行结束后才释放锁
    • 2 采用轻量级锁,申请自增主键后就释放
    • 1
      • 普通insert:2;
      • 类似insert…select这样批量的:0;

采用2,性能高,但是主从复制经过binlog可能存在不一致的情况下,可以用过binlog_format=row解决。

1.3.行级锁

(1)Record Lock

Record Lock 称为记录锁,锁住的是一条记录。读共享(S锁),锁独占(X锁)。

(2)Gap Lock

Gap Lock 称为间隙锁,只存在于可重复读隔离级别。间隙锁之间是兼容的。

(3)Next-Key Lock

Next-Key Lock 称为临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。读共享,写独占。

(4)插入意向锁

不是意向锁,而是一种特殊的间隙锁,值锁住一个点。与间隙锁互斥。

2.行级锁实现

如果 LOCK_MODE 为 X,说明是 next-key 锁;
如果 LOCK_MODE 为 X, REC_NOT_GAP,说明是记录锁;
如果 LOCK_MODE 为 X, GAP,说明是间隙锁;

加锁的对象是索引

2.1.唯一索引

(1)等值查询

查询记录存在:Next-Key Lock会退化成记录锁。
查询记录不存在:Next-Key Lock会退化成间隙锁。
在这里插入图片描述

在这里插入图片描述

(2)范围查询

要考虑Next-Key Lock的左开右闭特性!再看各个分段是哪个锁!

大于
select * from user where id > 15 for update;
在这里插入图片描述

大于等于
select * from user where id >= 15 for update;
在这里插入图片描述

小于
select * from user where id < 6 for update;在这里插入图片描述

小于等于
select * from user where id <= 5 for update;
在这里插入图片描述

2.2.非唯一索引

会影响到主键,同时记录锁也会变成next-key锁。

(1)等值查询

记录不存在情况
select * from user where age = 25 for update;
在这里插入图片描述

锁住的不仅是age的(22,39),还包括id的(10,20)。

记录存在情况
select * from user where age = 22 for update;
在这里插入图片描述

锁住的不仅是age的(21,22],(22,39),还包括id的(5,20)。

(2)范围查询

不会退化
select * from user where age >= 22 for update;
在这里插入图片描述

锁住的不仅是age的(21,22],(22,39),(39,+∞],还包括id的(5,+∞)。

2.3.无索引

每一条记录的索引上都会加 next-key 锁,这样就相当于锁住的全表,这时如果其他事务对该表进行增、删、改操作的时候,都会被阻塞。

在线上在执行 update、delete、select … for update 等具有加锁性质的语句,一定要检查语句是否走了索引,如果是全表扫描的话,会对每一个索引加 next-key 锁,相当于把整个表锁住了。

3.死锁问题

3.1.死锁产生

在这里插入图片描述

事务A和事务B都给表加入了间隙锁(不冲突),之后想插入时,再想加入插入意向锁,便会产生冲突。需要等对方释放间隙锁,此时便产生死锁。

3.2.死锁避免

死锁的必要条件:互斥、占有且等待、不可强占用、循环等待。

  • 设置事务等待锁的超时时间:一个事务的等待时间超过该值后,进行回滚。
  • 开启主动死锁检测:检测到死锁后,主动回滚某一事务。

3.3.Insert加行级锁

Insert语句用的是隐式锁,也就是说不发生冲突时,不会提前加锁。

(1)间隙锁情况

当其他事务在本事务想要插入数据的地方,提前加了间隙锁。那么本事务会生成一个插入意向锁,然后阻塞住。

(2)唯一键冲突

当插入的记录,与已有记录的主键/唯一键二级索引列相同时,插入会失败,然后会为这条记录加上S型锁。分别加S型记录锁/S型next-key锁。

六、日志

在这里插入图片描述

1.undo log 回滚日志

1.1.特点

保证了事务的原子性;发生崩溃时用来回滚,作原先操作的相反操作(如原本是新增,那么就删除)。

一条记录的每一次更新操作产生的 undo log 格式都有一个 roll_pointer 指针和一个 trx_id 事务id:

  • 通过 trx_id 可以知道该记录是被哪个事务修改的;
  • 通过 roll_pointer 指针可以将这些 undo log 串成一个链表,这个链表就被称为版本链;
    在这里插入图片描述

1.2.特点

  1. 实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执行了 ROLLBACK 语句,MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态。
  2. 实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过 ReadView + undo log 实现的。undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的记录。

2.buffer pool 缓存池

基于内存。

2.1.作用

在这里插入图片描述

  • 读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
  • 修改数据时,如果数据存在于 Buffer Pool 中,那直接修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。

2.2.缓存内容

在这里插入图片描述

  • undo log 会写入到undo页。
  • 没查询一条记录,会将整个页加载到buffer pool中。

3.redo log 重做日志

基于磁盘。

3.1.作用

(1)WAL技术

WAL (Write-Ahead Logging) 技术指的是, MySQL 的写操作并不是立刻写到磁盘上,而是先写日志,然后在合适的时间再写到磁盘上。

(2)redo log特性

redo log是物理日志,持久化于磁盘;内存修改undo log后,需要记录对应的redo log。

(3)与undo log对比

undo log:记录事务开始前;
redo log:记录事务完成后。

(4)特点
  1. 实现事务的持久性,让 MySQL 有 crash-safe 的能力,能够保证 MySQL 在任何时间段突然崩溃,重启后之前已提交的记录都不会丢失;
  2. 将写操作从「随机写」变成了「顺序写」,提升 MySQL 写入磁盘的性能。

3.2.刷盘

基于redo log buffer

(1)刷盘时机
  1. MySQL正常关闭
  2. redo log buffer满了一半
  3. InnoDB后台线程每间隔一秒
  4. 主动刷盘
(2)主动刷盘

innodb_flush_log_at_trx_commit参数:

  • 0:不触发主动刷盘(安全性依赖数据库)
  • 1:每次事务提交都主动刷盘
  • 2:每次事务提交都写入到page cache(安全性依赖系统)

3.3.文件写满

有两个redo log文件组成“重做日志文件组”,两个文件循环写。
在这里插入图片描述

若redo log满了,MySQL会阻塞,停下来将buffer pool中的脏页刷新到磁盘,标记对应redo log可以擦除的部分。

4.binlog 归档日志

binlog 文件是记录了所有数据库表结构变更和表数据修改的日志。

4.1.与redo log对比

(1)适用对象
  • binlog :MySQL 的 Server 层实现的日志,所有存储引擎都可以使用

  • redo log :Innodb 存储引擎实现的日志;

(2)文件格式
  • binlog :STATEMENT(默认,记录SQL语句)、ROW(记录行数据变化)、MIXED。

  • redo log :物理日志;

(3)写入方式
  • binlog :追加写,不会覆盖。

  • redo log :追加写,循环写,会覆盖(redo 因此做不到大范围恢复);

(4)用途
  • binlog :用于备份恢复、主从复制;
  • redo log :用于掉电等故障恢复。

4.2.主从复制

(1)过程

在这里插入图片描述

  1. 写入 Binlog:主库写 binlog 日志,提交事务,并更新本地存储数据。
  2. 同步 Binlog:把 binlog 复制到所有从库上,每个从库把 binlog 写到暂存日志中。
  3. 回放 Binlog:回放 binlog,并更新存储引擎中的数据。
(2)从库数量

并非越多越好,过多消耗主库资源、受限于主库网络带宽。

(3)主从复制模型
  • 同步复制:MySQL 主库提交事务的线程要等待所有从库的复制成功响应,才返回客户端结果。性能很差;可用性很差,主库和所有从库任何一个数据库出问题,都会影响业务。
  • 异步复制(默认模型):MySQL 主库提交事务的线程并不会等待 binlog 同步到各从库,就返回客户端结果。这种模式一旦主库宕机,数据就会发生丢失。
  • 半同步复制:MySQL 5.7 版本之后增加的一种复制方式,介于两者之间,事务线程不用等待所有的从库复制成功响应,只要一部分复制成功响应回来就行。

4.3.刷盘

基于binlog cache
binlog cache→(write)→page cache→(fsync)→磁盘

sync_binlog参数:

  • 0 每次提交只write(默认)
  • 1 每次提交都write和fsync
  • N>1 没词提交都write,但积累N个事务后才fsync

5.两阶段提交

5.1.作用

事务提交后,redo logbinlog 都要持久化到磁盘,但是这两个是独立的逻辑,可能出现半成功的状态,这样就造成两份日志之间的逻辑不一致。既在宕机前,其中一个刷入磁盘,另一个没有来得及写。

5.2.过程

在这里插入图片描述

  • prepare 阶段:将 XID 到 redo log,同时将 redo log 对应的事务状态设置为 prepare,然后将 redo log 持久化到磁盘(innodb_flush_log_at_trx_commit = 1 的作用);

  • commit 阶段:把 XID 写入到 binlog,然后将 binlog 持久化到磁盘(sync_binlog = 1 的作用),接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(状态无需持久化磁盘)。

5.3.异常重启

在这里插入图片描述

在 MySQL 重启后会按顺序扫描 redo log 文件,碰到处于 prepare 状态的 redo log,就拿着 redo log 中的 XID 去 binlog 查看是否存在此 XID:

  • 如果 binlog 中没有当前内部 XA 事务的 XID,说明 redolog 完成刷盘,但是 binlog 还没有刷盘,则回滚事务。对应时刻 A 崩溃恢复的情况。
  • 如果 binlog 中当前内部 XA 事务的 XID,说明 redolog 和 binlog 都已经完成了刷盘,则提交事务。对应时刻 B 崩溃恢复的情况。

两阶段提交是以 binlog 写成功为事务提交成功的标识

5.4.存在问题

  • 磁盘 I/O 次数高:对于“双1”配置,每个事务提交都会进行两次 fsync(刷盘),一次是 redo log 刷盘,另一次是 binlog 刷盘。
  • 锁竞争激烈:「多事务」的情况下,还需要加一个锁来保证提交的原子性。

5.5.组提交

binlog组提交:当有多个事务提交的时候,会将多个 binlog 刷盘操作合并成一个,从而减少磁盘 I/O 的次数。
redo组提交:将prepare阶段的刷盘,延迟到flush阶段。

每个队列的第一个事务会成为leader。

(1)flush阶段

多个事务按进入的顺序将 binlog 从 cache 写入文件(不刷盘);
在这里插入图片描述

flsuh队列用于支持redo log的组提交,如果这一步崩溃,会回滚该组事务。

(2)sync阶段

对 binlog 文件做 fsync 操作(多个事务的 binlog 合并一次刷盘);
等待时长受到参数binlog_group_commit_sync_no_delay_countbinlog_group_commit_sync_delay影响。时间到了将binlog刷盘。
在这里插入图片描述

如果在这一步完成后数据库崩溃,由于 binlog 中已经有了事务记录,MySQL会在重启后通过 redo log 刷盘的数据继续进行事务的提交。

(3)commit阶段

调用引擎的提交事务接口,各个事务按顺序做 InnoDB commit 操作;

在这里插入图片描述

七、buffer pool的管理

有关管理空闲页、脏页、提高缓存命中率、脏页刷盘等。详情见小林。

八、其他

1.1.vanchar(n)中n的最大取值

  • 所有字段长度
  • 每个变长字段字节数列表所占用字节数(每个1或2字节)
  • NULL标识

1.2.长连接占用内存问题

  • 定期断开长连接
  • 客户端主动重置连接

1.3.回表和覆盖索引

(1)回表

如果某个查询语句使用了二级索引,但是查询的数据不是主键值,这时在二级索引找到主键值后,需要去聚簇 索引中获得数据行,这个过程就叫作「回表」。

(2)覆盖索引

当查询的数据是主键值时,因为只在二级索引就能查询到,不用再去聚簇索引查,这个过程就叫作「索引覆盖」。

2.1.MySQL单表最大值

略,自行看小林。
Total = x z − 1 × y \text{Total}=x^{z-1} \times y Total=xz1×y
其中 x x x 为非叶子节点,指向其他页的数量;
y y y 为叶子节点所能容纳的数据行数;
z z z B+树的层数。

2.2.MySQL使用"%x"一定会索引失效吗

不一定,如果只有主键+二级索引,会走全扫描二级索引树。其他情况下会失效。

2.3.count(*)和count(1)对比

(1)对比

对于InnoDB,按照性能排序:
count(*)= count(1)>count(主键字段)>count(字段)

(2)count(*)/count(1)过程

  • 优先选二级索引,但只有聚簇索引时:循环遍历聚簇索引(主键索引),将读取到的记录返回给 server 层,但是不会读取记录中的任何字段的值。不区分NULL与否。

(3)count(主键字段)过程

  • 优先选二级索引,但只有聚簇索引时:循环遍历聚簇索引,将读取到的记录返回给 server 层,然后读取记录中的 id 值,就会 id 值判断是否为 NULL,如果不为 NULL,就将 count 变量加 1。

(4)count(字段)过程

可能使用全表查询,效率很低。

2.4.为什么采用B+树

(1)相比B树

B树在非叶子节点也存储数据。

  1. I/O访问:因此,B+树的单个节点数据量更小,相同I/O下可以查询更多结点。
  2. 内存:查询B树时,中途用不到的数据也会被反复放入内存,浪费资源。
  3. 范围查询:B+树叶子节点采用双向链表连接,适合范围的顺序查找。B树无法做到。
  4. 单点查询:B树虽然单点查询略快,但速度不稳定。
  5. 插入删除:B+树可以直接从叶子节点删除,无需动非叶子结点,效率高很多,树结构变化小。插入同理。

(2)相比二叉树

当数据量比较大时,二叉树的高度会很高 log ⁡ 2 N \log_2 N log2N,而B树每层几百个,高度很浅 log ⁡ M N \log_M N logMN。有利于减少磁盘I/O操作。

(3)相比Hash

Hash很适合等值查询,但不适合范围查询。

4.1.update全局锁事故

在执行 update、delete、select … for update 等具有加锁性质的语句,一定要检查语句是否走了索引,如果是全表扫描的话,会对每一个索引加 next-key 锁,相当于把整个表锁住了。

5.1.MySQL磁盘I/O优化

  1. 设置binlog_group_commit_sync_delay(延迟时间微秒提交)和binlog_group_commit_sync_no_delay_count(延迟事务个数提交)。
  2. 设置sync_binlog为大于1的值。
  3. 设置innodb_flush_log_at_trx_commit设置为2.

5.2.update全过程

UPDATE t_user 
SET name = 'xiaolin' 
WHERE id = 1;
  1. 执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id = 1 这一行记录:

    • 如果 id=1 这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;
    • 如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。
  2. 执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:

    • 如果一样的话就不进行后续更新流程;
    • 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;
  3. 开启事务, InnoDB 层更新记录前,首先要记录相应的 undo logundo log 会写入 Buffer Pool 中的 Undo 页面,不过在内存修改该 Undo 页面后,需要记录对应的 redo log

  4. InnoDB 层开始更新记录,会先更新内存(同时标记为脏页),然后将记录写到 redo log 里面,这个时候更新就算完成了。为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。这就是 WAL 技术

  5. 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog,此时记录的 binlog 会被保存到 binlog cache,并没有刷新到硬盘上的 binlog 文件,在事务提交时才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。

  6. 事务提交,剩下的就是「两阶段提交」的事情了。

相关文章:

MySQL八股学习笔记

文章目录 一、MySQL结构1.宏观结构1.1.Server层1.2.存储引擎层 2.建立链接-连接器3.查询缓存4.解析SQL-解析器&#xff08;1&#xff09;词法分析&#xff08;2&#xff09;语法分析 5.执行SQL5.1.预处理器 prepare5.2.优化器 optimize5.3.执行器 execute&#xff08;1&#xf…...

C++ 设计模式-备忘录模式

游戏存档实现&#xff0c;包括撤销/重做、持久化存储、版本控制和内存管理 #include <iostream> #include <memory> #include <deque> #include <stack> #include <chrono> #include <fstream> #include <sstream> #include <ct…...

Jenkins 环境搭建---基于 Docker

前期准备 提前安装jdk、maven、nodeJs&#xff08;如果需要的话&#xff09; 创建 jenkins 环境目录&#xff0c;用来当做挂载卷 /data/jenkins/ 一&#xff1a;拉取 Jenkins 镜像 docker pull jenkins/jenkins:lts 二&#xff1a;设置 Jenkins挂载目录 mkdir -p ~/jen…...

【动态规划篇】:解析背包问题--动态规划塑造的算法利器

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;动态规划篇–CSDN博客 文章目录 一.01背包问题1.模板题2.例题1.分割等和子集2.目标和3.最后…...

ok113i平台——多媒体播放器适配

1. 视频播放支持 1.1 在Linux平台交叉编译ffmpeg动态库&#xff0c;详情查看《ok113i平台——交叉编译音视频动态库》 提取如下动态库&#xff1a; libavcodec.so.58.134.100 libavdevice.so.58.13.100 libavfilter.so.7.110.100 libavformat.so.58.76.100 libavutil.so.56.…...

【保姆级教程】DeepSeek R1+RAG,基于开源三件套10分钟构建本地AI知识库

一、总体方案 目前在使用 DeepSeek 在线环境时&#xff0c;页面经常显示“服务器繁忙&#xff0c;请稍后再试”&#xff0c;以 DeepSeek R1 现在的火爆程度&#xff0c;这个状况可能还会持续一段时间&#xff0c;所以这里给大家提供了 DeepSeek R1 RAG 的本地部署方案。最后实现…...

线程与进程的深入解析及 Linux 线程编程

在操作系统中&#xff0c;进程和线程是进行并发执行的两种基本单位。理解它们的区别和各自的特点&#xff0c;能够帮助开发者更好地进行多任务编程&#xff0c;提高程序的并发性能。本文将探讨进程和线程的基础概念&#xff0c;及其在 Linux 系统中的实现方式&#xff0c;并介绍…...

微信问题总结(onpageshow ,popstate事件)

此坑描述 订单详情某按钮点击&#xff0c;通过window.location.href跳转到&#xff08;外部&#xff09;第三方链接后&#xff0c;回退后&#xff0c;在ios中生命周期和路由导航钩子都失效了&#xff0c;无法触发。 在安卓中无视此坑&#xff0c; 回退没有问题 解决 原因&am…...

自己安装一台DeepSeek的服务器

找一台还可以的Linux服务器&#xff0c;登录后执行&#xff1a; curl -fsSL https://ollama.com/install.sh | sh 等待安装完成&#xff1a; 执行命令&#xff0c;根据服务器能力安装不同版本的AI模型&#xff1a; ollama run llama3.2 下一步就开始对话吧&#xff1a; llam…...

面阵工业相机提高餐饮业生产效率

餐饮行业是一个快节奏、高要求的领域&#xff0c;该领域对生产过程中每一个阶段的效率和准确性都有很高的要求。在食品加工、包装、质量控制和库存管理等不同生产阶段实现生产效率的优化是取得成功的关键步骤。面阵工业相机能够一次性捕捉对象的二维区域图像&#xff0c;并支持…...

Java 中 HTTP 协议版本使用情况剖析

Java 中 HTTP 协议版本使用情况剖析 一、HTTP/1.1 与 HTTP/2 概述 (一)HTTP/1.1 HTTP/1.1 是广泛应用且成熟的 HTTP 协议版本,它在互联网发展历程中扮演了重要角色。其特点主要包括: 连接方式:默认采用短连接,即每次请求都要建立新的 TCP 连接,请求完成后断开。不过也…...

计算机网络之物理层——基于《计算机网络》谢希仁第八版

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…...

DeepSeek 助力 Vue 开发:打造丝滑的缩略图列表(Thumbnail List)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

day56 第十一章:图论part06

108.冗余连接 注意init初始化 改进&#xff1a; 其实只有一条边冗余&#xff0c;改为&#xff0c;如果两条边在同一个集合里&#xff0c;就输出&#xff0c;不然加入。 #include <iostream> #include <vector> using namespace std;int n 1005; vector<int>…...

conda 配置源

无论是Anaconda vs Miniconda vs Miniforge 中的哪个&#xff0c;只要使用conda就涉及源&#xff0c;换源的目的是为了加速包的获取 修改配置文件 通过修改用户目录下的 .condarc 文件来使用 不同系统下的 .condarc 目录如下&#xff1a; Linux: ${HOME}/.condarcmacOS: ${…...

LangChain大模型应用开发:多模态输入与自定义输出

介绍 大家好&#xff0c;博主又来给大家分享知识了。今天给大家分享的内容是使用LangChain进行大模型应用开发中的多模态输入与自定义输出。 LangChain中的多模态数据输入是指将多种不同形式的数据作为输入提供给基于语言模型的应用程序或系统&#xff0c;以丰富交互内容和提…...

HarmonyOS 开发套件 介绍 ——上篇

HarmonyOS 开发套件 介绍 ——上篇 在当今科技飞速发展的时代&#xff0c;操作系统作为智能设备的核心&#xff0c;其重要性不言而喻。而HarmonyOS&#xff0c;作为华为推出的全新操作系统&#xff0c;正以其独特的魅力和强大的功能&#xff0c;吸引着越来越多的开发者和用户的…...

【Unity Shader编程】之图元装配与光栅化

执行方式&#xff1a;自动完成 图元装配自动化流程 顶点坐标存入装配区 → 按绘制模式连接顶点 → 生成完整几何图元 示例&#xff1a;gl.drawArrays(gl.TRIANGLES, 0, 3)自动生成三角形 会自动自动裁剪超出屏幕范围&#xff08;NDC空间外&#xff09;的三角形&#xff0c;仅保…...

小游戏-记忆卡牌

1、游戏开始4张卡牌&#xff0c;每次过关后新增两张&#xff0c;总共64张卡&#xff0c;可以修改数组EMOJIS&#xff0c;添加表情&#xff0c;增加卡牌数量 2、新建txt文件&#xff0c;将代码粘贴进去&#xff0c;保存后&#xff0c;将txt修改后缀名为html的格式 <!DOCTYPE…...

数据结构——二叉树经典习题讲解

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 大家好&#xff0c;我们今天来学习java数据结构的二叉树 递归很重要的一些注意事项&#xff1a; 1&#xff1a;递归你能不能掌握在于&#xff1…...

centos 9 时间同步服务

在 CentOS 9 中&#xff0c;默认的时间同步服务是 chrony&#xff0c;而不是传统的 ntpd。 因此&#xff0c;建议使用 chrony 来配置和管理时间同步。 以下是使用 chrony 配置 NTP 服务的步骤&#xff1a; 1. 安装 chrony 首先&#xff0c;确保系统已安装 chrony。 在 CentOS…...

视觉应用工程师(面试)

视觉应用工程师&#xff08;面试&#xff09; 1.自我介绍、会的技能、项目 2.相机和机械手调试过程 检查硬件&#xff0c;看软件驱动是否链接&#xff0c;调节相机和镜头保证能够识别这个物料&#xff0c;看接口和通讯是否正常&#xff0c;如&#xff1a;波特率&#xff0c;数…...

macos sequoia 禁用 ctrl+enter 打开鼠标右键菜单功能

macos sequoia默认ctrlenter会打开鼠标右键菜单&#xff0c;使得很多软件有冲突。关闭方法&#xff1a; end...

【后端基础】布隆过滤器原理

文章目录 一、Bloom Filter&#xff08;布隆过滤器&#xff09;概述1. Bloom Filter 的特点2. Bloom Filter 的工作原理 二、示例1. 添加与查询2. 假阳性 三、Bloom Filter 的操作1、假阳性概率2、空间效率3、哈希函数的选择 四、应用 Bloom Filter 是一种非常高效的概率型数据…...

cs*n 网页内容转为html 加入 onenote

csdn上有好用的内容&#xff0c;我们怎么将它们加到 onenote 里吃灰呢。 一、创建 新html create_html.py import sysdef create_html_file(filename):# 检查是否提供了文件名if not filename:print("请提供HTML文件名")return# 创建HTML内容html_content f"…...

输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路

详细前端代码写于上一篇&#xff1a;输入搜索、分组展示选项、下拉选取&#xff0c;el-select 实现&#xff1a;即输入关键字检索&#xff0c;返回分组选项&#xff0c;选取跳转到相应内容页 —— VUE项目-全局模糊检索 【效果图】&#xff1a;分组展示选项 【去界面操作体验】…...

蓝桥杯 Java B 组之岛屿数量、二叉树路径和(区分DFS与回溯)

Day 3&#xff1a;岛屿数量、二叉树路径和&#xff08;区分DFS与回溯&#xff09; &#x1f4d6; 一、深度优先搜索&#xff08;DFS&#xff09;简介 深度优先搜索&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一种用于遍历或搜索树或图的算法。它会沿着树的分…...

【论文阅读】SAM-CP:将SAM与组合提示结合起来的多功能分割

导言 近年来&#xff0c;视觉基础模型的快速发展推动了多模态理解的进步&#xff0c;尤其是在图像分割任务中。例如&#xff0c;Segment Anything模型&#xff08;SAM&#xff09;在图像Mask分割上表现出色&#xff0c;但在语义及实例分割方面仍存在局限。本文提出的SAM-CP&am…...

JUC并发—9.并发安全集合四

大纲 1.并发安全的数组列表CopyOnWriteArrayList 2.并发安全的链表队列ConcurrentLinkedQueue 3.并发编程中的阻塞队列概述 4.JUC的各种阻塞队列介绍 5.LinkedBlockingQueue的具体实现原理 6.基于两个队列实现的集群同步机制 4.JUC的各种阻塞队列介绍 (1)基于数组的阻塞…...

爱普生 SG-8101CE 可编程晶振在笔记本电脑的应用

在笔记本电脑的精密架构中&#xff0c;每一个微小的元件都如同精密仪器中的齿轮&#xff0c;虽小却对整体性能起着关键作用。如今的笔记本电脑早已不再局限于简单的办公用途&#xff0c;其功能愈发丰富多样。从日常轻松的文字处理、网页浏览&#xff0c;到专业领域中对图形处理…...

k8s网络插件详解(flannel)

1、介绍 Flannel 是一个轻量级、易于配置的网络插件&#xff0c;旨在简化 Kubernetes 集群中 Pod 网络的管理。Flannel 的核心功能是提供一个虚拟的网络&#xff0c;允许每个 Pod 获取一个独立的 IP 地址&#xff0c;并实现不同节点间的 Pod 之间的通信 2、网络模式 vxlan&am…...

基于flask+vue框架的的医院预约挂号系统i1616(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能:用户,医生,科室信息,就诊信息,医院概况,挂号信息,诊断信息,取消挂号 开题报告内容 基于FlaskVue框架的医院预约挂号系统开题报告 一、研究背景与意义 随着医疗技术的不断进步和人们健康意识的日益增强&#xff0c;医院就诊量逐年增加。传统的现场…...

JUC并发—8.并发安全集合一

大纲 1.JDK 1.7的HashMap的死循环与数据丢失 2.ConcurrentHashMap的并发安全 3.ConcurrentHashMap的设计介绍 4.ConcurrentHashMap的put操作流程 5.ConcurrentHashMap的Node数组初始化 6.ConcurrentHashMap对Hash冲突的处理 7.ConcurrentHashMap的并发扩容机制 8.Concu…...

Linux 内核网络设备驱动编程:私有协议支持

一、struct net_device的通用性与私有协议的使用 struct net_device是Linux内核中用于描述网络设备的核心数据结构,它不仅限于TCP/IP协议,还可以用于支持各种类型的网络协议,包括私有协议。其原因如下: 协议无关性:struct net_device的设计是通用的,它本身并不依赖于任何…...

机器学习的数学基础(三)——概率与信息论

目录 1. 随机变量2. 概率分布2.1 离散型变量和概率质量函数2.2 连续型变量和概率密度函数 3. 边缘概率4. 条件概率5. 条件概率的链式法则6. 独立性和条件独立性7. 期望、方差和协方差7.1 期望7.2 方差7.3 协方差 8. 常用概率分布8.1 均匀分布 U ( a , b ) U(a, b) U(a,b)8.2 Be…...

使用Docker Desktop部署GitLab

1. 环境准备 确保Windows 10/11系统支持虚拟化技术&#xff08;需在BIOS中开启Intel VT-x/AMD-V&#xff09;内存建议≥8GB&#xff0c;存储空间≥100GB 2. 安装Docker Desktop 访问Docker官网下载安装包安装时勾选"Use WSL 2 instead of Hyper-V"&#xff08;推荐…...

推理模型时代:大语言模型如何从对话走向深度思考?

一、对话模型和推理模型的区别概述 对话模型是专门用于问答交互的语言模型,符合人类的聊天方式,返回的内容可能仅仅只是一个简短的答案,一般模型名称后面会带有「chat」字样。 推理模型是比较新的产物,没有明确的定义,一般是指输出过程中带有<think>和</think&…...

GESP2024年3月认证C++七级( 第三部分编程题(1)交流问题)

参考程序&#xff1a; #include <iostream> #include <vector> #include <unordered_map> using namespace std;// 深度优先搜索&#xff0c;给每个节点染色&#xff0c;交替染色以模拟两校同学的划分 void dfs(vector<vector<int>>& graph…...

DeepSeek:AI商业化的新引擎与未来蓝图

摘要 在人工智能迅猛发展的浪潮中&#xff0c;DeepSeek以其卓越的技术实力和高超的商业化能力崭露头角。作为一款现象级AI产品&#xff0c;它不仅在算法性能上位居行业前列&#xff0c;还通过灵活的定制解决方案渗透到金融、医疗、零售等多个领域。DeepSeek以创新的商业模式和场…...

2025年度福建省职业院校技能大赛中职组“网络建设与运维”赛项规程模块三

模块三&#xff1a;服务搭建与运维 任务描述&#xff1a; 随着信息技术的快速发展&#xff0c;集团计划把部分业务由原有的 X86 服 务器上迁移到ARM 架构服务器上&#xff0c;同时根据目前的部分业务需求进行 了部分调整和优化。 一、X86 架构计算机操作系统安装与管理 1&…...

Python----数据结构(队列,顺序队列,链式队列,双端队列)

一、队列 1.1、概念 队列(Queue)&#xff1a;也是一种基本的数据结构&#xff0c;在队列中的插入和删除都遵循先进先出&#xff08;First in First out&#xff0c;FIFO&#xff09;的原则。元素可以在任何时刻从队尾插入&#xff0c;但是只有在队列最前面 的元素才能被取出或…...

【自学笔记】Spring Boot框架技术基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Spring Boot框架技术基础知识点总览一、Spring Boot简介1.1 什么是Spring Boot&#xff1f;1.2 Spring Boot的主要特性 二、Spring Boot快速入门2.1 搭建Spring Boo…...

神经网络剪枝技术的重大突破:sGLP-IB与sTLP-IB

神经网络剪枝技术的重大突破:sGLP-IB与sTLP-IB 在人工智能飞速发展的今天,深度学习技术已经成为推动计算机视觉、自然语言处理等领域的核心力量。然而,随着模型规模的不断膨胀,如何在有限的计算资源和存储条件下高效部署这些复杂的神经网络模型,成为了研究者们亟待解决的…...

Django-Vue 学习-VUE

主组件中有多个Vue组件 是指在Vue.js框架中&#xff0c;主组件是一个父组件&#xff0c;它包含了多个子组件&#xff08;Vue组件&#xff09;。这种组件嵌套的方式可以用于构建复杂的前端应用程序&#xff0c;通过拆分功能和视图&#xff0c;使代码更加模块化、可复用和易于维…...

【Gin】2:快速上手Gin框架(模版、cookie、session)

本文目录 一、模版渲染二、自定义模版函数三、cookie四、Session五、cookie、session区别六、会话攻击 一、模版渲染 在 Gin 框架中&#xff0c;模板主要用于动态生成 HTML 页面&#xff0c;结合 Go 语言的模板引擎功能&#xff0c;实现数据与视图的分离。 模板渲染是一种动态…...

Linux修改主机名称

hostnamectl set-hostname 主机名称 exit 退出登录重新进入即可...

亲测Windows部署Ollama+WebUI可视化

一. Ollama下载 登录Ollama官网(Ollama)点击Download进行下载 如果下载很慢可用以下地址下载&#xff1a; https://github.com/ollama/ollama/releases/download/v0.5.7/OllamaSetup.exe 在DeepSeek官网上&#xff0c;你可以直接点击【model】 到达这个界面之后&#xff0c;…...

Java四大框架深度剖析:MyBatis、Spring、SpringMVC与SpringBoot

目录 前言&#xff1a; 一、MyBatis框架 1. 概述 2. 核心特性 3. 应用场景 4. 示例代码 二、Spring框架 1. 概述 2. 核心模块 3. 应用场景 4. 示例代码 三、SpringMVC框架 1. 概述 2. 核心特性 3. 应用场景 4. 示例代码 四、SpringBoot框架 1. 概述 2. 核心…...

ubuntu部署小笔记-采坑

ubuntu部署小笔记 搭建前端控制端后端前端nginx反向代理使用ubuntu部署nextjs项目问题一 如何访问端口号配置后台运行该进程pm2 问题二 包体过大生产环境下所需文件 问题三 部署在vercel时出现的问题需要魔法访问后端api时&#xff0c;必须使用https协议电脑端访问正常&#xf…...

23. AI-大语言模型-DeepSeek简介

文章目录 前言一、DeepSeek是什么1. 简介2. 产品版本1. 类型2. 版本3. 参数规模与模型能力 3. 特征4. 三种访问方式1. 网页端和APP2. DeepSeek API 二、DeepSeek可以做什么1. 应用场景2. 文本生成1. 文本创作2. 摘要与改写3. 结构化生成 3. 自然语言理解与分析1. 语义分析2. 文…...