【MySQL笔记】正确的理解MySQL的MVCC及实现原理

2023-11-07

MVCC多版本并发控制


如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里

!首先声明,MySQL 的测试环境是 5.7

  • 前提概要
    • 什么是 MVCC
    • 什么是当前读和快照读?
    • 当前读,快照读和 MVCC 的关系
  • MVCC 实现原理
    • 隐式字段
    • undo日志
    • Read View
    • 整体流程
  • MVCC 相关问题
    • RR 是如何在 RC 级的基础上解决不可重复读的?
    • RC, RR 级别下的 InnoDB 快照读有什么不同?

前提概要


什么是 MVCC ?

MVCC
MVCC,全称 Multi-Version Concurrency Control ,即多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
mvcc - @百度百科

MVCCMySQL InnoDB 中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读


什么是当前读和快照读?

在学习 MVCC 多版本并发控制之前,我们必须先了解一下,什么是 MySQL InnoDB 下的当前读快照读?

  • 当前读
    像 select lock in share mode (共享锁), select for update; update; insert; delete (排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁

  • 快照读
    不加锁的 select 操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即 MVCC ,可以认为 MVCC 是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

说白了 MVCC 就是为了实现读-写冲突不加锁,而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现


当前读,快照读和MVCC的关系
  • MVCC 多版本并发控制是 「维持一个数据的多个版本,使得读写操作没有冲突」 的概念,只是一个抽象概念,并非实现
  • 因为 MVCC 只是一个抽象概念,要实现这么一个概念,MySQL 就需要提供具体的功能去实现它,「快照读就是 MySQL 实现 MVCC 理想模型的其中一个非阻塞读功能」。而相对而言,当前读就是悲观锁的具体功能实现
  • 要说的再细致一些,快照读本身也是一个抽象概念,再深入研究。MVCC 模型在 MySQL 中的具体实现则是由 3 个隐式字段undo 日志 Read View 等去完成的,具体可以看下面的 MVCC 实现原理

MVCC 能解决什么问题,好处是?

数据库并发场景有三种,分别为:

  • 读-读:不存在任何问题,也不需要并发控制
  • 读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
  • 写-写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

MVCC 带来的好处是?
多版本并发控制(MVCC)是一种用来解决读-写冲突无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。 所以 MVCC 可以为数据库解决以下问题

  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
  • 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

小结一下咯
简而言之,MVCC 就是因为大佬们,不满意只让数据库采用悲观锁这样性能不佳的形式去解决读-写冲突问题,而提出的解决方案,所以在数据库中,因为有了 MVCC,所以我们可以形成两个组合:

  • MVCC + 悲观锁
    MVCC解决读写冲突,悲观锁解决写写冲突
  • MVCC + 乐观锁
    MVCC 解决读写冲突,乐观锁解决写写冲突

这种组合的方式就可以最大程度的提高数据库并发性能,并解决读写冲突,和写写冲突导致的问题


MVCC 的实现原理


MVCC 的目的就是多版本并发控制,在数据库中的实现,就是为了解决读写冲突,它的实现原理主要是依赖记录中的 3个隐式字段undo日志 Read View 来实现的。所以我们先来看看这个三个 point 的概念

隐式字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的 DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID 等字段

  • DB_TRX_ID
    6 byte,最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID
  • DB_ROLL_PTR
    7 byte,回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)
  • DB_ROW_ID
    6 byte,隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID产生一个聚簇索引
  • 实际还有一个删除 flag 隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除 flag 变了

在这里插入图片描述
如上图,DB_ROW_ID 是数据库默认为该行记录生成的唯一隐式主键,DB_TRX_ID 是当前操作该记录的事务 ID ,而 DB_ROLL_PTR 是一个回滚指针,用于配合 undo日志,指向上一个旧版本


undo日志

undo log 主要分为两种:

  • insert undo log
    代表事务在 insert 新记录时产生的 undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
  • update undo log
    事务在进行 updatedelete 时产生的 undo log ; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被 purge 线程统一清除

purge

  • 从前面的分析可以看出,为了实现 InnoDB 的 MVCC 机制,更新或者删除操作都只是设置一下老记录的 deleted_bit ,并不真正将过时的记录删除。

  • 为了节省磁盘空间,InnoDB 有专门的 purge 线程来清理 deleted_bit 为 true 的记录。为了不影响 MVCC 的正常工作,purge 线程自己也维护了一个read view(这个 read view 相当于系统中最老活跃事务的 read view );如果某个记录的 deleted_bit 为 true ,并且 DB_TRX_ID 相对于 purge 线程的 read view 可见,那么这条记录一定是可以被安全清除的。

对 MVCC 有帮助的实质是 update undo logundo log 实际上就是存在 rollback segment 中旧记录链,它的执行流程如下:

一、 比如一个有个事务插入 persion 表插入了一条新记录,记录如下,name 为 Jerry , age 为 24 岁,隐式主键是 1,事务 ID 回滚指针,我们假设为 NULL

二、 现在来了一个事务 1 对该记录的 name 做出了修改,改为 Tom

  • 事务 1 修改该行(记录)数据时,数据库会先对该行加排他锁
  • 然后把该行数据拷贝到 undo log 中,作为旧记录,既在 undo log 中有当前行的拷贝副本
  • 拷贝完毕后,修改该行name为Tom,并且修改隐藏字段的事务 ID 为当前事务 1 的 ID, 我们默认从 1 开始,之后递增,回滚指针指向拷贝到 undo log 的副本记录,既表示我的上一个版本就是它
  • 事务提交后,释放锁

三、 又来了个事务 2 修改 person 表的同一个记录,将age修改为 30 岁

  • 事务2修改该行数据时,数据库也先为该行加锁
  • 然后把该行数据拷贝到 undo log 中,作为旧记录,发现该行记录已经有 undo log 了,那么最新的旧数据作为链表的表头,插在该行记录的 undo log 最前面
  • 修改该行 age 为 30 岁,并且修改隐藏字段的事务 ID 为当前事务 2 的 ID, 那就是 2 ,回滚指针指向刚刚拷贝到 undo log 的副本记录
  • 事务提交,释放锁

从上面,我们就可以看出,不同事务或者相同事务的对同一记录的修改,会导致该记录的undo log成为一条记录版本线性表,既链表,undo log 的链首就是最新的旧记录,链尾就是最早的旧记录(当然就像之前说的该 undo log 的节点可能是会 purge 线程清除掉,向图中的第一条 insert undo log,其实在事务提交之后可能就被删除丢失了,不过这里为了演示,所以还放在这里


Read View 读视图

什么是 Read View?

什么是 Read View,说白了 Read View 就是事务进行快照读操作的时候生产的读视图 (Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的 ID (当每个事务开启时,都会被分配一个 ID , 这个 ID 是递增的,所以最新的事务,ID 值越大)

所以我们知道 Read View 主要是用来做可见性判断的, 即当我们某个事务执行快照读的时候,对该记录创建一个 Read View 读视图,把它比作条件用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。

Read View遵循一个可见性算法,主要是将要被修改的数据的最新记录中的 DB_TRX_ID(即当前事务 ID )取出来,与系统当前其他活跃事务的 ID 去对比(由 Read View 维护),如果 DB_TRX_ID 跟 Read View 的属性做了某些比较,不符合可见性,那就通过 DB_ROLL_PTR 回滚指针去取出 Undo Log 中的 DB_TRX_ID 再比较,即遍历链表的 DB_TRX_ID(从链首到链尾,即从最近的一次修改查起),直到找到满足特定条件的 DB_TRX_ID , 那么这个 DB_TRX_ID 所在的旧记录就是当前事务能看见的最新老版本

那么这个判断条件是什么呢?
在这里插入图片描述
我们这里盗窃@呵呵一笑百媚生一张源码图,如上,它是一段 MySQL 判断可见性的一段源码,即 changes_visible 方法(不完全哈,但能看出大致逻辑),该方法展示了我们拿 DB_TRX_ID 去跟 Read View 某些属性进行怎么样的比较

在展示之前,我先简化一下 Read View,我们可以把 Read View 简单的理解成有三个全局属性

  • trx_list(名称我随意取的)
    • 一个数值列表
    • 用于维护 Read View 生成时刻系统 正活跃的事务 ID 列表
  • up_limit_id
    • lower water remark
    • 是 trx_list 列表中事务 ID 最小的 ID
  • low_limit_id
    • hight water mark
    • ReadView 生成时刻系统尚未分配的下一个事务 ID ,也就是 目前已出现过的事务 ID 的最大值 + 1
    • 为什么是 low_limit ? 因为它也是系统此刻可分配的事务 ID 的最小值
  • 首先比较 DB_TRX_ID < up_limit_id , 如果小于,则当前事务能看到 DB_TRX_ID 所在的记录,如果大于等于进入下一个判断
  • 接下来判断 DB_TRX_ID >= low_limit_id , 如果大于等于则代表 DB_TRX_ID 所在的记录在 Read View 生成后才出现的,那对当前事务肯定不可见,如果小于则进入下一个判断
  • 判断 DB_TRX_ID 是否在活跃事务之中,trx_list.contains (DB_TRX_ID),如果在,则代表我 Read View 生成时刻,你这个事务还在活跃,还没有 Commit,你修改的数据,我当前事务也是看不见的;如果不在,则说明,你这个事务在 Read View 生成之前就已经 Commit 了,你修改的结果,我当前事务是能看见的

整体流程

我们在了解了 隐式字段undo log, 以及 Read View 的概念之后,就可以来看看 MVCC 实现的整体流程是怎么样了

整体的流程是怎么样的呢?我们可以模拟一下

  • 事务 2 对某行数据执行了快照读,数据库为该行数据生成一个Read View读视图,假设当前事务 ID 为 2,此时还有事务1事务3在活跃中,事务 4 事务 2 快照读前一刻提交更新了,所以 Read View 记录了系统当前活跃事务 1,3 的 ID,维护在一个列表上,假设我们称为trx_list
事务 1 事务 2 事务 3 事务 4
事务开始 事务开始 事务开始 事务开始
修改且已提交
进行中 快照读 进行中
  • Read View 不仅仅会通过一个列表 trx_list 来维护事务 2执行快照读那刻系统正活跃的事务 ID 列表,还会有两个属性 up_limit_idtrx_list 列表中事务 ID 最小的 ID ),low_limit_id ( 快照读时刻系统尚未分配的下一个事务 ID ,也就是目前已出现过的事务ID的最大值 + 1 资料传送门 | 呵呵一笑百媚生的回答 ) 。所以在这里例子中 up_limit_id 就是1,low_limit_id 就是 4 + 1 = 5,trx_list 集合的值是 1, 3,Read View 如下图
  • 我们的例子中,只有事务 4 修改过该行记录,并在事务 2 执行快照读前,就提交了事务,所以当前该行当前数据的 undo log 如下图所示;我们的事务 2 在快照读该行记录的时候,就会拿该行记录的 DB_TRX_ID 去跟 up_limit_id , low_limit_id活跃事务 ID 列表( trx_list )进行比较,判断当前事务 2能看到该记录的版本是哪个。
  • 所以先拿该记录 DB_TRX_ID 字段记录的事务 ID 4 去跟 Read Viewup_limit_id 比较,看 4 是否小于 up_limit_id( 1 ),所以不符合条件,继续判断 4 是否大于等于 low_limit_id( 5 ),也不符合条件,最后判断 4 是否处于 trx_list 中的活跃事务, 最后发现事务 ID 为 4 的事务不在当前活跃事务列表中, 符合可见性条件,所以事务 4修改后提交的最新结果对事务 2 快照读时是可见的,所以事务 2 能读到的最新数据记录是事务4所提交的版本,而事务4提交的版本也是全局角度上最新的版本

在这里插入图片描述

  • 也正是 Read View 生成时机的不同,从而造成 RC , RR 级别下快照读的结果的不同

MVCC 相关问题


RR 是如何在 RC 级的基础上解决不可重复读的?
当前读和快照读在 RR 级别下的区别:

表1:

事务A 事务B
开启事务 开启事务
快照读(无影响)查询金额为500 快照读查询金额为500
更新金额为400
提交事务
select 快照读金额为500
select lock in share mode当前读金额为400

在上表的顺序下,事务 B 的在事务 A 提交修改后的快照读是旧版本数据,而当前读是实时新数据 400

表2:

事务A 事务B
开启事务 开启事务
快照读(无影响)查询金额为500
更新金额为400
提交事务
select 快照读金额为400
select lock in share mode当前读金额为400
而在表 2这里的顺序中,事务 B 在事务 A 提交后的快照读和当前读都是实时的新数据 400,这是为什么呢?
  • 这里与上表的唯一区别仅仅是表 1的事务 B 在事务 A 修改金额前快照读过一次金额数据,而表 2的事务B在事务A修改金额前没有进行过快照读。

所以我们知道事务中快照读的结果是非常依赖该事务首次出现快照读的地方,即某个事务中首次出现快照读的地方非常关键,它有决定该事务后续快照读结果的能力

我们这里测试的是更新,同时删除更新也是一样的,如果事务B的快照读是在事务A操作之后进行的,事务B的快照读也是能读取到最新的数据的


RC , RR 级别下的 InnoDB 快照读有什么不同?

正是 Read View 生成时机的不同,从而造成 RC , RR 级别下快照读的结果的不同

  • 在 RR 级别下的某个事务的对某条记录的第一次快照读会创建一个快照及 Read View, 将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个 Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个 Read View,所以对之后的修改不可见;
  • 即 RR 级别下,快照读生成 Read View 时,Read View 会记录此时所有其他活动事务的快照,这些事务的修改对于当前事务都是不可见的。而早于Read View创建的事务所做的修改均是可见
  • 而在 RC 级别下的,事务中,每次快照读都会新生成一个快照和 Read View , 这就是我们在 RC 级别下的事务中可以看到别的事务提交的更新的原因

总之在 RC 隔离级别下,是每个快照读都会生成并获取最新的 Read View;而在 RR 隔离级别下,则是同一个事务中的第一个快照读才会创建 Read View, 之后的快照读获取的都是同一个 Read View。


MySQL系列


参考资料


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【MySQL笔记】正确的理解MySQL的MVCC及实现原理 的相关文章

  • PDO::commit() 成功或失败

    The PHP PDO 提交 http www php net manual en pdo commit php文档指出该方法成功时返回 TRUE 失败时返回 FALSE 这是指beginTransaction 和commit 之间的语句执
  • PMA 4.5.2.0 file_exists():open_basedir 限制生效

    从 PPA 在我的 Ubuntu 服务器上安装 phpMyAdmin 后 https launchpad net nijel archive ubuntu phpmyadmin https launchpad net nijel archi
  • 本地数据库缓存的最佳实践?

    我正在开发一个应用程序 该应用程序的部分内容依赖于 MySQL 数据库 在某些情况下 应用程序将在互联网连接 UMTS 有限的环境中运行 特别是延迟较高的环境 应用程序的用户能够登录 并且应用程序用户界面的大部分内容都是从 MySQL 数据
  • 基本表创建 fpdf

    我找不到使用 fpdf 制作表格并从 mysql 数据库获取数据的合适教程 我只是想知道如何创建一个 我在网上尝试示例时遇到了很多错误 例如 我有 名字 中间名 姓氏 年龄 和 电子邮件 列 如何使用 fpdf 创建表格并回显数据库中的条目
  • Clojure MySQL 语法错误异常(“[...] 靠近 '???????????????' [...]”)

    除了建立连接之外 我在使用 clojure contrib sql 做任何事情时都遇到困难 我有一个 mysqld 在 localhost 3306 上运行 数据库名为clj db 用户 clj user localhost 和密码 clj
  • 如何在Sequelize中从主模型同一级别的包含模型返回结果?

    这是我在项目中完成的代码和结果 我想获得包含模型的结果与主模型相同的结果 下面的代码是我所做的 序列化查询 User findAll include model Position attributes POSITION NAME then
  • 如何使用 PHP 从 MySQL 检索特定值?

    好吧 我已经厌倦了 过去一周我花了大部分空闲时间试图解决这个问题 我知道 SQL 中的查询已更改 但我无法弄清楚 我能找到的所有其他帖子似乎都已经过时了 如果有人能帮助我 我将非常感激 我想做的就是使用手动输入数据库的唯一 密码 来检索行的
  • 哪个是识别关系或非识别关系中的子表?

    在表之间的识别和非识别关系的上下文中 MySQL 文档大量将表称为父表和子表 如何判断哪个表是父表 哪个表是子表 子表 A K A 弱实体 http en wikipedia org wiki Weak entity 是一个表 其主键属性d
  • SQL:查找每个跑步者跑步之间的平均天数

    因此 如果我们给出下表 runner ran Carol 2011 02 01 Alice 2011 02 01 Bob 2011 02 01 Carol 2011 02 02 Bob 2011 02 02 Bob 2011 02 03 B
  • SQLSTATE[HY000] [2002] 资源暂时不可用 - mysql - innodb 和 pdo

    在我的错误日志中得到大量结果 如下所列 数据库中的所有表都是 innodb 并且就与这些表的任何交互而言 一切都是带有准备好的语句的 pdo 正如我所说 所有错误几乎与下面列出的错误相同 但发生在几个不同的页面上 无论页面如何 错误行始终指
  • 如何在数据库中保存未来(!)日期

    这个问题专门涉及未来的日期和时间 对于过去的值 UTC 无疑是首选 我想知道是否有人对拯救生命的 最佳 方法有建议futureMySQL 数据库中的日期和时间 或者就此而言一般来说 特别是在该列可以保存不同时区时间的情况下 考虑到时区规则可
  • 将 mysql LONGTEXT 值转换为 VARCHAR 值?

    我有一个在用户 Facebook 墙上发布的功能 我发送到 facebook 的一件事是我从设置为 LONGTEXT 的 mysql 表中获取的一些文本 如果我将表设置为 LONGTEXT 则文本不会发送到 facebook 但如果我将表设
  • MySQL 中的 UDF 性能

    我注意到 当查询在 SELECT 或 WHERE 子句中调用 UDF 时 MySQL 查询执行时间的性能会呈指数级下降 有问题的 UDF 查询本地表以返回标量值 因此它们不仅执行算术表达式 而且充当相关子查询 我通过简单地删除 UDF 并使
  • MySQL:空间查询查找纬度/经度点是否位于给定边界内

    我正在研究谷歌地图搜索功能 其目的是找出 地理位置 点是否位于多边形内 如下图所示 我使用带有 Spatial 扩展的 mysql 5 6 20 我知道它内置有用的几何函数 因此我可以直接从数据库查询地理编码位置 我的目的是熟悉地理空间函数
  • 选择 mysql 枚举的 php 函数

    因此 我创建了一个函数 它将从数据库中的枚举字段中提取值
  • Mysql 在给定日期时间范围内插入随机日期时间

    使用 SQL 我可以在给出范围的列中插入随机日期时间值吗 例如 给定一个范围2010 04 30 14 53 27 to 2012 04 30 14 53 27 我对范围部分感到困惑 因为我刚刚做了这个 INSERT INTO someta
  • 插入 Mysql 表时防止 Json 排序

    在发送 AJAX 请求时 Json Content 的重新排序已经是一个已知问题 但我不知道在将 Json content 插入 JSON 类型的 Mysql 表时也会发生同样的情况 在这种情况下 mysql 服务器在保存之前也会对其内容进
  • 使用 PHP 显示 Mysql 中的图像

    这就是我的数据库中的表的样子 我正在尝试显示我存储的图像 它是 mimetype longblob 当我运行代码时 它会给我一个带有 的小框 没有错误 只是那个框 有谁知道错误是什么以及如何修复它 Display Index Display
  • 重新启动我的 sql 时,jenkins 失败“sudo:不存在 tty,并且未指定 Askpass 程序 抱歉,请重试。”

    我刚刚配置了 jenkins 在预构建步骤中我尝试重新启动 jenkins 但最终出现以下错误 Commencing build of Revision c5b9f8daac092efc5396d80f568a2cf89ae8b697 or
  • MySql 复合索引

    我们使用 MySql 作为我们的数据库 以下查询在 mysql 表 大约 2500 万条记录 上运行 我在这里粘贴了两个查询 查询运行得太慢 我想知道更好的复合索引是否可以改善这种情况 你知道最好的综合指数是什么吗 并建议我这些查询是否需要

随机推荐

  • STM32单片机初学5-IIC通信驱动OLED屏幕

    在我上篇文章 STM32 软件模拟IIC通信 讲解了软件模拟IIC通信 这篇文章详将细讲解利用软件模拟IIC来控制0 96寸的OLED屏幕 如下图 使其显示字符串 本文将不再对IIC通信原理做详细讲解 所以对IIC通信原理不熟悉的话可以参考
  • NAT技术和代理服务器

    NAT NAT是地址转换协议 将内网地址转换为公网地址 简单的说 NAT就是在局域网内部网络中使用内部地址 而当内部节点要与外部网络进行通讯时 就在网关处 将内部地址替换成公用地址 从而在外部公网 internet 上正常使用 NAT可以使
  • Nginx配置静态资源文件403 没权限及404 Not Found问题解决方法

    Nginx配置静态资源文件403 没权限及404 Not Found问题解决方法 修改配置文件nginx conf 静态文件报错403配置 文件最上方 user nobody改为 user root owner 404错误配置 nginx配
  • Shell脚本——流量探测(自动化运维)

    目的 自动 捕获指定IP或端口的流量生成日志 实现流量探测功能 准备 Root用户权限下才能运行tcpdump脚本 优势 Liunx系统自带 无需安装其他组件 捕获准确度高 缺点 不能同时检测多个IP流量 效率低 重点 日志文件 touch
  • 【报错记录】解决华擎J3455-ITX不插显示器无法开机的问题

    我的J3455 ITX主要当作下载机使用 对付那个速度奇慢的百度云 速度任它慢 我7 24小时不停的下 总能下完 然后又嵌套了一个CentOS7的虚拟机 用于作为GitLab代码服务器使用 可以说是一举多得 但是最近发现这台经常掉线 远程桌
  • idea集成visualvm插件 以及添加visual GC插件 - 监控程序

    安装VisualVM插件 1 插件安装 setting gt Plugings gt VisualVM launcher gt Search in repositories gt install gt Restart IDEA 安装完成之后
  • Java——Intellij IDEA出现java.lang.ClassNotFoundException: com.mysql.jdbc.Driver处理办法

    Intellij IDEA出现 Exception in thread main java lang ClassNotFoundException com mysql jdbc 处理办法 解决方法 File gt project struc
  • git修改提交记录的邮箱

    前言 旧仓库迁移到新的git仓库 而新仓库开启了规则 检查 Git 提交的提交者 Committer 和提交作者 Author 必须是已验证的邮箱 于是 旧的代码仓库无法整库迁移 提交时提示 remote 提交 52954f93882138
  • vue 循环input获取值

    html代码 循环input v model绑定
  • c语言中的语义错误和语法错误,C语言程序中对错误的调试

    程序调试 现在我们已经可以编写一个简单的 C语言程序了 但是你可能会犯一些简单的错误 程序的错误通常叫做 bug 而发现和修正这些错误的过程叫做调试 下面有一个带有一些错误的程序 看看你能找出多少 语法错误 上面的程序中包含了几个语法错误
  • linux grep 使用

    1 grep 单独使用 搜素指定目录中包含指定字符的文件 例如 grep r words 搜素当前目录中包含 words 字符的文件 grep r words wc 搜素当前目录中包含 words 字符的文件 只显示 包含该字符的数量 2
  • gre 填空78-89

    section 78 median 1 Kinetic dynamic energizing Immutable not capable of or susceptible to change 2 It is often argued th
  • idea build 报错,maven install 正常运行

    pom中引的包 代码写的时候也有提示 写完也不报错 build 或者 run 或者 debug 启动就报错 提示程序包xxx无法找到 原来是idea 自身的问题 首先执行maven 命令 mvn idea idea 再点击idea的菜单fi
  • 被包围的棋子 Surrounded Regions

    问题 Given a 2D board containing X and O capture all regions surrounded by X A region is captured by flipping all O s into
  • 浅谈MVC(jsp+servlet+JavaBean简单实例)

    MVC Model View Controller 旨在分离模型 控制 视图 是一种分层思想的体现 项目实例 购物车商品管理 总体设计 1实现DBHelper类 2创建实体类 3创建业务逻辑类 DAO 4创建控制层 5创建页面层 1数据库连
  • Android面试回忆录:Service有几种启动方式?,android开发工程师

    如果需要做耗时的操作 你会怎么做 问题便这样展开了 一个人是否真正懂得原理会灵活运用 一下子便能看出来 当面试者回答到线程和Handler方式时 我会再问一下对方 是否知道IntentService 在什么场景下使用IntentServic
  • 文件操作之文件下载、文件读取

    本文章仅做学习交流 如有违法行为 上传者自行负责 原理 原理案例 检测 怎么寻找文件下载漏洞 利用方面 文件目录的获取分两种 文件类型 常见文件 敏感文件 实际案例演示 Javaweb文件下载代码 当贝市场 通过功能点找到漏洞 RoarCT
  • win10下使用mmdet训练自己的数据模型

    win10下使用mmdet训练自己的数据模型 1 环境配置 2 制作自己的coco数据集 3 进行训练 4 计算测试图像的交并比 参考文献 1 环境配置 1 查看自己cuda版本 2 查看自己python版本 3 安装pytorch 官方地
  • 项目实训(树莓派)(七)树莓派4B下的ubuntu系统下命令行的使用-磁盘管理部分

    目录 前言 实验目的 实验内容 实验环境 实验步骤 1 df命令 2 fdisk命令 磁盘分区 3 hdparm命令 显示与设定硬盘参数 4 lsblk命令 查看系统的磁盘 5 vgextend命令 扩展卷组 前言 通过前面的实验 我们已经
  • 【MySQL笔记】正确的理解MySQL的MVCC及实现原理

    MVCC多版本并发控制 如果觉得对你有帮助 能否点个赞或关个注 以示鼓励笔者呢 博客目录 先点这里 首先声明 MySQL 的测试环境是 5 7 前提概要 什么是 MVCC 什么是当前读和快照读 当前读 快照读和 MVCC 的关系 MVCC