建设教育协会网站,wordpress协会主题,怎么做网站加盟,网站托管费用多少前言
Mysql#xff0c;作为一款优秀而广泛使用的数据库管理系统#xff0c;对于众多Java工程师来说#xff0c;几乎是日常开发中必不可少的一环。无论是存储海量数据#xff0c;还是高效地检索和管理数据#xff0c;Mysql都扮演着重要的角色。然而#xff0c;除了使用My…
前言
Mysql作为一款优秀而广泛使用的数据库管理系统对于众多Java工程师来说几乎是日常开发中必不可少的一环。无论是存储海量数据还是高效地检索和管理数据Mysql都扮演着重要的角色。然而除了使用Mysql进行日常开发之外我们是否真正了解它的底层架构以及设计实现的流程呢本篇博客将带您深入探索Mysql底层架构的设计与实现流程帮助您更好地理解和应用这个强大的数据库系统。让我们一同揭开Mysql底层的神秘面纱探寻其中的奥秘。
1.你眼中的Mysql是什么样子
MySQL在大部分普通Java工程师的眼中往往被视为一种用于存储和操作数据的工具。我们常常将其用于建立数据库、创建表和索引以便进行数据的增删改查操作。这些基本的使用方法已经成为我们日常工作中与MySQL打交道的常规操作。就像下图一样 然而在日常开发中我们往往只关注于如何正确地使用MySQL进行数据操作而很少深入了解MySQL的底层架构和实现原理。我们可能对存储引擎、查询优化器、事务管理等底层机制知之甚少对于如何优化性能、保证数据一致性、备份恢复等方面的知识掌握有限。 正因如此了解MySQL底层架构设计和实现流程对我们来说至关重要。它不仅可以帮助我们更全地理解MySQL的内部机制还能够提升我们的工作效率和质量。在接下来的内容中我们将深入探讨MySQL底层架构的各个组件和技术希望能够为大家带来更深入、更全面的MySQL知识。让我们一同揭开MySQL底层的面纱探索其中的奥秘
2.Java系统是如何连接Mysql的
在Java中连接MySQL数据库通常需要通过JDBCJava Database Connectivity来实现。JDBC是Java提供的一套用于访问数据库的API它提供了一种标准的接口使得我们可以通过Java代码与各种数据库进行交互。
要连接MySQL数据库首先需要确保系统中已经安装了MySQL数据库并且在Java项目中导入了适当的MySQL JDBC驱动。Mysql驱动为我们搭建了Java系统到Msyql数据库之间的桥梁
因此当我们在实现业务代码的时候如果需要执行相关的SQL语句就可以由Mysql驱动帮我们传递SQL语句到Mysql数据库进行落地执行 接着我们来思考一个问题一个Java系统难道只会跟数据库建立一个连接吗这个肯定是不行的因为我们要明白一个道理假设我们用Java开发了一个Web系统是部署在Tomcat中的那么Tomcat本身肯定是有多个线程来并发处理接收到的多个请求的我们看下图 但是在高并发场景下如果每个Tomcat线程在访问数据库时都创建一个数据库连接、执行SQL语句然后销毁连接这样的做法行得通吗可能有几百个线程会频繁执行这一过程。这种方式是不可取的。每次建立数据库连接都需要耗费时间当连接建立完成SQL语句执行完毕后就销毁连接再重新建立连接。这样的效率非常低下。
因此我们需要引入连接池的概念可以解决这个问题。连接池会维护一组可重用的数据库连接并对连接进行有效管理。Tomcat线程在需要访问数据库时可以从连接池中获取一个可用连接执行完毕后将连接归还给连接池。这样可以减少连接的频繁创建和销毁提升性能。如下所示 3.Mysql为什么也需要连接池
你知道去银行办业务时有时候需要排队等待吗假设每个人都需要等待银行的工作人员为他们办理业务这样会很浪费时间和资源对吧MySQL连接池就像是银行办理业务的排队系统它帮助我们更有效地管理和利用数据库连接。 提高连接效率在MySQL中建立数据库连接需要进行一些准备工作就像是银行工作人员办理业务前需要做一些准备。如果每次都重新创建连接就像每个人都要去银行排队取号、办理业务那将非常低效。连接池会提前创建一些连接就像是银行提前准备好几个窗口供业务办理这样只需从连接池获取一个可用连接减少了等待时间提高了连接效率。节约系统资源数据库连接是有限的资源就像银行的工作人员有限。如果每个人都占用一个工作人员办理业务银行很快就会瘫痪。连接池可以管理和控制连接的数量类似于银行控制窗口的数量确保不会创建过多的连接从而避免数据库和服务器资源的浪费。简化连接管理连接池可以让我们更轻松地管理连接就像银行的排队系统让银行工作人员可以集中处理客户业务一样。通过连接池我们无需手动创建和释放连接只需从连接池获取连接并使用完成后归还给连接池。这样简化了连接管理的工作提高了开发效率。综上所述MySQL连接池就像银行排队系统它能够提高连接效率、节约系统资源、管理连接的可靠性并简化连接的管理。接池在高并发的数据库操作中起着重要的作用帮助我们更有效、更方便地与MySQL数据库进行连接和交互。 4.Mysql如何处理连接请求的
当Mysql接收到一个网络连接请求后它是如何去处理该请求的以及如何将SQL最终执行的我们一起来看看整个过程链路中会经历哪些步骤。 首先
网络连接必须得分配给一个线程去进行处理由一个线程来监听请求以及读取请求数据比如从网络连接中读取和解析出来一条Java系统发送过去的SQL语句。Mysql内部提供了一个组件SQL接口SQL Interface用来专门执行SQL语句的接口然后通过查询优化器选择最优的查询路径来执行作用针对你编写的几十行、几百行甚至上千行的复杂SQL语句生成查询路径树然后从里面选择一条最优的查询路径出来。调用执行器根据执行计划调用存储引擎的接口调用存储引擎接口真正执行SQL语句作用 执行器会根据优化器选择的执行方案去调用存储引擎的接口按照一定的顺序和步骤就把SQL语句的逻辑给执行了存储引擎管理和存储数据支持各种各样的存储引擎比如InnoDB、MyISAM、Memory我们可以自己选择使用哪种存储引擎来负责具体的SQL语句执行现在MySQL一般都是默认使用InnoDB存储引擎 以上整个执行过程大家感兴趣的可以深入研究本篇文章就不做细节介绍了。我们接着来分析InnoDB存储引擎是如何管理和存储我们的数据。
5.InnoDB的重要内存结构缓冲池
InnoDB存储引擎中有一个非常重要的放在内存里的组件就是缓冲池BufferPool这里面会缓存很多的数据以便于以后在查询的时候万一你要是内存缓冲池里有数据就可以不用去查磁盘了我们看下图。 比如SQL语句update users set name‘xxx’ where id1比如对“id1”这一行数据他其实会先将“id1”这一行数据看看是否在缓冲池里如果不在的话那么会直接从磁盘里加载到缓冲池里来而且接着还会对这行记录加独占锁。
缓冲池使用LRULeast Recently Used最近最少使用算法来管理内存中的数据页。当查询需要访问数据时InnoDB首先检查缓冲池中是否存在相应的数据页。如果存在它会直接从内存中获取数据而不是从磁盘中读取这大大提高了查询性能。如果数据页不在缓冲池中InnoDB会将其读取到缓冲池并将其保留在内存中供后续查询使用。
通过适当配置缓冲池的大小可以使常用的数据页始终在内存中提高查询效率。较大的缓冲池通常适用于具有大量内存的服务器
6.undo日志文件让更新的数据可以回滚
Undo日志文件用于记录数据库中正在进行的事务的操作以便在需要回滚事务时提供回滚数据。当有更新、删除或插入操作发生时InnoDB引擎会将相关信息记录到Undo日志文件中。
当需要撤销事务时InnoDB引擎使用Undo日志来还原数据到事务开始之前的状态。它通过逆向操作来撤销对数据的修改并将数据还原为先前的状态。 当我们把要更新的那行记录从磁盘文件加载到缓冲池同时对他加锁之后而且还把更新前的旧值写入undo日志文件之后我们就可以正式开始更新这行记录了更新的时候先是会更新缓冲池中的记录此时这个数据就是脏数据了。
这里所谓的更新内存缓冲池里的数据意思就是把内存里的“id1”这行数据的name字 段修改为“xxx” 7.redo日志文件保证数据的一致性和持久性
现在我们试想下上图中的修改操作如果已经写入缓存中但是还未来得及同步到磁盘进行持久化此时msyql的机器宕机了挂了那么缓存中的数据必然也会丢失那么本次更新的数据也就丢失了。因此为了保障Mysql数据的一致性和持久性innodb引擎引入了redo 日志文件。 Redo Log日志是一种物理日志主要用于记录在事务提交前对数据库进行的修改操作。当数据库崩溃或发生故障时通过Redo Log可以恢复到最后一次提交的状态保证数据的持久性。 Redo Log的作用主要体现在以下两个方面
数据恢复当数据库发生故障时通过Redo Log可以将未提交的修改操作重新应用到数据库中从而恢复到最后一次提交的状态。提高性能通过将修改操作记录到Redo Log中可以将磁盘IO操作转化为顺序写操作大幅提高了数据库的写入性能。
因此当更新操作执行后Mysql会把对内存所做的修改写入到一个Redo Log Buffer里去这也是内存里的一个缓冲区是用来存放redo日志的。所谓的redo日志就是记录下来你对数据做了什么修改比如对“id10这行记录修改了name字段的值为xxx”这就是一个日志。如下图所示 备注innodb_log_buffer_size指定Redo Log的缓冲区大小默认为8MB。较大的值 可以减少频繁的刷新操作提高性能但同时也会占用更多的内存。
8.提交事务redo日志刷盘
当提交事务的时候redolog中缓存区中的数据才会被刷入到磁盘。那么此时数据丢失要紧吗
其实是不要紧的因为你一条更新语句没提交事务就代表他没执行成功此时MySQL宕机虽然导致内存里的数据都丢失了但是你会发现磁盘上的数据依然还停留在原样子。
redo日志写入磁盘的三种策略
刷盘策略是通过innodb_flush_log_at_trx_commit来配置的他有几个选项
1.参数值为0redo log不进磁盘表示不刷写Redo Log到磁盘即异步写入策略。事务提交时Redo Log的修改操作只会写入到操作系统的页缓存中并不会马上刷写到磁盘。这样可以提供最好的写入性能但在数据库崩溃或发生故障时可能会造成一定程度的数据丢失。
2.参数值为1redo log进磁盘【默认值】表示同步刷写Redo Log到磁盘。事务提交时Redo Log的修改操作会立即写入磁盘并等待IO操作完成。确保数据持久性的同时也会对性能产生一定的影响。这是最常用的设置适合大多数应用场景。 3.参数值为2redo log进os cache缓存 刷盘策略选择
选择适当的innodb_flush_log_at_trx_commit值取决于对数据的持久性和性能的需求。如果对数据的持久性要求非常高可以将其设置为1。如果对性能要求较高且可以接受一定程度的数据丢失可以将其设置为0。如果在保证一定程度的数据保护的同时追求更好的性能可以选择设置为2。
可以通过修改MySQL配置文件中的参数设置来调innodb_flush_log_at_trx_commit值并重启MySQL服务使其生效。
我们通常建议是设置为1。也就是说提交事务的时候redo日志必须是刷入磁盘文件里的。这样可以严格的保证提交事务之后数据是绝对不会丢失的因为有redo日志在磁盘文件里可以恢复你做的所有修改。
9.binlog到底是什么东西
实际上我们之前说的redo log他是一种偏向物理性质的重做日志因为他里面记录的是类似这样的东西“对哪个数据页中的什么记录做了个什么修改”。
而且redo log本身是属于InnoDB存储引擎特有的一个东西。而binlog叫做归档日志他里面记录的是偏向于逻辑性的日志类似于“对users表中的id1的一行数据做了更新操作更新以后的值是什么”binlog不是InnoDB存储引擎特有的日志文件是属于mysql server自己的日志文件。因此在提交事务的时候同时会写入binlog binlog日志的刷盘策略分析
对于binlog日志其实也有不同的刷盘策略有一个sync_binlog参数可以控制binlog的刷盘策略他的默认值是0此时你把binlog写入磁盘的时候其实不是直接进入磁盘文件而是进入os cache内存缓存。所以跟之前分析的一样如果此时机器宕机那么你在os cache里的binlog日志是会丢失的 如果要是把sync_binlog参数设置为1的话那么此时会强制在提交事务的时候把binlog直接写入到磁盘文件里去那么这样提交事务之后哪怕机器宕机磁盘上的binlog是不会丢失的。
基于binlog和redo log完成事务的提交
当我们把binlog写入磁盘文件之后接着就会完成最终的事务提交此时会把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置都写入到redo log日志文件里去同时在redo log日志文件里写入一个commit标记。在完成这个事情之后才算最终完成了事务的提交我们看下图的示意 最后一步redo日志中写入commit标记的意义是什么
用来保持redo log日志与binlog日志一致的必须是在redo log中写入最终的事务commit标记了然后此时事务提交成功而且redo log里有本次更新对应的日志binlog里也有本次更新对应的日志 redo log和binlog完全是一致的
后台IO线程随机将内存更新后的脏数据刷回磁盘
MySQL有一个后台的IO线程会在之后某个时间里随机的把内存buffer pool中的修改后的脏数据给刷回到磁盘上的数据文件里去我们看下图 在你IO线程把脏数据刷回磁盘之前哪怕mysql宕机崩溃也没关系因为重启之后会根据redo日志恢复之前提交事务做过的修改到内存里去然后等适当时机IO线程自然还是会把这个修改后的数据刷到磁盘上的数据文件里去的。
10.总结
InnoDB存储引擎主要就是包含了一些buffer pool、redo log buffer等内存里的缓存数据同时还包含了一些undo日志文件redo日志文件等东西同时mysql server自己还有binlog日志文件。
在你执行更新的时候每条SQL语句都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤但是当你提交事务的时候一定会把redo log刷入磁盘binlog刷入磁盘完成redo log中的事务commit标记最后后台的IO线程会随机的把buffer pool里的脏数据刷入磁盘里去。 总结
相信你如果掌握了上图上面所有的知识技能并且能够灵活的运用的话月薪20k以上并不会是什么问题 下方这份完整的软件测试视频学习教程已经整理上传完成朋友们如果需要可以自行免费领取 【保证100%免费】 这些资料对于【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴上万个测试工程师们走过最艰难的路程希望也能帮助到你 软件测试面试文档
我们学习必然是为了找到高薪的工作下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料并且有字节大佬给出了权威的解答刷完这一套面试资料相信大家都能找到满意的工作。 资料获取方式
这份文档和视频资料对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你以上均可以分享关注公众号一个心态巨好的朋友 扣 ‘1’ 即可自行领取。