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

《高性能MySQL》读书笔记(上)

目录

MySQL的架构

MySQL中的锁

MySQL中的事务

事务特性

隔离级别

事务日志

多版本并发控制MVCC

影响MySQL性能的物理因素

InnoDB缓冲池

MySQL常用的数据类型以及优化

字符串类型  

日期和时间类型

数据标识符


MySQL的架构

默认情况下,每个客户端连接都会在服务器进程中拥有一个线程,该连接的查询只会在这个单独的线程中执行,该线程驻留在一个内核或者是CPU上,服务器维护了一个缓存区,用来存放已经就绪的线程,因此不需要为每个新的连接创建或者是销毁线程。

MySQL中的锁

MySQL的锁的粒度:

  • 行锁:并发大,系统开销大(比如:内核态和用户态之间的频繁转换)

  • 表锁:并发小,系统开销小。

MySQL的读写锁:

  • 读锁:读锁也称为共享锁:并发访问共享资源的时候不进行阻塞,MySQL中的查询语句是读锁,在查询语句后面添加 for share /for update 可以为查询语句加写锁。

  • 写锁:也称为排他锁,并发访问共享资源时会出现阻塞,MySQL中增,删,改语句都是自带写锁的。

注意:增删改是隐式上锁,查询语句要上锁需要显式上锁。

死锁:

死锁是指两个或者是多个事务相互持有和请求相同资源上的锁,产生了循环依赖。

INnoDB目前处理死锁的方式是将持有最少行级排他锁的事务进行回滚。实际上,InnoDB存储引擎会帮我们先检测锁的情况,如果检测到死锁,那么会立刻返回一个错误的信息。

一旦发生死锁,如果不回滚其中的一个事务,就无法打破死锁。

MySQL中的事务

事务特性

MySQL事务:(MySQL中只有INnoDB引擎才支持事务)

事务就是一组SQL语句,作为一个工作单位以原子方式进行处理,作为事务的一组语句,要么全部执行成功,要么全部执行失败。

事务的四大特性:

  • 原子性:一个事务必须被视为不可分割的工作单元,整个事务的所有操作要么全部提交成功,要么全部失败回滚。

  • 一致性:可以简单的理解为守恒,数据库总是从一个一致性状态转换到下一个一致的状态。比如两个账户进行转账,那么转账前后这两个账户里面的总钱数都是一致的。

  • 隔离性:隔离性最常见的一种情况就是,一个事务所做的修改在最终提交以前,对其他事务都是不可见的。

  • 持久性:事务一旦成功提交,那么事务所做的修改就会被永久的保存在数据库中。

隔离级别

MySQL默认的隔离级别是可重复读。

  • 读未提交(READUNCOMMITTED):在事务中可以查看到其他事务中还没有提交的修改。这个级别的隔离一般很少使用。

  • 读已提交(READ COMMITTED):一个事务可以看到其他事务在它开始之后提交的修改,在该事务提交之前,其所做的任何修改对其他事务都是不可见的。(这个级别仍然会出现不可重复读,不可重复读:同一事务中两次执行相同SQL语句,可能会看到不同的数据结果

  • 可重复读(REPEATABLE READ):解决了读已提交隔离级别的不可重复读问题,保证了在同一个事务中多次读取相同行数据结果是一样的。但是不能解决幻读问题。(幻读:指的是当某个事务在读取范围内的记录的时候,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取某个范围内的记录是,产生了幻行。)

  • 可串行化(SERIALIZABLE):前制事务按序执行,相当于加锁阻塞,所以可能会导致大量超时和锁竞争的相关问题出现。在实际生产环境中也很少用到这个隔离级别。

隔离级别是否出现脏读是否出现不可重复读是否出现幻读
读未提交
读已提交
可重复读
可串行化

事务日志

事务日志可以提高事务的效率,存储引擎只需要更改内存中的数据副本,而不是每次修改磁盘中的表,然后再把更改的记录写入事务中,事务日志会被持久化存在磁盘上。

因为事务日志采用的是追加写的操作,是在硬盘中一小块区域内的顺序IO,而不是随机IO,所以写入事务日志是一种相对比较快的操作,最后会有一个后台进程在某个时间去更新磁盘中的表。(操作日志顺序写入磁盘一次,然后更新磁盘中的表一次,会操作两次磁盘)

多版本并发控制MVCC

多版本并发控制(MVCC):可以理解为行级锁的一种变种,但是mvcc在很多情况下避免了加锁操作,因此开销更低。

简要理解mvcc的思想和一些设计:MVCC的工作原理是使用数据在某个时间节点的快照来实现的;

意味着,无论事务运行多长时间,都可以看到数据的一致视图;也意味着不同事务可以在同一时间看到同一张表的不同数据。

MySQL就是通过MVCC解决了幻读的问题。

每个存储引擎实现MVCC的方式都是不同的,InnoDB通过为每个事务在启动时分配一个【事务ID】来实现MVCC,该ID在事务首次读取任何数据的时候分配(只读事务ID永远为0),后面每次操作数据都会影响这个事务ID的值,所有在下次来读取的时候就可以通过循环来比较这个事务ID,从而返回对应的视图(视图的存在类似一个链表,保存不同时间的数据)。

注意:MVCC只适用于【重复读】和【读已提交】这两个事务的隔离级别。

InnoDB默认为可重复读隔离级别,并且通过间隙锁策略来防止在这个隔离级别上的幻读:InnoDB不只锁定在查询中涉及到的行,还会对索引结构中的间隙进行锁定,以防止幻行被插入。

影响MySQL性能的物理因素

MySQL服务器的性能受限于整个系统最薄弱的环节,承载MySQL服务器的操作系统和硬件是最主要的限制因素。最常见的几个就是:磁盘空间大小,可用内存,CPU,网络,以及磁盘的材质(涉及到IO,所以能用固态硬盘那就尽量使用固态硬盘)。

为MySQL服务器配置大内存,并不是为了在内存中保存大量的数据,而是为了减少磁盘IO次数,磁盘IO访问数据比直接访问内存中的数据要慢几个数量级。

MySQL的读取,写入,缓存:如果有足够大的内存,是可以大幅度的减少磁盘IO的次数,因为如果数据都可以装到内存的话,那么服务器一旦完成数据的缓存预热,那么每次读取数据都是一次的缓存命中,在这种情况下,仍然会从内存中进行逻辑的读取,但是不会从磁盘中进行物理的读取数据。而且,写入也是可以在内存中执行的,但是数据最后必然是会被写入磁盘进行持久化的,也就是说,缓存可以延迟写操作,但缓存不能像消除读操作那样消除写操作的磁盘IO。

事实上,缓存的存在除了运行延迟写操作外,还可以允许写操作与其他方式组合起来一起使用。

  • 多次写操作,一次刷新(这种设计不仅可以减少IO次数,还可以把写入磁盘的随机IO变成顺序IO)

    • 一个数据片段可以在内存中被多次更改,而无须每一次都将新值写入磁盘。当数据最终被刷新到磁盘时,自上次物理写入以来发生的所有修改都将被持久化。

  • IO合并

    • 许多不同的数据片段可以在内存中被修改,这些修改可以被收集在一起,因此物理写可以作为单个磁盘操作来执行。

写操作可以从缓存中收益,可以将随机IO转变成顺序IO。

内存与交换:

当操作系统因为没有足够的内存来容纳虚拟内存时而将一些虚拟内存写入磁盘时,就会发生交换。写操作是缩短磁盘的整体寿命的,当然我们也可以关闭交换,这样就可以完全消除交换带来的负面影响,但是需要承担因为内存耗尽导致进程被终止的情况。

InnoDB缓冲池

InnoDB缓冲池不仅缓存索引,还缓存行数据,自适应哈希索引,更改缓冲区,锁和其他内部结构等,InnoDB还是用缓冲池来实现延迟写操作,从而可以将多个写操作合并在一起并按顺序执行。InnoDB严重依赖缓冲池,所以应该确保为其分配足够的内存。

当然,大型的缓冲区也会带来一些其他问题,比如更长的关闭时间和预热时间,而且如果缓冲池中存在许多脏页(被修改过的数据,还没被同步到磁盘中,就是说内存中的数据与磁盘中的数据不一致),那么InnoDB可能需要很长时间才能关闭,因为它会在关闭的时候将脏页写到数据文件中。

InnoDB默认使用同一个后台线程来刷新脏页,以及合并写操作并按顺序执行以提高效率,当脏页的百分比超过设置的阈值时,InnoDB会尽可能快的刷新页面,以降低脏页的数量。

事务日志:InnoDB使用日志来降低提交事务的成本,它不会在每个事务提交时将缓冲池刷新到磁盘,而是将事务记录到日志中(使用追加的方式来记录这个日志,避免了随机IO),使用这个事务日志,InnoDB可以将随机磁盘转换为顺序IO。InnoDB最终必须还是要将更改的数据写入数据文件,因为日志的大小是固定的,采取的是循环写入的方式:当到达日志末尾的时候,它会环绕到日志的开头,如果日志记录中包含更改且尚未应用于数据文件的操作,则会到值无法覆盖日志记录,因为这将删除以提交事务的唯一永久记录。

事务日志是使用连续的磁盘空间来进行记录的,InnoDB引擎中,在事务提交的时候,必须先将该事务的所有事务日志写入到磁盘上的redoLog File和undoLog File 中进行持久化。

日志缓冲区:InnoDB修改数据时会将修改记录写入到日志缓冲区,并将其保存在内存中,当缓冲区满了,事务提交时,或者每秒一次(这三个条件以先满足为准),InnoDB会将缓冲区刷新到磁盘上的日志文件中。与InnoDB的普通数据相比,日志的条目非常紧凑。

InnoDB如何刷新日志缓冲区:

使用互斥锁锁定缓冲区,将其刷新到所需的位置,如何将剩余的条目移动到缓冲区的前面,当释放互斥锁时,可能会有多个事务准备刷新其日志条目,InnoDB使用了一组提交特性,可以在单次IO操作将一组日志全部提交。日志缓冲区必须被刷新到持久存储中,以确保提交的事务完全的持久。

InnoDB_flush_log_at_trx_commit可以用来控制日志缓冲区的刷新位置和刷新频率

  • 0:每秒定时将日志缓冲区写入日志文件,并且刷新日志文件,但在事务提交时不做任何操作。

  • 1:每次事务提交时,将日志缓冲区写入日志文件,并将其刷新到持久存储中,这是默认的设置(也是最安全的设置);

  • 2:每次事务提交时都将日志缓冲区写入日志文件,但不执行刷新。InnoDB按计划每秒刷新一次。与0设置最主要的区别是,如果只是MySQL进程崩溃,设置2不会丢失任何事务,但是,如果整个服务器崩溃或者是断电,仍然可能丢失事务。

注意:在大多数操作系统中,将缓冲区写入日志只是将数据从InnoDB的内存缓冲区移动到操作系统的缓存中,依然还是在内存中,它实际上不会将数据写入到持久存储,因此,如果发生崩溃或者是断电,设置为0和2通常会导致最多一秒的数据丢失,因为数据可能只存在操作系统的缓存中。

MySQL常用的数据类型以及优化

字符串类型  

可变字符串varchar:

  • varchar用于存储可变长度的字符串,比固定长度的类型更节省空间,因为它仅使用必要的空间。

    varchar需要额外使用1或者是2个字节来记录字符串的长度,如果列的最大长度小于或者是等于255字节,则只使用一个字节表示,否则使用两个字节进行表示。比如varchar(10)需要11个字节的存储空间,而varchar(1000)需要1002个字节的存储空间。

    注意:由于行是可变长度,在更新数据的时候可能会增长,这会导致额外的工作,如果行的增长使原来位置无法容纳跟多内容,则具体的处理行为取决于使用的存储引擎。例如,innodb可能会需要分割页面来容纳行

下面这些情况使用varchar是比较好的:

  • 字符串的最大长度远大于平均长度;

  • 列的更新很少,可以避免内存碎片的产生。

固定字符串char:

  • char是固定的长度,MySQL总是为定义的字符串长度分配足够的空间,当存储char值时,MySQL会删除所有尾随的空格;

char适用于存储非常短的字符串,或者是适用于所有值的长度几乎相同的情况下。固定长度不容易产生内存碎片。

日期和时间类型

DATETIME:这种类型可以保存大范围的数值,从1000年到9999年,精度为1微秒。它以YYYYMMDDHHMMSS格式存储压缩压缩成整数的日期和时间,且与时区无关。但是需要8个字节进行存储。

TIMESTAMP(时间戳):存储自1970年1月1日格林尼治标准时间午夜以来经过的秒数,只需要4个字节就可,所以范围要比datatime要小得多,只能表示1970年到2038年1月19日,时间戳的时间依赖于时区

数据标识符

数据标识符:一般来说,标识符是数据行的唯一标识。比如我们最常见的ID就是最常见的标识符。标识符可能是主键中的部分或者是全部。

为标识符选择好数据类型后,要确保在所有相关的表中使用的是相同的数据类型,否则在进行多表联查的时候就可能会出问题(标识符应该与联接表中的对应列的数据类型保持一致)。

  • 整数类型:整数通常是标识符的最佳选择,因为他们的速度快,并且可以自动递增。AUTO_INCREMENT是一个列属性,可以为新的行自动的生成一个整数类型的值。但是这种类型的标识符也有缺点:整数类型可能存在整数意外耗尽的情况,从而导致服务器停机,所以如果选择了整数类型的数据作位标识符,那么应该确保选择合适预期数据增长的整数大小。

  • 字符串类型:如果可能,应该尽可能的避免使用字符串类型作为标识符的数据类型,因为它们非常消耗空间,并且通常比整数类型慢,特别是在有索引的情况下。

另外,对于完全随机的字符串要特别小心,如MD5(),SHA1()或者是UUID()生成的字符串,这些函数生成的新值会任意分布在很大的空间内,这会减慢insert和某些类型的select查询的速度

  • 因为插入的值会写到索引的随机位置,所以会使得INSERT查询变慢,这会导致页分裂,磁盘随机访问,以及对聚簇存储引擎产生聚簇索引碎片。

  • select查询也会变慢,因为逻辑上相邻的行(指的是内存中的数据)会广泛分布在磁盘和内存中。

  • 对于所有类型的查询,随机值都会导致缓存的性能低下,因为它们会破坏引用的局部性,而这正是缓存的工作原理

MySQL会对null进行索引,但是oracle不会。

相关文章:

《高性能MySQL》读书笔记(上)

目录 MySQL的架构 MySQL中的锁 MySQL中的事务 事务特性 隔离级别 事务日志 多版本并发控制MVCC 影响MySQL性能的物理因素 InnoDB缓冲池 MySQL常用的数据类型以及优化 字符串类型 日期和时间类型 数据标识符 MySQL的架构 默认情况下,每个客户端连接都…...

05-代理模式

代理模式 代理模式使用代理对象来代替真实对象的访问,在不修改原有对象的前提下,提供额外的操作,扩展目标对象的功能。代理模式分为静态代理和动态代理。 静态代理 手动为目标对象中的方法进行增强,通过实现相同接口重写方法进…...

RocketMQ源码分析之消费队列、Index索引文件存储结构与存储机制-上篇

RocketMQ 存储基础回顾: 源码分析RocketMQ之CommitLog消息存储机制 本文主要从源码的角度分析 Rocketmq 消费队列 ConsumeQueue 物理文件的构建与存储结构,同时分析 RocketMQ 索引文件IndexFile 文件的存储原理、存储格式以及检索方式。RocketMQ 的存储…...

基于Java的浏览器的设计与实现毕业设计

技术:Java等摘要:当今世界是一个以计算机网络为核心的信息时代,互联网为人们快速获取、发布和传递信息提供了便捷,而浏览器作为互联网上查找信息的重要工具,给人们提供了巨大而又宝贵的信息财富,受到了大家…...

手把手教你使用vite打包自己的js代码包并推送到npm

准备 要有npm账号,没有的铁子去npm官网注册一个,又不要钱。 使用vite创建项目 一行代码搞定 npm create vite viet-demo框架选择Others 模板选择library 选择ts 这样项目就创建完了 这个项目默认有一个函数,用来记录按钮的点击次数并…...

Tomcat源码分析-关于tomcat热加载的一些思考

在前面的文章中,我们分析了 tomcat 类加载器的相关源码,也了解了 tomcat 支持类的热加载,意味着 tomcat 要涉及类的重复卸装/装载过程,这个过程是很敏感的,一旦处理不当,可能会引起内存泄露 卸载类 我们知…...

DataWhale 大数据处理技术组队学习task4

五、分布式并行编程模型MapReduce 1. 概述 1.1 分布式并行编程 背景:摩尔定律已经开始逐渐失效,提升数据处理计算能力刻不容缓。传统的程序开发与分布式并行编程 传统的程序开发:以单指令、单数据流的方式顺序执行,虽然这种方式…...

Oracle 12C以上统计信息收集CDB、PDB执行时间不一致问题

文章目录前言一、统计信息窗口期调查二、时区调查三、查询alert记录四、why Database Statistic Collection Job is running two times inside a Maintenance Window?五、Default Scheduler Timezone Value In PDB$SEED Different Than CDB六、总结前言 在实际工作中发现一个…...

用Python获取弹幕的两种方式(一种简单但量少,另一量大管饱)

前言 弹幕可以给观众一种“实时互动”的错觉,虽然不同弹幕的发送时间有所区别,但是其只会在视频中特定的一个时间点出现,因此在相同时刻发送的弹幕基本上也具有相同的主题,在参与评论时就会有与其他观众同时评论的错觉。 在国内…...

算法训练营 day55 动态规划 买卖股票问题系列3

算法训练营 day55 动态规划 买卖股票问题系列3 最佳买卖股票时机含冷冻期 309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode) 给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下…...

电商共享购模式,消费增值返利,app开发

在当今以市场需求为主导的数字经济时代,消费者需求呈现出精细化管理和多元化的特性,目标市场日渐完善,另外在大数据技术迅速进步和运用的驱动下,总体行业的发展节奏感也在不断加速。因而,企业需要建立一套灵活多变的经…...

机房信息牌系统

产品特色: 无线低功耗安装简单,快速布置易于维护墨水屏显示,清晰,更环保信息后台推送,远程管理多模版样式随意制作多尺寸:4.2寸,7.5寸,10.2寸4.2寸7.5寸10.2寸标签特性:…...

金测评 手感更细腻的游戏手柄,双模加持兼容更出色,雷柏V600S上手

很多朋友周末都喜欢玩玩游戏放松一下,在家玩游戏的时候,PC是大家常用的平台,当然了,玩游戏的时候用键鼠的话,手感难免差点意思,还是要手柄才能获得更好的体验。我现在用的是雷柏V600S,这是一款支…...

Windows10 下测试 Intel SGX 功能

文章目录参考文献系统要求一、安装Open Enclave SDK 环境(一)什么是Open Enclave SDK(二)启动SGX功能方法一: BIOS启动方法二:软件方式启动(三)安装必要环境(1&#xff0…...

Tina_Linux_功耗管理_开发指南

Tina Linux 功耗管理开发指南 1 概述 1.1 编写目的 简要介绍tina 平台功耗管理机制,为关注功耗的开发者,维护者和测试者提供使用和配置参考。 1.2 适用范围 表1-1: 适用产品列表产品名称内核版本休眠类型参与功耗管理的协处理器R328Linux-4.9NormalS…...

golang编译dll失败问题解决

执行go build -buildmodec-shared -o exportgo.dll exportgo.go报类似如下错误/usr/lib/gcc/x86_64-pc-msys/9.1.0/../../../../x86_64-pc-msys/bin/ld: 找不到 -lmingwex/usr/lib/gcc/x86_64-pc-msys/9.1.0/../../../../x86_64-pc-msys/bin/ld: 找不到 -lmingw32安装tdm gcc m…...

Convolutional Neural Networks for Sentence Classification

摘要 We report on a series of experiments with convolutional neural networks (CNN) trained on top of pre-trained word vectors for sentence-level classification tasks. We show that a simple CNN with little hyperparameter tuning and static vectors achieves e…...

基于SpringBoot的共享汽车管理系统

文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…...

TCP三次握手

参考:4.1 TCP 三次握手与四次挥手面试题 | 小林coding TCP 头格式 我们先来看看 TCP 头的格式,标注颜色的表示与本文关联比较大的字段,其他字段不做详细阐述。 序列号:在建立连接时由计算机生成的随机数作为其初始值&#xff0c…...

未来土地利用模拟FLUS模型

未来土地利用模拟(FutureLand-Use Simulation, FLUS)模型1 模型简介1.1 基于ANN 的适宜性概率计算1.2 基于自适应惯性机制的元胞自动机1.3 模拟精度评价参考流域 径流变化是 自然因素和 人为因素共同作用的结果,其中人为因素最为直接的方式就…...

压力传感器MPX5700D/MPX5700GP/MPX5700AP产品概述、特征

MPX5700系列压阻式换能器是最先进的单片硅压力传感器,可广泛用于各种应用,特别是采用A/D输入微控制器或微处理器的应用。这一获得专利的单元件传感器集合了高级微加工技术、薄膜金属化、双极工艺,能够提供精确的、与所施加压力成正比的高电平…...

taobao.trades.sold.query( 根据收件人信息查询交易单号 )

¥开放平台免费API必须用户授权聚石塔内调用 根据收件人信息查询交易单号。 公共参数 请求地址: HTTP地址 公共请求参数: 公共响应参数: 请求参数 请求示例 TaobaoClient client new DefaultTaobaoClient(url, appkey, secret); TradesSoldQueryRequest req new…...

【JavaWeb】JSON、AJAX(305-317)

305.JSON-什么是JSON JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON 采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C, C#, Java, JavaScript, Perl,…...

AI入场,搜索这个“营销枢纽”有新故事吗?

哪里有内容,哪里就有搜索。 以前,互联网离我们生活很远,传统搜索与用户的距离分割,只有当用户想要了解什么,才会去使用。 如今,互联网与真实世界密不可分,加之新技术、新平台的不断涌现&#xf…...

字节在职5年,一个测试工程师的坎坷之路

几年前进入到IT行业,现在发现学习软件测试的人越来越多,今天我想根据自己的行业经验给大家提一些建议。 跟其他行业相比,做软件测试的岗位确实算是高薪职业,我们那个时候起步的工资并不高,而看现在很多毕业的学生薪资都…...

什么是web框架?

什么是web框架? 我们解释一个概念的时候,通常会用到其他更多的概念去解释它,如果听的人不理解解释它的概念,那么这个解释是失败的,因此首先要回答一下解释web框架中所用到的概念。 回答这个问题前,首先需…...

说一说关系数据库中的范式建模

面试中可能会被问到,来回顾总结一下,参考《数据库系统第五版》(王珊/萨师煊) 范式(normal form),我的理解是用来规范关系数据库中实体如何划分以及实体间如何建立联系来保持数据完整性的一种指导思想,目的就…...

Mysql是怎样运行的之Inno页介绍

一、InnoDB介绍 InnoDB是一个将表中的数据存储到磁盘上的存储引擎,所以即使关机后重启我们的数据还是存在的。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内…...

【华为OD机试模拟题】用 C++ 实现 - 找字符(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 货币单位换算(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 选座位(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 停车场最大距离(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 重组字符串(2023.Q1) 【华为OD机试模…...

JAVA 8 新特性 Lamdba表达式

Java8 新特性: 1、Lamdba表达式 2、函数式接口 3、方法引用和构造引用 4、Stream API 5、接口中的默认方法和静态方法 6、新时间日期API 7、Optional 8、其他特性 Java8 优势:速度快、代码更少(增加了新的语法 Lambda 表达式)、强…...