MySQL之高级特性(三)

高级特性

分布式(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而不能再次被查询缓存使用。这类"空隙"我们成为碎片,这在内存管理、文件系统管理上都是经典问题。有很多种情况都会导致碎片,例如缓存失效时,可能导致留下太小的数据块无法在后续缓存中管使用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3d交互式场景在线编辑平台的好处

在数字化教学的新时代,我们为您带来了革命性的产品——VR全景展示搭建编辑器。它将传统的教学方式升级为三维模式,让课程训练更加真实生动,为您带来前所未有的学习体验。 VR全景展示搭建编辑器不仅支持视频录播、PDF、图文等多种内容承载方式…

数据采集项目1-用户行为数据同步

环境准备 linux配置、克隆103和104、编写集群分发脚本、ssh无密码登录配置、jdk安装、数据模拟集群日志数据输出脚本、xcall脚本、安装hadoop、zk安装、kafka安装、flume安装、mysql安装、maxwell安装、datax安装、hive安装 用户行为数据同步-总的数据流程图 第一层flume 数据…

VS2022 使用C++访问 mariadb 数据库

首先,下载 MariaDB Connector/C++ 库 MariaDB Products & Tools Downloads | MariaDB 第二步,安装后 第三步,写代码 #include <iostream> #include <cstring> #include <memory> #include <windows.h>#include <mariadb/conncpp.hpp>…

C#——析构函数详情

析构函数 C# 中的析构函数&#xff08;也被称作“终结器”&#xff09;同样是类中的一个特殊成员函数&#xff0c;主要用于在垃圾回收器回收类实例时执行一些必要的清理操作。 析构函数: 当一个对象被释放的时候执行 C# 中的析构函数具有以下特点&#xff1a; * 析构函数只…

CID引流电商下的3C产品选品策略深度解析

​摘要&#xff1a;随着电商行业的迅猛发展和消费者需求的日益多样化&#xff0c;CID引流电商作为一种新兴的电商模式&#xff0c;逐渐受到了广泛关注。在这一模式下&#xff0c;3C产品作为高客单价、高技术含量的代表品类&#xff0c;其选品策略的制定显得尤为重要。本文将从多…

调用百度API实现图像多主体检测

目录 1. 作者介绍2&#xff0e;百度API介绍与获取2.1 API介绍2.2 注册账号并获取API Key 3&#xff0e;完整实验代码&#xff0c;测试结果3.1 调用API3.2框出主体部分&#xff0c;并标注标签和置信度3.3 测试结果 1. 作者介绍 邓富贵&#xff0c;男&#xff0c;西安工程大学电…

基于YOLO检测算法(单检测器网络+多视频输入)设计与实现

在单摄像头目标检测的基础上&#xff0c;实现单网络多线程的实时目标检测。 1&#xff0c;应用场景 在安防领域&#xff0c;YOLO的多摄像头实时目标检测应用具有以下特点和优势&#xff1a; 实时性能&#xff1a; YOLO算法以非常高的速度运行&#xff0c;能够实现实时目标检测…

threejs开发之 测量工具

基于threejs做三维开发已经有几年了&#xff0c;经常会遇到写一下通用的工具&#xff0c;比如测量工具。 测量工具很有意思&#xff0c;估计大家认为这个不是很容易写吗&#xff0c;就是几个事件&#xff0c;然后绘制点线面&#xff0c;然后用three计算长度&#xff0c;展示出来…

力扣752. 打开转盘锁

Problem: 752. 打开转盘锁 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.用一个集合 deads 存储所有的“死锁”状态&#xff0c;一个集合 visited 存储所有已经访问过的状态&#xff0c;以避免重复访问&#xff0c;一个队列 q 进行广度优先搜索&#xff08;BF…

出现“由于找不到msvcr120.dll,无法继继续执行代码”提示的问题处理方法

本文章针对出现“由于找不到msvcr120.dll,无法继续执行代码”的问题进行深入剖析&#xff0c;并提供了两种有效的解决方案&#xff0c;方便大家能快速恢复正常工作状态。 一.关于msvcr120.dll文件部分介绍 “由于找不到msvcr120.dll,无法继续执行代码”常发生在我们打开一个软…

毕业了!给学计算机朋友的 10 条血泪建议

大家好&#xff0c;我是程序员鱼皮。最近高考结束了&#xff0c;也有很多同学毕业了&#xff0c;首先祝福这些朋友在人生的新阶段一帆风顺。 刚参加完高考的朋友&#xff0c;面临的最大问题就是选专业&#xff0c;这段时间也有一些家长向我咨询&#xff1a;还能不能选计算机啦…

flutter开发实战-RichText富文本居中对齐

flutter开发实战-RichText富文本居中对齐 在开发过程中&#xff0c;经常会使用到RichText&#xff0c;当使用RichText时候&#xff0c;不同文本字体大小默认没有居中对齐。这里记录一下设置过程。 一、使用RichText 我这里使用RichText设置不同字体大小的文本 Container(de…

考研计组chap3存储系统

目录 一、存储器的基本概念 80 1.按照层次结构 2.按照各种分类 &#xff08;41&#xff09;存储介质 &#xff08;2&#xff09;存取方式 &#xff08;3&#xff09;内存是否可更改 &#xff08;4&#xff09;信息的可保存性 &#xff08;5&#xff09;读出之后data是否…

如何在国产深度发行版Linux上部署ONLYOFFICE协作空间社区版?

如何在国产深度发行版Linux上部署ONLYOFFICE协作空间社区版&#xff1f; 书接上文&#xff1a; ONLYOFFICE 协作空间服务器如何一键安装自托管私有化部署 讲的是如何把ONLYOFFICE协作空间服务器部署到自托管云服务器VPS上面&#xff0c;这里继续&#xff0c;在自己Windows电…

StarRocks详解

什么是StarRocks&#xff1f; StarRocks是新一代极速全场景MPP数据库&#xff08;高并发数据库&#xff09;。 StarRocks充分吸收关系型OLAP数据库和分布式存储系统在大数据时代的优秀研究成果。 1.可以在Spark和Flink里面处理数据&#xff0c;然后将处理完的数据写到StarRo…

SQL入门到入土索引优化,聚合函数,数据备份与恢复,事务处理,查询、更新、插入和删除数据库

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

pdf书签怎么做?这三款软件轻松驾驭文档!

在数字化时代&#xff0c;PDF文件已成为我们工作、学习中的重要组成部分。然而&#xff0c;面对海量的PDF内容&#xff0c;如何快速定位关键信息&#xff0c;提高阅读效率呢&#xff1f;答案就是——制作PDF书签。今天&#xff0c;我将为大家介绍三款实用的软件&#xff0c;助你…

Ubuntu 的 apt 相关问题

错误:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal InRelease Couldnt create temporary file /tmp/apt.conf.KSeTlI for passing config to apt-key 原因 无法创建配置文件 /tmp/apt.conf.KSeTlI 并传递给 apt-key apt-key 等实际上并不是直接使…

失眠焦虑的解脱之道:找回内心的平静

&#x1f343; 在这个快节奏的时代&#xff0c;失眠与焦虑似乎成了许多人的隐形敌人。每当夜幕降临&#xff0c;它们便悄悄潜入心底&#xff0c;扰乱我们的思绪&#xff0c;让宁静的夜晚变得无比漫长。然而&#xff0c;生活总有办法让我们找回内心的平静&#xff0c;只需稍作调…

0613#111. 构造二阶行列式

时间限制&#xff1a;1.000S 空间限制&#xff1a;256MB 题目描述 小欧希望你构造一个二阶行列式&#xff0c;满足行列式中每个数均为不超过 20 的正整数&#xff0c;且行列式的值恰好等于x。你能帮帮她吗? 输入描述 一个正整数x。-1000 < x < 1000 输出描述 如果…