存储管理(三):分区表

news2024/11/25 0:54:04

什么是分区表


假设存在表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版

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

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

相关文章

【Python】已解决:ModuleNotFoundError: No module named ‘sklearn‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:ModuleNotFoundError: No module named ‘sklearn‘ 一、分析问题背景 在进行机器学习项目时,Scikit-Learn(简称sklearn)是一…

MySQL的limit关键字和聚合函数讲解

目录 一、MySQL数据库介绍二、MySQL聚合函数三、MySQL数据排序分组四、MySQL的limit关键字 一、MySQL数据库介绍 MySQL是一种广泛使用的开源关系型数据库管理系统,由瑞典MySQL AB公司开发,后被Sun Microsystems收购,最终成为Oracle公司的一部…

Consul入门笔记

简介 Consul,HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul的方案更一站式,内置服务注册与发现框架、分布一致性协议实现、健康检查、K/V存储、多数据中心方案&…

地图初始化-多视图几何基础

在ORB-SLAM2中初始化和使用的传感器类型有关,其中单目相机模式初始化相对复杂,需要运行一段时间才能成功初始化。而双目相机、 RGB-D相机模式下比较简单,一般从第一帧开始就可以完成初始化。 为什么不同传感器类型初始化差别这么大呢&#x…

springboot宠物医院管理系统-计算机毕业设计源码07221

目 录 1 绪论 1.1 选题背景和意义 1.2国内外研究现状 1.3论文结构与章节安排 2 宠物医院管理系统系统分析 2.1 可行性分析 2.1.1技术可行性分析 2.1.2 操作可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分…

metasfresh开源ERP系统Windows开发环境配置参考

目录 概述 开发环境 配置过程 后端启动 前端启动 登陆系统 其他 概述 Compiere闭源之后衍生出了Admpiere等若干开源的产品,metasfresh就是其中之一,metasfresh截至发稿时在GitHub上已有64000多次的修改提交,而且仍在维护中&#xff0…

vue3-cropperjs图片裁剪工具-用户上传图片截取-(含预览视频)

效果图 上传图片弹窗预览 对于这个上传图片样式可以参考 官方原代码 官网传送入口 Upload 上传 | Element Plus (element-plus.org) <template><el-uploadclass"upload-demo"dragaction"https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6…

使用label-studio对OCR数据进行预标注

导读 label-studio作为一款数据标注工具相信大家都不陌生&#xff0c;对于需要进行web数据标注协同来说应该是必备工具了&#xff0c;标注的数据类型很全涉及AI的各个任务(图像、语音、NLP、视频等)&#xff0c;还支持自定义涉及模版。 然而&#xff0c;我们在标注数据的过程…

【简单讲解下Fine-tuning BERT,什么是Fine-tuning BERT?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

<Python><ffmpeg>基于python使用PyQt5构建GUI实例:音频格式转换程序(MP3/aac/wma/flac)(优化版2)

前言 本文是基于python语言使用pyqt5来构建的GUI,功能是使用ffmpeg来对音频文件进行格式转换,如mp3、aac、wma、flac等音乐格式。 UI示例: 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、ffmpeg 概述 本文是建立在之前的博文的基础上的优化版…

Linux多进程和多线程(二)-进程间通信-管道用法

进程间通信 关于多进程的通信管道无名管道(匿名管道)创建无名管道示例:创建子进程,父进程通过管道向子进程发送消息无名管道(匿名管道) 的特点 有名管道(命名管道) 创建有名管道需要调⽤ mkfifo() 函数示例:创建两个没有关联关系的进程,通过有名管道通信 注意: 缺点优点 关于判…

烧结刚玉砂轮片 磨具用晶谷低温陶瓷结合剂玻璃粉

晶谷CBN 砂轮磨具用低温陶瓷结合剂玻璃粉的一些特点如下&#xff1a; - 软化点&#xff1a;通常为450~650度&#xff1b; - 膨胀系数&#xff1a;50~12010-7&#xff1b; - 粒径&#xff1a;300~3000目&#xff08;可按要求订做&#xff09;&#xff1b; - 外观颜色&#xff…

6. 较全的Open3D点云数据处理(python)

注意&#xff1a;以下内容来自博客爆肝5万字❤️Open3D 点云数据处理基础&#xff08;Python版&#xff09;_python 点云 焊缝-CSDN博客&#xff0c;这篇博客写的全且详细&#xff0c;在这里是为了记笔记方便查看&#xff0c;并非抄袭。 1.点云的读写 代码如下&#xff1a; …

使用Perplexity打造产品的27种方式

ChatGPT和Perplexity等聊天机器人正迅速成为产品经理的首选助手。以下是一份全面的指南&#xff0c;介绍PM如何在日常工作中使用Perplexity&#xff0c;该指南基于300多份回复和30次电话后的总结。 理解并制定增长战略&#xff1a;例如&#xff0c;解释增长会计的基本原理&…

什么是 Elasticsearch 数据预热?

引言&#xff1a;在现代的信息检索和数据分析领域&#xff0c;Elasticsearch 已经成为一个广泛应用的分布式搜索和分析引擎。作为开源项目的一部分&#xff0c;Elasticsearch 提供了强大的实时搜索和分析能力&#xff0c;使得处理大规模数据变得更加高效和可靠。然而&#xff0…

MySQL高级-MVCC-undo log 版本链

文章目录 1、undo log2、undo log 版本链2.1、然后&#xff0c;有四个并发事务同时在访问这张表。2.1.1、修改id为30记录&#xff0c;age改为32.1.2、修改id为30记录&#xff0c;name改为A32.1.3、修改id为30记录&#xff0c;age改为10 2.2、总结 1、undo log 回滚日志&#xf…

运行vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

报错背景: 重装了win10系统,然后准备安装Vue,这个时候我已经安装好了node.js和npm,输入node -v和npm -v都有正确输出,但是每次输入npm install -g vue/cli 安装的时候,就会报错. 大家安装node.js的时候最好就是默认路径(C:\Program Files\nodejs),别去修改不然很多报错.(个人…

Ubuntu网络管理命令:netstat

安装Ubuntu桌面系统&#xff08;虚拟机&#xff09;_虚拟机安装ubuntu桌面版-CSDN博客 顾名思义&#xff0c;netstat命令不是用来配置网络的&#xff0c;而是用来查看各种网络信息的&#xff0c;包括网络连接、路由表以及网络接口的各种统计数据等。 netstat命令的基本语法如…

3-linux命令行与基本命令

目录 什么是shell linux命令 命令组成 几个简单的命令 linux文件系统导航 什么是shell linux学习路径&#xff1a;学习shell→配置和环境→见任务和主要工具→编写shell脚本 shell是一个接收由键盘输入的命令&#xff0c;并将其传递给操作系统来执行的程序。几乎所有…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 03

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econom…