存储管理(三):分区表

什么是分区表


假设存在表t:

CREATETABLE `t` (
  `ftime`datetime NOT NULL,
  `c` int(11) DEFAULT NULL,
  KEY (`ftime`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(ftime))
(PARTITION p_2017 VALUES LESS THAN (2017) ENGINE = InnoDB,
 PARTITION p_2018 VALUES LESS THAN (2018) ENGINE = InnoDB,
 PARTITION p_2019 VALUES LESS THAN (2019) ENGINE = InnoDB,
 PARTITION p_others VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
insert into t values('2017-4-1',1),('2018-4-1',1);

表对应磁盘文件:

我在表t中初始化插入了两行记录, 按照定义的分区规则, 这两行记录分别落在p_2018和p_2019这两个分区上。

从图中可以看到,这个表包含了一个.frm文件和4个.ibd文件,每个分区对应一个.ibd文件。也就是说:

  1. 对于引擎层来说, 这是4个表。
  2. 对于Server层来说, 这是1个表。

注:分区表是由server层定义的,而非引擎层。

分区表的引擎层行为


序列示例,在分区表加间隙锁,目的是说明对于InnoDB来说,这是4个表。

初始化表t的时候, 只插入了两行数据, ftime的值分别是, ‘2017-4-1’ 和’2018-4-1’ 。

InnoDB引擎层行为

session A的select语句对索引ftime上这两个记录之间的间隙加了锁。 如果是一个普通表的话,那么T1时刻, 在表t的ftime索引上, 间隙和加锁状态如图:

也就是说, ‘2017-4-1’ 和’2018-4-1’ 这两个记录之间的间隙是会被锁住的。 那么, sesion B的两条插入语句应该都要进入锁等待状态。

但是, 从上面的实验效果可以看出, session B的第一个insert语句是可以执行成功的。

这是因为, 对于引擎来说, p_2018和p_2019是两个不同的表, 也就是说2017-4-1的下一个记录并不是2018-4-1, 而是p_2018分区的supremum(上界)。 所以T1时刻, 在表t的ftime索引上, 间隙和加锁的状态如下:

由于分区表的规则, session A的select语句其实只操作了分区p_2018, 因此加锁范围就是图中深绿色的部分。

sesson B加锁信息(show engine innodb status):

总结:单个分区加锁,不影响其它分区。

MyISAM引擎层行为

先用alter table t engine=myisam, 把表t改成MyISAM表。

然后, 我再用下面这个例子说明, 对于MyISAM引擎来说, 这是4个表。

在session A里面, 我用sleep(100)将这条语句的执行时间设置为100秒。 由于MyISAM引擎只支持表锁, 所以这条update语句会锁住整个表t上的读。

问1:从上图执行结果看,session B的第一条查询语句是可以正常执行的, 第二条语句才进入锁等待状态。是什么原因?

答:这是因为MyISAM的表锁是在引擎层实现的,session A加表锁,其实是所在分区p_2018上。因此,只会堵住在这个分区上的查询,落到其它分区的查询是不受影响的。

使用分区表的一个重要原因就是单表过大。那么,如果不使用分区表的话,就需要使用手动分表的方式。

问2:手动分表和分区表有什么区别?

  1. 分区表:在server层看来是一张表,由server层来决定使用哪个分区。
  2. 手工分区表:在server层看来是多张表,由应用层代码来决定使用哪个分区表。
  3. 从引擎层来看,这两种方式并没有差别。

问3:手动分表和分区表对MDL加锁行为的影响?

  1. 分区表:分区表加MDL锁时,针对所有分区。
  2. 手工分表加MDL锁时,仅针对一个分表。

分区策略


每当第一次访问一个分区表时,MySQL需要把所有的分区都访问一遍。

一个典型的报错:如果一个分区表的分区很多,比如超过了1000个,而MySQL启动时,open_files_limit参数使用的是默认值1024, 那么就会在访问这个表的时候, 由于需要打开所有的文件, 导致打开表文件的个数超过了上限而报错。

示例:创建一个包含了很多分区的表t_myisam,执行一条插入语句后报错:

insert语句只需要访问一个分区,但语句却无法执行。

注:该表使用的是MyISAM引擎,如果使用InnoDB引擎并不会出现上述错误。

问:为什么MyISAM分区表会报错,而InnoDB表不会报错?

答:因为open_files_limit参数限制的是MySQL server层打开句柄数,而MyISAM分区表是由server层控制的,InnoDB分区表是由引擎层控制的。

通用分区策略

MyISAM分区表使用的分区策略, 我们称为通用分区策略(generic partitioning),每次访问分区都由server层控制。

正是由于MyISAM分区表的打开是由server层控制的,所以当MyISAM分区表数量过多时,才会导致上述错误。

通用分区策略, 是MySQL一开始支持分区表的时候就存在的代码, 在文件管理、 表管理的实现上很粗糙, 因此有比较严重的性能问题。

本地分区策略

从MySQL 5.7.9开始, InnoDB引擎引入了本地分区策略(native partitioning) 。

这个策略是在InnoDB内部自己管理打开分区的行为。

MySQL从5.7.17开始, 将MyISAM分区表标记为即将弃用(deprecated),意思是“从这个版本开始不建议这么使用, 请使用替代方案。 在将来的版本中会废弃这个功能”。

从MySQL 8.0版本开始, 就不允许创建MyISAM分区表了, 只允许创建已经实现了本地分区策略的引擎。 目前来看, 只有InnoDB和NDB这两个引擎支持了本地分区策略。

问: open_files_limit参数和innodb_open_files参数的区别?

  1. open_files_limit限制MySQL打开句柄数(server层),在server层打开文件超过 open_files_limit这个值的时候,就会报错。
  2. innodb_open_files限制InnoDB打开句柄数,在InnoDB引擎打开文件超过 innodb_open_files这个值的时候,就会关掉一些之前打开的文件。

分区表的server层行为


如果从server层看的话, 一个分区表就只是一个表。

示例序列:

show processlist结果:

可以看到, 虽然session B只需要操作p_2107这个分区, 但是由于session A持有整个表t的MDL锁, 就导致了session B的alter语句被堵住。

总结:

  1. MySQL在第一次打开分区表时,需要访问所有分区。
  2. 在server层,一个分区表被认为是一个表,因此所有分区共用一个MDL锁。
  3. 在引擎层,分区表被认为是不同的表,因此MDL锁之后的执行过程,会根据分区表规则,只访问必要的分区。

注1:而关于“必要的分区”的判断, 就是根据SQL语句中的where条件, 结合分区规则来实现的。 比如:where ftime=‘2018-4-1’, 根据分区规则year函数算出来的值是2018, 那么就会落在p_2019这个分区。(具体内容见:分区表的引擎层行为)

注2:如果这个where 条件改成 where ftime>=‘2018-4-1’, 虽然查询结果相同, 但是这时候根据where条件, 就要访问p_2019和p_others这两个分区。

分区表的应用场景


  1. 分区表的优点:
    1. 使用简单,对业务透明。
    2. 方便清理数据,例如:通过命令alter table t drop partition ...清理分区数据。该命令直接删除分区数据文件,类似drop普通表,相比于delete速度更快,影响更小。
  2. 分区表缺点:
    1. 第一次访问,需要打开所有分区,可能占用很多文件句柄。
    2. 多个分区共用MDL锁,性能上可能不及手工分表。
  3. 适用场景:存放历史数据,并需要定时归档清理。

小结:思考题


小结:

  1. 分区表并非越细越好,一般数据量小于2000时,不建议使用分区表。
  2. 分区表不宜一开始建立过多分区,可以通过自动化脚本动态维护少量可用分区即可。
  3. 分区表的目标更多是提高可维护性,而非性能。

思考:举例的表中没有用到自增主键, 假设现在要创建一个自增字段id。 MySQL要求分区表中的主键必须包含分区字段。 如果要在表t的基础上做修改, 你会怎么定义这个表的主键呢? 为什么这么定义呢?

答:由于MySQL要求主键包含分区字段,所以肯定是要创建联合主键。

两种选择:一种是(ftime, id), 另一种是(id, ftime)。

  1. 因为ftime做分区key,说明大多数语句都是包含ftime的,使用这种模式,可以利用前缀索引规则,减少一个索引。
  2. 建议尽量使用InnoDB引擎。InnoDB表要求至少有一个索引,以自增字段作为第一个字段,所以需要加一个id的单独字段。

建表语句如下:

CREATETABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ftime`datetime NOT NULL,
  `c` int(11) DEFAULT NULL,
  PRIMARY KEY (`ftime`,`id`),
  KEY `id` (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(ftime))
(PARTITION p_2017 VALUES LESS THAN (2017) ENGINE = InnoDB,
 PARTITION p_2018 VALUES LESS THAN (2018)ENGINE = InnoDB,
 PARTITION p_2019 VALUES LESS THAN (2019)ENGINE = InnoDB,
 PARTITION p_others VALUES LESS THAN MAXVALUE ENGINE = InnoDB);

有关分区表的使用请参考:MySQL技术内幕InnoDB存储引擎第2版

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

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

相关文章

Vue.js 和 Node.js 全栈项目的运行与部署指南

Vue.js 和 Node.js 全栈项目的运行与部署指南 前言具体运行方式导入数据库初始化安装配置nodejs启动server后端启动client前端确保前后端正确连接 前言 本博客用来介绍一下一个包含前端和后端代码的全栈项目MoreMall,前端部分使用了 Vue.js,后端部分使用…

UE5蓝图快速实现打开网页与加群

蓝图节点:启动URL 直接将对应的网址输入,并使用即可快速打开对应的网页,qq、discord等群聊的加入也可以直接通过该节点来完成。 使用后会直接打开浏览器。

填报志愿时,要结合个人的优势和擅长

每年高考后的填报志愿,总会令很多家长和考生感到头痛,尤其是在选择学校专业的时候总是模棱两可,不知道应该如何入手。其实,在填报志愿的时候可以考虑结合考生擅长的科目择优选择专业。 大学的专业课程其实和高中课程是有一定关联…

Java代码高风险弱点与修复之——弱密码哈希漏洞-Very weak password hashing (WEAK_PASSWORD_HASH)

弱密码哈希漏洞 弱密码哈希漏洞指的是在密码存储和验证过程中,由于使用了不安全的哈希算法或哈希函数的错误使用,导致攻击者能够更容易地破解或绕过密码验证机制。这种漏洞使得存储在系统或应用中的用户密码容易受到威胁,增加了账户被非法访问和数据泄露的风险。 常见的弱…

SpringCloud中Eureka和Nacos的区别和各自的优点

Eureka注册中心 Eureka作为一个注册中心,服务提供者把服务注册到注册中心,服务消费者去注册中心拉取信息, 然后通过负载均衡得到对应的服务器去访问。 服务提供者每隔30s向注册中心发送请求,报告自己的状态,当超过一定…

找不到d3dcompiler_43.dll无法继续执行的修复指南

在电脑使用过程中,我们可能会遇到一些错误提示,其中之一就是“缺失d3dcompiler43.dll”。那么,这个错误提示到底是怎么回事呢?小编将从常见原因、对电脑的影响以及解决方法等方面进行详细解析。 一,了解d3dcompiler_43…

【子串】3. 无重复的最长子串

3. 无重复的最长子串 难度:中等难度 力扣地址:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/ 题目看起来简单,刷起来有好几个坑,特此记录一下,解法比官网的更加简单&…

【Sklearn-驯化】一文搞懂机器学习树模型建模可视化过程

【Sklearn-驯化】一文搞懂机器学习树模型建模可视化过程 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 免费获取相关内容文档关注&#xff…

研导智能科技——AI辅助科研产品开发

人工智能(AI)技术的飞速发展为科研领域带来了革命性的变化。本公司致力于开发基于人工智能的科研辅助产品,旨在通过智能化手段提高科研人员的工作效率和研究质量。目前,我们成功开发了研导学术平台(www.zhiyanxueshu.c…

Docker Compose 入门

想象一下在服务器上运行静态页面的场景。对于这项任务,NGINX 服务器是一个不错的选择。我们在 static-site/index.html 路径下有一个简单的 HTML 文件: 通过使用 Docker,我们将使用以下官方镜像运行 NGINX 服务器 docker run --rm -p 8080:…

Day6: 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字

题目344. 反转字符串 - 力扣&#xff08;LeetCode&#xff09; void reverseString(vector<char>& s) {int len s.size();int left 0;int right len - 1;while (left < right){swap(s[left], s[right--]);}return;} 题目541. 反转字符串 II - 力扣&#xff0…

教您设置打开IDM下载浮动条的快捷键 全网最强下载神器idm怎么使用教程 idm浮动条不显示怎么办

很多人都知道Internet Download Manager(以下简称IDM)是一款非常优秀的下载提速软件。它功能强大&#xff0c;几乎能下载网页中的所有数据&#xff08;包括视频、音频、图片等&#xff09;&#xff0c;且适用于现在市面上几乎所有的浏览器&#xff0c;非常受大家欢迎。 在使用I…

docker网络功能介绍

一、 网络启动过程二、 修改容器dns和主机名① 临时处理&#xff08;容器终止或重启后不会保存&#xff09;② 通过参数指定 三、 容器内访问控制① 容器访问外部网络② 容器间互相访问&#xff08;1&#xff09;访问所有端口&#xff08;2&#xff09;访问指定端口 四、 docke…

Bureau of Contacts联机卡顿、联机延迟高的三种有效解决办法

Bureau of Contacts是一款全新的驱鬼游戏&#xff0c;最多支持4名玩家同时联机探索&#xff0c;玩家将进入被诅咒的地点&#xff0c;在这里找到被黑暗隐藏的秘密&#xff0c;并了解其消灭的办法&#xff0c;清除一切超自然内容&#xff0c;最终成功存活。不过有玩家反馈&#x…

2024最出色的代理软件评估及推荐

随着网络技术的飞速发展&#xff0c;代理软件已成为许多网络活动不可或缺的工具&#xff0c;特别是在数据抓取、网络安全防护等方面。在众多代理软件中&#xff0c;哪些能真正满足用户需求&#xff0c;提供卓越的性能和服务呢&#xff1f;我们的测评团队经过深入研究和测试&…

AutoHotKey自动热键(一)下载与安装

首先讲一下这个软件有什么作用,它可以实现代替鼠标和键盘的操作,并且能够代录入文字,添加并改变组合快捷键等等,到后面我们慢慢来讲AHK软件有1版本和2版本,在实际使用中,2版本容易被报毒,并且1版本已经极致成熟,所以我们使用1版本,我们进入官网下载下来,软件本身是免费的,不用有…

学习笔记——动态路由——OSPF(OSPF状态机、DR\BDR选举)

七、OSPF状态机、DR\BDR选举 1、OSPF的8种状态机 OSPF在邻居与邻接建立的过程中会经过多个状态机的变化&#xff0c;状态机的出现不仅能让我们了解OSPF建立过程&#xff0c;也能在OSPF出现故障的时候通过状态机的状态来粗略判断问题的所在。 (1)邻居建立状态变化过程 1、Dow…

狼人杀系列

目录 杀人游戏&#xff08;天黑请闭眼&#xff09; &#xff08;1&#xff09;入门版 &#xff08;2&#xff09;标准版 &#xff08;3&#xff09;延伸版——百度百科 &#xff08;3.1&#xff09;引入医生和秘密警察 &#xff08;3.2&#xff09;引入狙击手、森林老人和…

Excel+vue+java实现批量处理功能

需求背景: 产品创建流程比较复杂&#xff0c;有时候需要一次性创建多至10个&#xff0c;所以做了Excel维护产品信息&#xff0c;直接导入创建的功能。能极大提高效率。 简要概括实现&#xff1a; 一、参考单个创建&#xff0c;设计创建模板&#xff0c;表头对应填写字段名&…

CC1利用链分析

分析版本 Commons Collections 3.1 JDK 8u65 环境配置参考JAVA安全初探(三):CC1链全分析 分析过程 我的Github主页Java反序列化学习同步更新&#xff0c;有简单的利用链图 首先看下CC1利用链的RCE利用点&#xff0c;在接口Transformer 接下来查看此接口的实现类&#xf…