MYSQL三大日志、隔离级别(MVCC+锁机制实现)

MySQL三大日志

​Undo Log(回滚日志)

作用

事务回滚时恢复数据到修改前的状态。
支持 ​​MVCC​​,为读操作提供历史版本数据。

存储

存放在 undo tablespace 中,通过回滚段管理。

格式

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

​​Redo Log(重做日志)

作用

保证事务的​​持久性​​,记录物理页的修改(物理日志,比如对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新,每当执行一个事务就会产生这样的一条或者多条物理日志),用于崩溃恢复。

写入时机​​

事务执行中按顺序循环写入,通过 innodb_flush_log_at_trx_commit 控制刷盘策略(0/1/2)。

组成

内存中的 redo log buffer 和磁盘上的 redo log file。

undo log 和 redo log 区别

undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值;
redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
事务提交之前发生了崩溃,重启后会通过 undo log 回滚事务,事务提交之后发生了崩溃,重启后会通过 redo log 恢复事务
在这里插入图片描述

​​​​Binlog(二进制日志)

MySQL 在完成一条更新操作后,Server 层还会生成一条 binlog,等之后事务提交的时候,会将该事物执行过程中产生的所有 binlog 统一写 入 binlog 文件。

作用

记录所有对数据库的​​修改操作​​(逻辑日志),用于主从复制、数据恢复(如通过 mysqlbinlog 工具恢复数据)。

写入时机​​

事务提交后顺序写入,通过参数 sync_binlog 控制刷盘策略。

格式

STATEMENT(记录SQL语句)、ROW(记录行数据变化)、MIXED(混合模式)。

redo log 和 binlog 区别

1、适用对象不同:
binlog 是 MySQL 的 Server 层实现的日志,所有存储引擎都可以使用;
redo log 是 Innodb 存储引擎实现的日志;
2、文件格式不同:
binlog 记录每一条修改数据的 SQL (相当于记录了逻辑操作,所以针对这种格式, binlog 可以称为逻辑日志),
redo log 是物理日志,记录的是在某个数据页做了什么修改,比如对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新;
3、写入方式不同:
binlog 是追加写,写满一个文件,就创建一个新的文件继续写,不会覆盖以前的日志,保存的是全量的日志。
redo log 是循环写,日志空间大小是固定,全部写满就从头开始,保存未被刷入磁盘的脏页日志。
4、用途不同:
binlog 用于备份恢复、主从复制;
redo log 用于掉电等故障恢复。

MySQL Buffer Pool

核心概念​

MySQL 的数据都是存在磁盘中的,那么我们要更新一条记录的时候,得先要从磁盘读取该记录,然后在内存中修改这条记录。修改完这条记录不是直接写回到磁盘,而是缓存起来。
为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。
Buffer Pool​​ 是 InnoDB 引擎的关键内存区域,用于缓存​​数据页和索引页​​,减少磁盘 I/O,提升数据库性能。
所有读写操作首先作用于 Buffer Pool,修改后的页称为​​脏页(Dirty Page)​​,最终由后台线程刷回磁盘。
在这里插入图片描述
当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
当修改数据时,如果数据存在于 Buffer Pool 中,那直接修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页(该页的内存数据和磁盘上的数据已经不一致),为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。

Buffer Pool 配置​

大小设置​​:

通过参数 innodb_buffer_pool_size 配置,通常设为系统内存的 ​​50%-70%​​。

多实例​​:

在高并发场景下,可通过 innodb_buffer_pool_instances 分割为多个实例,减少锁竞争。

内存管理与 LRU 算法​

LRU 链表优化​​:

InnoDB 将 LRU 链表分为 ​​Young 区(热点数据)​​和 ​​Old 区(新加载数据)​​,避免全表扫描冲刷热点数据。
​​Old SubList​​:新数据页首先插入 Old 区头部。
​​Young SubList​​:若 Old 区的页在 innodb_old_blocks_time(默认 1 秒)后被再次访问,则移到 Young 区。

预读机制​​:

​​线性预读(Linear Read-ahead)​​:基于顺序访问模式,预读相邻页。
​​随机预读(Random Read-ahead)​​:根据页的访问模式预测加载其他页(默认关闭)。

脏页刷新与持久化​

刷新机制​​:

​​Checkpoint​​:定期将脏页刷盘,崩溃恢复时从 Checkpoint 位置开始重放 redo log。InnoDB 通过 ​​Checkpoint​​ 机制标记哪些 Redo Log 对应的脏页已经刷盘
​​自适应刷新(Adaptive Flushing)​​:根据负载动态调整刷盘速率,避免 I/O 尖峰。

​​刷盘触发条件​​:

1.Buffer Pool 空间不足时:
当 Buffer Pool 空间不足时,InnoDB 会根据 ​​LRU(Least Recently Used)算法​​ 淘汰旧页:如果淘汰的是脏页,会先将其刷盘(确保数据一致性)。
2.Redo Log 空间不足(触发 Checkpoint,强制刷脏页以释放 Redo Log 空间)。
3.后台线程定期刷新。

与日志系统的协作​

Redo Log​​:事务提交时先写 redo log,确保即使脏页未刷盘,崩溃后仍可通过 redo log 恢复。
​​Undo Log​​:用于事务回滚和 MVCC,其历史版本数据可能存储在 Buffer Pool 的 undo 页中。

事务隔离级别​

MySQL 支持四种隔离级别,通过 ​​MVCC​​ 和​​锁机制​​实现:

READ UNCOMMITTED(读未提交)​​

事务可以读到其他未提交事务的修改。
​​问题​​:脏读、不可重复读、幻读。

READ COMMITTED(读已提交,RC)​​

事务只能读到其他已提交事务的修改。
​​实现​​:每次 SELECT 生成新的 ReadView。
​​问题​​:不可重复读、幻读。

REPEATABLE READ(可重复读,RR)​​

​​默认隔离级别​​,事务内多次读取同一数据的结果一致。
​​实现​​:事务第一次 SELECT 时生成 ReadView,后续复用。
​​解决​​:脏读、不可重复读;通过​​间隙锁(Gap Lock)​​ 避免幻读(当前读时生效)。

SERIALIZABLE(串行化)​​

所有操作加锁,强制事务串行执行。
​​解决​​:所有并发问题,但性能最低。

MVCC

MVCC(多版本并发控制 Multi-Version Concurrency Control)是数据库实现高并发访问的核心机制,​​通过维护数据的多个版本,允许读操作不阻塞写操作,写操作也不阻塞读操作​​。InnoDB 引擎使用 MVCC 实现了 ​​非阻塞读​​,显著提升了数据库的并发性能,尤其在高读低写的场景下效果显著。

MVCC 的核心原理​

在这里插入图片描述

​​隐藏字段​​

InnoDB 的每行数据包含两个隐藏字段:
​​DB_TRX_ID​​:最近修改该行数据的事务 ID(事务提交时写入)。
​​DB_ROLL_PTR​​:指向 Undo Log 的回滚指针,用于构建数据的历史版本链。

​​Undo Log​​

存储数据的历史版本,通过回滚指针(DB_ROLL_PTR)串联成一个链表(版本链)。
​​作用​​:
事务回滚时恢复数据到旧版本。
提供 MVCC 所需的历史版本数据。

ReadView​​(读视图)

事务在发起读操作时生成的一个​​快照​​,用于判断数据版本的可见性。
​​关键信息​​:
m_ids:生成 ReadView 时活跃(未提交)的事务 ID 集合。
min_trx_id:活跃事务中的最小事务 ID。
max_trx_id:生成 ReadView 时系统将分配给下一个事务的 ID。
creator_trx_id:创建该 ReadView 的事务 ID(仅当该事务自身有修改时存在)。
在这里插入图片描述

数据可见性规则​

MVCC 通过以下规则判断数据版本是否对当前事务可见:
如果数据版本的 ​​DB_TRX_ID < min_trx_id​​,说明该版本在 ReadView 生成前已提交,​​可见​​。
如果数据版本的 ​​DB_TRX_ID >= max_trx_id​​,说明该版本由未来事务修改,​​不可见​​。
如果 ​​DB_TRX_ID 在 m_ids 中​​,说明该版本由未提交的事务修改,​​不可见​​。
如果 ​​DB_TRX_ID 不在 m_ids 中且 DB_TRX_ID < max_trx_id​​,说明该版本已提交,​​可见​​。
特殊处理​​:
如果该版本由当前事务自身修改(DB_TRX_ID == creator_trx_id),则可见。

MVCC 与隔离级别​

不同隔离级别下,MVCC 的行为差异主要体现在 ​​ReadView 的生成时机​​:

READ COMMITTED(读已提交,RC)​​

​​每次 SELECT 都生成新的 ReadView​​。
​​效果​​:能读到其他事务已提交的最新数据,但可能导致不可重复读。

REPEATABLE READ(可重复读,RR)​​

​​事务第一次 SELECT 时生成 ReadView,后续复用​​。(每开启一个事物才会生成一个 readView,一个事务的所有SQL语句共享一个 readView。)
​​效果​​:整个事务中看到的数据版本一致,解决不可重复读。

MVCC 如何解决并发问题​

脏读​​

不可见未提交事务的版本(通过 ReadView 过滤活跃事务的修改)。
例:
如下所示是 student 学生表中的一条数据
在这里插入图片描述
(1) 假设现在有事务A和事务B两个事务并发操作该行数据。事务A执行了两次查询操作,事务B执行了一次更新操作;
(2)事务A执行第一次查询操作,先生成 readView ,我们姑且称之为 readView_1,还未开始查询操作,事务B率先执行了更新操作,将数据进行了修改并提交,事务B结束,此时事务A第一次查询开始,但由于事务A已经生成了 readView_1 ,所以它不会读取到事务B修改过后的数据,读取到的是 readView_1 中事务B修改之前的数据,解决了脏读的问题;
(3)然后,事务A进行第二次查询操作。注意!!!这里它又生成了一个 readView,我们称之为 readView_2,此时的 readView_2 中的数据是已经被事务B修改后的数据了,事务A再次进行查询,发现查询到的数据和刚操第一次查询到的不一样了,就产生了不可重复读的问题。
(4)所以说,MVCC 在读已提交隔离级别下只解决了脏读的问题,没有解决不可重复读的问题。

​​不可重复读​​

RR 隔离级别下,复用同一个 ReadView 保证多次读取结果一致。
例:
仍以上面的学生表举例,如下所示
在这里插入图片描述
(1)假设现在事务A与事务B并发操作来查询 student 表。事务A 执行SELECT查询操作,执行查询操作之前会生成一个 readView,我们姑且称之为 readView_1 ,事务A从始至终使用的都是 readView_1;
(2)此时事务B来修改 student 数据,可重复读隔离级别中一个事务生成一个 readView ,所以事务B也生成了一个 readView ,我们称之为 readView_2,然后事务B率先修改完毕并提交;
(3)事务A在事务B提交之后才进行的查询,按道理来说因为事务B修改了数据,我们会产生不可重复读,但是因为事务A从始至终都是用的 readView_1 ,所以 事务A在进行查询操作的时候,查询到的其实还是事务B修改之前的数据,由此就解决了不可重复读;而且即便事务A后续进行了多次 SELECT 查询操作,仍然使用最开始生成的 readView,解决了 不可重复读的问题。
(4)总结:其实归根结底,读已提交,可重复读两种隔离级别最关键的因素就是 readView 生成的时机不同,造就了它们不同的隔离级别。

幻读​​

幻读(Phantom Read)是数据库事务隔离性问题的一种,表现为:​​同一事务中多次执行相同范围的查询,后续查询返回了其他事务插入的新行​​。MySQL 在 ​​可重复读(RR)​​ 隔离级别下,通过 ​​MVCC​​ 和 ​​间隙锁(Gap Lock)​​ 结合的方式解决幻读问题。以下是详细分析:

幻读的本质​

​​场景示例​​:
事务 A 查询 age > 20 的用户,返回 10 条数据。
事务 B 插入一条 age = 25 的新用户并提交。
事务 A 再次查询 age > 20,发现返回了 11 条数据(多出事务 B 插入的行)。
​​核心问题​​:​​范围查询中新增的数据破坏了事务的一致性视图​​。

MySQL 解决幻读的机制​
MVCC(快照读)​​

​​原理​​:
在 RR 隔离级别下,事务首次读取数据时生成 ​​ReadView​​,后续查询复用该快照,确保多次读取同一范围的数据时,结果一致(基于历史版本)。
​​效果​​:
​​快照读(普通 SELECT)​​:通过 MVCC 读取历史版本数据,​​不会看到其他事务插入的新行​​,避免了幻读。
​​局限性​​:若事务中执行写操作(如 UPDATE/DELETE),可能触发当前读,导致幻读风险。

间隙锁(Gap Lock)​

​​​​原理​​:
对索引记录之间的“间隙”加锁,阻止其他事务在范围内插入新数据。
​​间隙范围​​:例如,表中现有 id=5 和 id=10 的记录,间隙锁会锁定 (5, 10) 区间。
​​加锁场景​​:
执行 SELECT … FOR UPDATE(当前读)。
执行 UPDATE 或 DELETE 影响范围内的数据。
​​效果​​:
其他事务无法在加锁的间隙内插入新数据,​​彻底避免幻读​​。
仅在 RR 隔离级别下生效。

不同隔离级别下的幻读行为​

在这里插入图片描述

RR 隔离级别下的幻读解决方案​
快照读 + MVCC(隐式解决)​​

​​场景​​:事务中仅执行普通 SELECT 查询(快照读)。
​​示例​​:

-- 事务 A(RR 隔离级别)
START TRANSACTION;
SELECT * FROM users WHERE age > 20; -- 生成 ReadView,返回 10 条数据-- 事务 B 插入新数据并提交
INSERT INTO users (age) VALUES (25);
COMMIT;-- 事务 A 再次查询
SELECT * FROM users WHERE age > 20; -- 仍返回 10 条数据(ReadView 未更新)

结果​​:事务 A 的两次查询结果一致,MVCC 屏蔽了事务 B 的插入操作。

当前读 + 间隙锁(显式解决)​

​​场景​​:事务中执行 SELECT … FOR UPDATE、UPDATE 或 DELETE(当前读)。
​​示例​​:

-- 事务 A(RR 隔离级别)
START TRANSACTION;
SELECT * FROM users WHERE age > 20 FOR UPDATE; -- 当前读,对 age > 20 的间隙加锁-- 事务 B 尝试插入新数据(age=25)
INSERT INTO users (age) VALUES (25); -- 被阻塞,直到事务 A 提交或回滚-- 事务 A 提交后,事务 B 才能继续执行
COMMIT;

结果​​:事务 B 的插入操作被间隙锁阻塞,事务 A 的两次查询结果一致。

MVCC 的实现细节​

​​版本链遍历​​

从当前数据行的 DB_ROLL_PTR 开始,沿着 Undo Log 链表查找符合可见性规则的版本。

Undo Log 清理​​

当没有事务需要访问某个历史版本时,对应的 Undo Log 会被 Purge 线程清理。
​​风险​​:长事务可能导致 Undo Log 堆积,引发存储膨胀。

事务 ID 分配​​

事务 ID(DB_TRX_ID)是全局自增的,每个事务在修改数据时被分配唯一 ID。

快照读 vs 当前读​

快照读(Snapshot Read)​​

​​操作​​:普通 SELECT 语句(不加锁)。
​​实现​​:基于 MVCC 读取历史版本数据。
​​特点​​:不阻塞写操作,但可能读到旧数据。

当前读(Current Read)​​

​​操作​​:SELECT … FOR UPDATE、UPDATE、DELETE、INSERT。
​​实现​​:读取最新数据并加锁(如行锁、间隙锁),确保操作的一致性。
​​特点​​:阻塞其他事务的并发修改,保证数据最新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/81766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访问计划(C++)

题目描述 Farmer John 计划建造 N&#xff08;1≤N≤10^5&#xff09;个农场&#xff0c;用 N−1 条道路连接&#xff0c;构成一棵树&#xff08;也就是说&#xff0c;所有农场之间都互相可以到达&#xff0c;并且没有环&#xff09;。每个农场有一头奶牛&#xff0c;品种为更…

时间同步服务

时间同步:多主机协作工作时&#xff0c;各个主机的时间同步很重要&#xff0c;时间不一致会造成很多重要应用的故障&#xff0c;如:加密协议&#xff0c;日志&#xff0c;集群等&#xff0c;利用NTP(Network Time Protocol )协议使网络中的各个计算机 时间达到同步。目前NTP协议…

Cordova开发自定义插件的方法

Cordova开发自定义插件的方法 文章目录 Cordova开发自定义插件的方法[TOC](文章目录) 一、自定义插件二、android下的自定义插件开发&#xff08;一&#xff09;步骤1、建立cordova工程2、建立自定义插件&#xff08;1&#xff09; 安装plugman&#xff08;2&#xff09; 用plu…

【libm】2整数接口(int_traits.rs)

一、源码 int_traits.rs文件定义了两个核心 trait MinInt 和 Int&#xff0c;为整数类型提供统一的抽象接口&#xff0c;并通过宏为所有原生整数类型&#xff08;i8 ~ i128/u8 ~ u128&#xff09;实现这些 trait。 use core::{cmp, fmt, ops};/// Minimal integer implementa…

WebSocket实战经验

WebSocket实战经验详解 WebSocket基础概念 #mermaid-svg-sdkZP4UrWBpk2Hco {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sdkZP4UrWBpk2Hco .error-icon{fill:#552222;}#mermaid-svg-sdkZP4UrWBpk2Hco .error-tex…

【C/C++】MQTT

文章目录 MQTT 协议1 基本概念2 核心特性3 核心组件4 C 简易实现&#xff08;基于 Paho MQTT 库&#xff09;环境准备示例代码 不同mqtt对比关键差异说明 MQTT 协议 1 基本概念 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅模式…

《Java 高并发程序设计》笔记

&#x1f4a1; 根据 遗忘曲线&#xff1a;如果没有记录和回顾&#xff0c;6天后便会忘记75%的内容 读书笔记正是帮助你记录和回顾的工具&#xff0c;不必拘泥于形式&#xff0c;其核心是&#xff1a;记录、翻看、思考 ::: 书名Java 高并发程序设计作者葛一鸣、郭超状态已读完简…

Fine Structure-Aware Sampling(AAAI 2024)论文笔记和启发

文章目录 本文解决的问题本文提出的方法以及启发 本文解决的问题 传统的基于Pifu的人体三维重建一般通过采样来进行学习。一般选择的采样方法是空间采样&#xff0c;具体是在surface的表面随机位移进行样本的生成。这里的采样是同时要在XYZ三个方向上进行。所以这导致了一个问…

【AI面试准备】性能测试与AI模型结合应用指南

面试题&#xff1a; 性能测试&#xff1a;AI模型预测系统瓶颈&#xff08;如LoadRunnerAI模块&#xff09;。 性能测试与AI模型预测系统瓶颈的结合是当前软件工程和运维领域的重要趋势&#xff0c;能够显著提升系统优化效率和问题预测能力。以下从核心概念、技术实现、快速掌握…

Spring MVC 与 FreeMarker 整合

以下是 Spring MVC 与 FreeMarker 整合的详细步骤&#xff0c;包含配置和代码示例&#xff1a; 1. 添加依赖 在 pom.xml 中引入 Spring MVC 和 FreeMarker 的依赖&#xff08;以 Maven 为例&#xff09;&#xff1a; <!-- Spring Web MVC --> <dependency><gr…

Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付

本章重点在于如何使用redis的分布式锁来锁定库存。减少超卖&#xff0c;同时也对接了支付宝&#xff0c;paypal&#xff0c;strip跨境支付 第一步先建立一个商品表 CREATE TABLE sys_product (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,code varchar(60) DEFAUL…

使用frpc链接内网的mysql

以下是配置 frpc 连接内网 MySQL 服务的详细步骤&#xff1a; 1. 准备工作 frps 服务器&#xff1a;已部署在公网 IP 11.117.11.245&#xff0c;假设 frps 的默认端口为 7000。 内网 MySQL 服务&#xff1a;运行在内网机器的 3306 端口。 目标&#xff1a;通过公网 IP 11.117…

2025信息安全网络安全意识培训资料汇编(24份)

最新整理&#xff1a;2025信息安全网络安全意识培训资料汇编&#xff0c;共24份资料&#xff0c;供学习参考。 互联网信息安全意识培训.pptx100个网络安全风险防范知识.pptx亚信信息安全意识培训.pptx网络安全法规及意识培训.pptx网络安全意识与案例分析.pptx绿盟-安全意识培训…

JAVA:使用 XStream 实现对象与XML转换的技术指南

1、简述 XStream 是一个简单便捷的 Java 库,用于对象与 XML 的相互转换。其主要特点是: 易于使用:无需复杂的配置即可直接使用。支持自定义:可以灵活地定制对象的序列化和反序列化规则。强大的功能:支持注解、自定义转换器等。本文将详细介绍 XStream 的基本使用方法,并…

VITA STANDARDS LIST,VITA 标准清单下载

VITA STANDARDS LIST&#xff0c;VITA 标准清单下载 DesignationTitleAbstractStatusVMEbus Handbook, 4th EditionA users guide to the VME, VME64 and VME64x bus specifications - features over 70 product photos and over 160 circuit diagrams, tables and graphs. The…

Assetto Corsa 神力科莎 [DLC 解锁] [Steam] [Windows]

Assetto Corsa 神力科莎 [DLC 解锁] [Steam] [Windows] 需要有游戏正版基础本体&#xff0c;安装路径不能带有中文&#xff0c;或其它非常规拉丁字符&#xff1b; DLC 版本 至最新全部 DLC 后续可能无法及时更新文章&#xff0c;具体最新版本见下载文件说明 DLC 解锁列表&…

【Java idea配置】

IntelliJ IDEA创建类时自动生成注释 /** * program: ${PROJECT_NAME} * * since: jdk1.8 * * description: ${description} * * author: ${USER} * * create: ${YEAR}-${MONTH}-${DAY} ${HOUR}:${MINUTE} **/自动导入和自动移除无用导入 idea彩色日志不生效 调试日志输出 在…

计算方法实验六 数值积分

【实验性质】综合性实验。 【实验目的】理解插值型积分法&#xff1b;掌握复化积分法算法。 【实验内容】 1对 &#xff0c;用复化梯形积分和变步长梯形积分求值&#xff08;截断误差不超过&#xff09;。 【理论基础】 积分在工程中有重要的应用&#xff0c;数值积分…

Webug4.0靶场通关笔记11- 第15关任意文件下载与第16关MySQL配置文件下载

目录 一、文件下载 二、第15关 任意文件下载 1.打开靶场 2.源码分析 3.渗透实战 三、第16关 MySQL配置文件下载 1.打开靶场 2.源码分析 3.渗透实战 &#xff08;1&#xff09;Windows系统 &#xff08;2&#xff09;Linux系统 四、渗透防御 一、文件下载 本文通过…

小土堆pytorch--tensorboard的使用

小土堆pytorch--tensorboard的使用 小土堆pytorch--tensorboard的使用0.介绍1.使用tensorboard绘制 y x 等简单函数1.1 相应的代码1.2 对上述代码的解释1.3 可能遇到的问题1.3.1 问题1.3.2 解决方法 2.使用tensorboard加载数据集中的图片2.1 相应代码2.2 对上述代码的解释2.2.…