针对sql中出现的一些问题,需要从架构的角度去分析和思考,有时候,也需要多从架构的角度去设计表的具体配置,优化数据库表的使用性能
SQL的基础架构图
总体上看,mysql可以分为服务层和存储引擎层两个部分
服务层:
主要包含连接器,查询缓存,分析器,优化器,执行器几个主要部分。包含了所有的主要功能,包含了跨存储引擎的数据库的功能。
存储引擎层
存储引擎层的架构模式是插件式的,主要负责数据的存储和提取。支持innodb,myisam等多个存储引擎。默认使用的存储引擎是innodb。从mysql5.5.5版本的开始就成为mysql的默认引擎。
服务层内容详解
连接器
连接器主要用于mysql客户端与mysql服务器进行连接。一般连接分为长连接和短连接两种形式。
长连接:一般是指连接完成后,客户端有持续的请求,则一直使用同一个连接。
短链接:一般是指连接完成后,只执行几个简单的请求就断开。
建立连接的过程,需要经历tcp协议沟通,是个比较复杂的过程,我们一般尽量减少建立连接的次数。所以我们在与数据库交互的时候,尽量使用长连接。
问题:内存管理是在数据库连接当中的,这些资源会在数据库断开连接的时候进行释放。如果长期使用长连接,可能导致内存太大,被系统清理。
解决方案:在经历一个比较占用内存的操作后,可以考虑主动断开长连接,或者设置mysql_reset_connection重新初始化连接资源。
关于一些思考:目前好像很多项目使用连接池,来与mysql进行连接的管理,可以关注一下项目连接池里与长连接,短连接的作用
查询缓存
当一条查询语句进入时,会去缓存中直接匹配结果,如果存在结果会直接返回。
但是使用缓存时弊大于利,因为每当数据库表发生变化或者更新时,都会使缓存失效。除非是很少更新的,长期作为配置的内容才适合使用。
mysql8以后会禁止使用本配置。
查询本配置的方法为:
select @@query_cache_type;
刚才自查了下负责的相关信息的配置,测试环境下本配置是关闭的,说明公司的前辈们也是认同本处的小配置的,所以后续对数据的处理,默认跳过查询缓存这个步骤。
分析器和优化器
确认是否符合mysql的语法,确认具体使用哪些缓存,优化查询路径。
执行器
调用存储引擎的接口,根据情况去存储引擎中获取数据。 在有索引的情况会优先查询索引所对应的数据内容,仅在小范围遍历查询。如果说没有索引依据,那么会大范围的遍历数据库表,直到完成所有的数据库操作。
小结:
数据缓存部分可以认为是关闭的。对于服务层相关的核心过程还是连接的建立,分析器,优化器,执行器这几个部分。在项目中,应该注意与mysql建立的连接的形式。如果说短连接,多关注资源的消耗,如果是长连接,关注mysql的内存。有时间,针对自己所管理项目中,连接池上如何处理的也进行一遍总结。
日志模块的介绍
与简单的查询语句不同,更新模式还设计到数据库中的两个日志模块。redolog(重做日志)和binlog(归档日志)。
redolog 重做日志模块
数据库在操作的过程中,存在内存空间与磁盘空间的差别。我们在执行操作中,如果内存空间有记录数据,那么直接获取的是内存空间的数据,如果内存空间不存在相关数据,会把磁盘中的数据读取到内存空间中去,再在内存空间做处理。
实际表现:当我们更新一条数据的时候,innodb引擎会先把数据记录在重做日志中,再把内存进行更新后,就算更新完成了。innodb引擎会在合适的时间,把这次更新记录到磁盘中,更新磁盘信息。
有了redolog,innodb引擎就可以做到,当mysql崩溃重启后,数据库数据依旧是最新的,因为所有的数据更新都通过了redolog完成了日志记录,重启时,服务器会自动更新。 - 这个能力叫做 crash-safe
binlog 归档日志模块
由于redolog日志是innodb引擎独有的,但是mysql本身也需要完成归档的日志,所以mysql的服务器存在binlog日志,用于归档记录所有的mysql操作。
binlog与redolog的核心区别:
redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
举例一个对数据库的更新过程。
update from test set `id` = `id` + 1 where `id` = 2;
步骤:
- 执行器找引擎拿id=2这一行数据。引擎侧按照内存-磁盘的顺序去获取当前这一行的数据。并将结果返回给执行器。
- 执行器根据数据,得到新数据,并调用引擎的接口去更新数据。
- 引擎将本次更新记录到内存中,同时将更新操作记录在redolog中,此时redolog处于prepare状态。
- 执行器生成这个操作的binlog,并记录在磁盘空间中
- 执行期提交事务,引擎将刚才的redolog更新为commit状态。
通过上述的操作,运维人员可以通过备份的数据库系统与binlog日志,将数据库回退到过去一段时间的任意时间状态,作为数据库紧急情况的处理。
配置内容:
innodb_flush_log_at_trx_commit 本参数为1的时候,可以保证每个commit的内容的redolog都存储在磁盘中,确保crash-safe的生效。
sync_binlog 本参数为1的时候,可以保证每个commit的内容的binlog日志都记录到磁盘中,确保每次mysql重启时的binlog日志不丢失。