MySQL之高级特性(三)

news2024/11/26 23:48:09

高级特性

分布式(XA)事务

存储引擎的事务特性能够保证在存储引擎级别实现ACID,而分布式事务则让存储引擎级别的ACID可以扩展到数据库层面,甚至可以扩展到多个数据库之间——这需要通过两阶段提交实现。MySQL5.0和更新版本的数据库已经开始支持XA事务了。XA事务中需要有一个事务协调器来保证所有的事务参与者都完成了准备工作(第一阶段)。如果协调器受到所有的参与者都准备好的消息,就会告诉所有的事务可以提交了,这时第二阶段。MySQL在这个XA事务过程中扮演一个参与者的角色,而不是协调者。实际上,在MySQL中有两种XA事务。一方面,MySQL可以参与到外部的分布式事务中;另一方面,还可以通过XA事务来协调存储引擎和二进制日志。

内部XA事务

MySQL本身的插件式架构导致在其内部需要使用XA事务。MySQL中各个存储引擎是完全独立的,彼此不知道对方的存在,所以一个跨存储引擎的事务就需要一个外部的协调者,如果不使用XA协议,例如,跨存储引擎的事务提交就只是顺序地要求每个存储引擎各自提交。如果在某个存储提交过程中发生系统崩溃,就会破坏事务的特性(要么全部提交,要么就不做任何操作)如果将MySQL记录的二进制日志操作看作一个独立的"存储引擎",就不难理解为什么即使是一个存储引擎参与的事务仍然需要XA事务了。在存储引擎提交的同时,需要将"提交"的信息写入二进制日志,这就是一个分布式事务,只不过二进制日志的参与者是MySQL本身。XA事务为MySQL带来巨大的性能下降。从MySQL5.0开始,它破坏了MySQL内部的"批量提交"()一种通过单磁盘IO操作完成多个事务提交的技术),使得MySQL不得不进行多次额外的fsync()调用。具体的,一个事务如果开启了二进制日志,则不仅需要对二进制日志进行持久化操作,InnoDB事务日志还需要两次日志持久化操作。换句话说,如果希望有二进制日志安全的事务实现,则至少需要做三次fsync()操作。唯一避免这个问题的办法就是关闭二进制日志,并将innodb_support_xa设置为0.(一个常见的误区是认为innodb_support_xa只有在需要XA事务的时候才需要打开。这是醋无的:该参数还会控制MySQL内部存储引擎和二进制日志之间的分布式事务。如果你真正关心你的数据,你需要将这个参数打开)。
但这样的设置是非常不安全的,而且这回导致MySQL赋值也没法正常工作。复制需要二进制日志和XA事务的支持,另外——如果希望数据尽可能安全——最好还要将sync_binlog设置成1, 这时存储引擎和二进制日志才是真正同步的(否则,XA事务支持就没有意义了,因为事务提交了二进制日志却可能没有"提交"到磁盘)。这也是为什么强烈建议使用带电池保护的RAID卡写缓存:这个缓存可以大大加快fsync()操作的效率

外部XA事务

MySQL能够作为参与者完成一个外部的分布式事务。但它对XA协议支持并不完整。例如XA协议要求在一个事务中的多个连接可以做关联,但目前的MysQL版本还不能支持。因为通信延迟和参与者本身可能失败,所以外部XA事务比内部消耗会更大。如果在广域网中使用XA事务,通常会因为不可预测的网络性能导致事务失败。如果有太多不可控因素,例如,不稳定的网络通信或者用户长时间等待而不提交,则最好避免使用XA事务。任何可能让事务提交发生延迟的操作代价都很大,因为它影响的不仅仅是自己本身,它还会让所有参与者都在等待。
通常,还可以使用别的方式实现高性能的分布式事务。例如,可以在本地写入数据,并将其放入队列,然后在一个更小、更快的事务中自动分发。还可以使用MySQL本身的复制机制来发送数据。我们看到很多应用程序都可以完全彼岸使用分布式事务。也就是说,XA事务是一种在多个服务器之间同步的方法。如果由于某些原因不能使用MySQL本身的复制,或者性能并不是瓶颈的时候,可以尝试使用。

查询缓存

很多数据库产品都能够缓存查询的执行计划,对于相同类型的SQL就可以跳过SQL解析和执行计划生成阶段。MySQL在某些场景下也可以实现,但是MySQL还有另一种不同的缓存类型:缓存完整的SELECT查询结果,也就是"查询缓存"。
MySQL查询缓存保存查询返回的完整结果。当查询命中该缓存,MySQL会立刻返回结果,跳过了解析、优化和执行解读那。查询缓存系统会跟踪查询中涉及的每个表,如果这些表发生变化,那么和这个表相关的所有的缓存数据都将失效。这种机制效率看起来比较低,因为数据表变化时很有可能对应的查询结果并没有变更,但是这种简单实现代价很小,而这点对于一个非常繁忙的系统来说非常重要。
查询缓存对应用程序是完全透明的。应用程序无须关心MySQL是通过查询缓存返回的结果还是实际执行返回的结果。事实上,这两种方式执行的结果是完全相同的。换句话说,查询缓存无须使用任何语法。无论是MySQL开启或关闭查询缓存,对应用程序都是透明的。(有一种方式查询缓存可能和原生的SQL工作方式有所不同:默认的,当要查询的表被LOCK TABLES锁住时,查询仍然可以通过查询缓存返回数据。你可以通过参数query_cache_wlock_invaidate打开或者关闭这种行为)。随者现在的通用服务器越来越强大,查询缓存被发现是一个影响服务器扩展性的因素。他可能成为整个服务器的资源竞争单点,在多核服务器上还可能导致服务器僵死。后面再详细介绍如何配合查询缓存,但是很多时候我们还是认为应该默认关闭查询缓存,如果查询缓存作用很大的话,那就配置一个很小的查询缓存空间(如几十兆)。后面再解释如何判断再系统压力下打开查询缓存是否有好处。

MySQL如何判断缓存命中

MySQL判断缓存命中的办法很简单:缓存放在一个引用表,通过一个哈希值引用,整个哈希值包括了如下因素,即查询本身、当前要查询的数据库、客户端协议的版本等一些其他可能会影响返回结果的信息。当判断缓存是否命中时,MySQL不会解析、"正规化"或者参数化查询语句,而是直接使用SQL语句和客户端发送过来的其他原始信息。任何字符上的不同,例如空格、注释——任何的不同——都会导致缓存的不命中。(对于这个规则,Percona Server是个例外。它会先将所有的注释语句删除,然后再比较查询语句是否有缓存。这是一个通用的需求,这样可以在查询语句中带入更多的处理过程信息)。所以在编写SQL语句的时候,需要特别注意这点。通常使用统一的编码规则是一个好的习惯,在这里这个好习惯会让你系统运行得更快。当查询语句中有一些不确定的数据时,则不会被缓存。例如包含函数NOW()或者CURRENT_DATE()的查询不会被缓存。类似的,包含CURRENT_USER或者CONNECTION_ID()的查询语句因为会根据不同的用户返回不同的结果,所以也不会被缓存。事实上,如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql库中的系统表,或者任何包含列级别权限的表,都不会被缓存。
我们常听到:“如果查询中包含一个不确定的函数,MySQL则不会检查查询缓存”。这个说法是不正确的。因为在检查查询缓存的时候,还没有解析SQL语句,所以MySQL并不知道查询语句中是否包含这类函数。在检查查询缓存之前,MySQL只做一件事情,就是通过一个大小写不敏感的检查看看SQL语句是不是以SEL开头。准确的说法应该是:“如果查询语句中包含任何的不确定函数,那么在查询缓存中是不可能找到缓存结果的”。因为即使之前刚刚执行了这样的查询,结果也不会放在查询缓存中。MySQL在任何时候只要发现不能被缓存的部分,就会禁止这个查询被缓存。所以,如果希望换成一个带日期的查询,那么最好将日期提前计算好,而不是直接使用函数。例如:

... DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY) -- Not cacheable!
... DATE_SUB('2007-07-14', INTERVAL 1 DAY) -- Cacheable

因为查询缓存是在完整的SELECT语句基础上的,而且只是在刚刚受到SQL语句的时候才检查,所以子查询和存储过程都没办法使用查询缓存。在MySQL5.1之前的版本中,绑定变量也无法使用查询缓存。MySQL的查询缓存在狠毒哦时候可以提升查询性能,在使用的时候,有一些问题需要特别注意。手下你打开查询缓存对读和写操作都会带来额外的消耗:

  • 1.读查询在开始之前必须先检查是否命中缓存
  • 2.如果这个读查询可以被缓存,那么当完成执行后,MSQL若发现查询缓存中没有这个查询,会将其结果存入查询缓存,这回带来额外的系统消耗
  • 3.这对写操作也会有影响,因为当向这某个表写入数据的时候,MySQL必须将对应表的所有缓存都设置失效。如果查询缓存非常大或者碎片很多,这个操作就可能带来很大系统消耗(设置了很多的内存给查询缓存用的时候).
    虽然如此,查询缓存仍然可能给系统带来性能提升。但是,如上所述,这些额外的消耗也可能不断增加,再加上对查询缓存操作是一个加锁排他操作,这个消耗可能不容小觑。对InnoDB用户来说,事务的一些特性会限制查询缓存的使用。当一个语句再事务中修改了某个表,MySQL会将这个表对应的查询缓存都设置失效,而事实上,InnoDB的多版本特性会暂时将这个修改对其他事务屏蔽。在这个事务提交之前,这个表的相关查询是无法被缓存的,所以所有在这个表上的查询——内部或外部的事务——都只能在该事务提交后才能被缓存。因此,长事件运行的事务,会大大降低查询缓存的命中率。
    如果查询缓存使用了很大量鞥多内存,缓存失效操作就可能成为一个非常严重的问题瓶颈。如果缓存中存放了大量的查询结果,那么缓存失效操作时整个系统都可能会僵死一会儿。因为这个操作是靠一个全局锁操作保护的,所有需要做该操作的查询都要等待这个锁,而且无论是检测是否命中缓存、还是缓存失效检测都需要等待这个全局锁。

查询缓存如何使用内存

查询缓存是完全存储在内存中的,所以在配置和使用它之前,我们需要先了解它是如何使用内存的。除了查询结果之外,需要缓存的还有很多别的维护相关的数据。这和文件系统有些类似:需要一些内存专门用来确定哪些内存目前是可用的、哪些是已经用掉的、哪些用来存储数据表和查询结果之前的映射、哪些用来存储查询字符串和查询结果。这些基本的管理维护数据结构大需要需要40KB的内存资源,除此之外,MySQL用于查询缓存的内存被分成一个个的数据块,数据块是变长的。每一个数据块中,存储了自己的类型、大小和存储的数据本身,还外加指向前一个和后一个数据块的指针。数据块的类型有:存储查询结果、存储查询和数据表的映射、存储查询文本,等等。不同的存储快,在内存使用上并没有什么不同,从用户角度来看无须区分它们。当服务器启动的时候,它先初始化查询缓存需要的内存。这个内存池初始是一个完整的空闲块。这个空闲块的大小就是你所配置的查询缓存大小再减去用于维护元数据的数据结构所消耗的空间。当有查询结果需要缓存的时候,MySQL先从大的空间块中申请一个数据块用于存储结果。这个数据块需要大于参数query_cache_min_res_unit的配置,即使查询结果远远小于此,仍需要至少申请query_cache_min_res_unit空间。因为需要在查询开始返回结果的时候就分配空间,而此时是无法预知查询结果到底多大的,所以MySQL无法为每一个查询结果精确分配大小恰好匹配的缓存空间。
因为需要先锁住空间块,然后找到合适大小数据块,所以相对来说,分配内存块是一个非常慢的操作。MySQL尽量避免这个操作的次数。当需要缓存一个查询结果的时候,它先选择一个尽可能小的内存块(也可能选择较大的),然后将结果存入其中。如果数据块全部用完,但仍有剩余数据需要存储,那么MySQL会申请一块新数据块——仍然是尽可能小的数据块——继续存储结果数据。当查询完成时,如果申请的内存空间还有剩余,MySQL会将其释放,并放入空闲内存部分。该过程如图所示。在这里插入图片描述

我们上面说的"分配内存块",并不是指通过函数malloc()向操作系统申请内存,这个操作只在初次创建查询缓存的时候执行一次。这里"分配内存块"是指在空闲块列表中找到一个合适的内存块,或者从正在使用的、待淘汰的内存块中回收再使用。也就是说这里MySQL自己管理一大块内存,而不依赖操作系统的内存管理。至此,一些都看起来很简单。不过实际情况要比上图更复杂。例如,我们假设平均查询结果非常小,服务器在并发地向不同的两个连接返回结果,返回完结果MySQL回收剩余数据块空间时发现,回收的数据块小于query_cache_min_res_unit,所以不能够直接在后续的内存块分配中使用。如果考虑到这种情况,数据块的分配就更复杂些,如图所示。在这里插入图片描述
在收缩第一个查询结果使用的缓存空间时,就会在第二个查询结果之间留下一个"空隙"——一个非常小的空闲空间,因为小于query_cache_min_res_unit而不能再次被查询缓存使用。这类"空隙"我们成为碎片,这在内存管理、文件系统管理上都是经典问题。有很多种情况都会导致碎片,例如缓存失效时,可能导致留下太小的数据块无法在后续缓存中管使用

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

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

相关文章

时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解

时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab…

vue-2 组件传值

组件关系分类 父子关系非父子关系 父子通信流程 父组件通过props将数据传递给子组件 给子组件以添加属性的方式传值子组件内部通过 props 接收模板中直接使用 props 接收的值 父组件 Parent.vue <template><div class"parent" style"border: 3px s…

全网首发-Docker被封后的代理设置教程

最近上交、科大以及阿里的一些docker镜像&#xff0c;好像都因为不可控力导致无法访问。 所以&#xff0c;之前好多正常的一些镜像的打包都会报错&#xff1a; 比如&#xff1a; #1 [internall load build definition from Dockerfile#1transferring dockerfile:972B done#1 D…

Day 13:3072. 将元素分配到两个数组中 Ⅱ

Leetcode 3072. 将元素分配到两个数组中 Ⅱ 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount &#xff0c;使得 greaterCount(arr, val) 返回数组 arr 中** 严格大于** val 的元素数量。 你需要使用 n 次操作&#xff0c;将 nums 的所有元素分配到…

一种基于混合协作的约束多目标优化的新型多群体进化算法

A novel multi-population evolutionary algorithm based on hybrid collaboration for constrained multi-objective optimization 原文链接: https://doi.org/10.1016/j.swevo.2024.101581 Wang Q, Li Y, Hou Z, et al. A novel multi-population evolutionary algorithm bas…

网络编程(一)基本概念、TCP协议

文章目录 一、概念&#xff08;一&#xff09;网络发展阶段1. ARPAnet阶段2. TCP/IP两个协议阶段3. 网络体系结构和OSI开放系统互联模型4. TCP/IP协议簇体系结构&#xff08;1&#xff09; 应用层&#xff1a;&#xff08;2&#xff09;传输层&#xff1a;&#xff08;3&#x…

集成算法实验(Bagging策略)

Bagging模型(随机森林) Bagging&#xff1a;训练多个分类器取平均 f ( x ) 1 / M ∑ m 1 M f m ( x ) f(x)1/M\sum^M_{m1}{f_m(x)} f(x)1/M∑m1M​fm​(x) 全称&#xff1a; bootstrap aggregation&#xff08;说白了就是并行训练一堆分类器&#xff09; 最典型的代表就是随…

聚鼎科技:装饰画哪里好卖

在当代社会&#xff0c;艺术与商业的界限日益模糊&#xff0c;装饰画作为一种既能美化空间又能体现个人品味的物品&#xff0c;受到了广泛的欢迎。但许多创作者和商家常常面临一个问题&#xff1a;《装饰画哪里好卖》? 要解决这个问题&#xff0c;我们需明白市场需求的重要性。…

斜率优化详解

斜率优化 [HNOI2008] 玩具装箱 状态转移方程&#xff1a; f i m i n ( f i , f j ( s u m i i − s u m j − j − L ) 2 ) i > j f_imin(f_i,f_j(sum_ii-sum_j-j-L)^2){i>j} fi​min(fi​,fj​(sumi​i−sumj​−j−L)2)i>j 设A为 s u m i i sum_ii sumi​i&…

代码随想录算法训练营第36天(py)| 贪心 | 452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间

452. 用最少数量的箭引爆气球 力扣链接 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同…

【kubernetes】k8s集群安全机制 保姆级攻略

目录 一、认证&#xff08;Authentication&#xff09; Kubernetes 作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介&#xff0c; 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 A…

CCNA 0基础入门

OSI & TCP/IP OSI参考模型 TCP/IP协议 应用层 ------↓表示层 ------>应用层会话层 ------↑传输层 ------>传输层网络层 ------>网络互联层链路层 ------>网络接口层物理层 ------>↑ 物理层 传输的信号以及网线以及接线 主要作用是产生并检测电…

怎么修改Visual Studio Code中现在github账号

git config --global user.name “你的用户名” git config --global user.email “你的邮箱” git config --global --list git push -u origin your_branch_name git remote add origin

手部出现这4种症状,可能是糖尿病先兆!务必及时监测血糖

糖尿病来袭&#xff0c;手部或先知&#xff01;出现这 4 种症状&#xff0c;务必尽快监测血糖 第一&#xff0c;手指麻木感明显&#xff0c;当持续性的高血糖损害手部血管与神经末梢时&#xff0c;便会导致手指产生麻木以及刺痛之感。而且随着血糖不断升高&#xff0c;受损的血…

【QT Creator软件】解决中文乱码问题

QT Creator软件解决中文乱码问题 问题描述&#xff1a;Qtcreator安装好后打印中文在控制台输出乱码 在网上也查找了修改编辑器的默认编码为UTF-8&#xff0c;但是仍然没有任何作用&#xff0c;于是有了以下的解决方案 原因剖析&#xff1a;因为项目的编码与控制台的编码不一致…

Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件

打包与运行 window版本上制作 我们要把idea中的程序抽取出来作为一个独立的jar包 把jar包放到服务器上 服务器是长期运行的 我们就能随时访问了 在Maven的生命周期中选择package 打包功能 在资源管理器中查找 java -jar 文件名.jar java -jar 文件名.jar 但是我们在测试…

kotlin 中的字符串

一、字符类访问 1、字符串的访问跟js一样&#xff0c;可以使用索引来访问或者直接循环。 fun main() {val a: String "2024"// 方式一&#xff1a;for (item in a) {println(item) // 输出每一个字符}// 方式二&#xff1a;println("${a[0]}, ${a[1]}, ${a[2…

纯干货科普!水浸传感器品牌该怎么选?

在现代化生产过程中&#xff0c;漏水是常见的安全隐患之一。特别是机房、档案馆等高精密设备较多的场合&#xff0c;一旦没有及时解决漏水问题&#xff0c;就有可能导致线路故障、设备损坏甚至业务办理。绝大部分管理人员会选择安装水浸传感器&#xff0c;它能够帮我们及时检测…

bugku---misc---easy_nbt

1、题目描述 2、下载附件&#xff0c;解压之后得到 3、查找资料发现&#xff1a;NBT文件是Minecraft游戏数据文件&#xff0c;其中包含以命名二进制标签(NBT)格式保存的数据。这种格式用于存储大量二进制数据&#xff0c;通常包含有关Minecraft世界的信息。NBT数据通常以.dat文…

2024 全球软件研发技术大会官宣,50+专家共话软件智能新范式!

2024年的全球软件研发技术大会&#xff08;SDCon&#xff09;由CSDN和高端IT咨询与教育平台Boolan联合主办&#xff0c;将于7月4日至5日在北京威斯汀酒店举行。本次大会的主题为“大模型驱动软件智能化新范式”&#xff0c;旨在探讨大模型和开源技术的发展如何引领全球软件研发…