mysql新增列并同时增加数据_图解MySQL | [原理解析] MySQL 为表添加列 是怎么quot;立刻quot;完成的...

在上一期图解 图解MySQL | MySQL DDL为什么成本高?中,我们介绍了:

  • 传统情况下,为表添加列需要对表进行重建

  • 腾讯团队为 MySQL 引入了 Instant Add Column 的方案(以下称为 "立刻加列" 功能)可以快速完成 为表添加列 的任务

同时我们留了以下思考题:

  • "立刻加列" 是如何工作的 ?

  • 所谓 "立刻加列" 是否完全不影响业务,是否是真正的 "立刻" 完成 ?

本期我们针对这几个问题来进行讨论:

传统情况

我们先回顾一下,在没有 "立刻加列" 功能时,加列操作是怎么完成的。我们也借此来熟悉一下本期的图例:

86ccc9255a83454a8d5a2c11195ddb24.png

  • 当进行 加列操作 时,所有的数据行 都必须要 增加一段数据(图中的 列 4 数据)

  • 如上一期图解所讲,当改变数据行的长度,就需要 重建表空间(图中灰蓝的部分为发生变更的部分)

  • 数据字典中的列定义也会被更新

以上操作的问题在于 每次加列 操作都需要重建表空间,这就需要大量 IO以及大量的时间


立刻加列

"立刻加列" 的过程如下图:

6aafa72bb6a7335d0c5cc7a8944d8f88.png

  • "立刻加列" 时,只会变更数据字典中的内容,包括:

    • 列定义中增加 新列的定义

    • 增加 新列的默认值

  • "立刻加列" 后,当要读取表中的数据时:

    • 由于 "立刻加列" 没有 变更行数据,读取的行数据只有 3 列

    • MySQL 会将 新增的第 4 列的默认值,追加到 读取的数据后

以上过程描述了 如何读取 在 "立刻加列" 之前写入的数据,其实质是:在读取数据的过程中,"伪造了一个新列出来

那么如何读取 在 "立刻加列" 之后 写入的数据呢 ? 过程如下图:

660ec61b63f41e6d4ddb9ba0e5812bdf.png

当读取 行 4 时:

  • 通过判断 数据行的头信息中的instant 标志位,可以知道该行的格式是 "新格式":该行头信息后有一个新字段 "列数"

  • 通过读取 数据行的 "列数" 字段,可以知道 该行数据中多少列有 "真实" 的数据,从而按列数读取数据

通过上图可以看到:读取 在"立刻加列" 前/后写入的数据是不同的流程

通过以上的讨论,我们可以总结 "立刻加列" 之所以高效的原因是:

  1. 在执行 "立刻加列" 时,不变更数据行的结构

  2. 读取 "旧" 数据时,"伪造" 新增的列,使结果正确

  3. 写入 "新" 数据时,使用了新的数据格式(增加了instant标志位 和 "列数" 字段),以区分新旧数据

  4. 读取 "新" 数据时,可以如实读取数据

那么 我们是否能一直 "伪造" 下去 ? "伪造" 何时会被拆穿 ?

考虑以下场景:

  1. 用 "立刻加列" 增加列 A

  2. 写入数据行 1

  3. 用 "立刻加列" 增加列 B

  4. 写入数据行 2

  5. 删除列 B

我们推测一下 "删除列 B" 的最小代价:需要修改 数据行中的instant标志位或 "列数" 字段,这至少会影响到 "立刻加列" 之后写入的数据行,成本类似于重建数据

从以上推测可知:当出现 与 "立刻加列" 操作不兼容 的 DDL 操作时,数据表需要进行重建如下图所示:

edfad06bff4bafe2e897d84db0341fd7.png

扩展思考题:是否能设计其他的数据格式,取代instant标志位和 "列数" 字段,使得 加列/删列 操作都能 "立刻完成" ?(提示:考虑 加列 - 删列 - 再加列 的情况)


使用限制

在了解原理之后,我们来看看 "立刻加列" 的使用限制,就很容易能理解其中的前两项:

  1. "立刻加列" 的加列位置只能在表的最后,而不能加在其他列之间在元数据中,只记录了 数据行 应有多少列,而没有记录 这些列 应出现的位置。所以无法实现指定列的位置

  2. "立刻加列" 不能添加主键列加列 不能涉及聚簇索引的变更,否则就变成了 "重建" 操作,不是 "立刻" 完成了

  3. "立刻加列"不支持压缩的表格式
    按照 WL 的说法:"COMPRESSED is no need to supported"(没必要支持不怎么用的格式)

总结回顾

我们总结一下上面的讨论:

  1. "立刻加列" 之所以高效的原因是:

    1. 在执行 "立刻加列" 时,不变更数据行的结构

    2. 读取 "旧" 数据时,"伪造" 新增的列,使结果正确

    3. 写入 "新" 数据时,使用了新的数据格式 (增加了 instant 标志位 和 "列数" 字段),以区分新旧数据

    4. 读取 "新" 数据时,可以如实读取数据

  2. "立刻加列" 的 "伪造" 手法,不能一直维持下去。当发生 与 "立刻加列" 操作不兼容 的 DDL 时,表数据就会发生重建

回到之前遗留的两个问题:

  • "立刻加列" 是如何工作的 ?

    我们已经解答了这个问题

  • 所谓 "立刻加列" 是否完全不影响业务,是否是真正的 "立刻" 完成 ?

    可以看到:就算是 "立刻加列",也需要变更 数据字典,那么 该上的锁还是逃不掉的。也就是说 这里的 "立刻" 指的是 "不变更数据行的结构",而并非指 "零成本地完成任务"

本期仍然留下一个思考题:

  • 本文中描述了 在 "立刻加列" 之后 插入 数据行的情况 (数据行会使用新格式)。那么在 "立刻加列" 之后 更新 数据行会发生什么情况呢 ?


5c600241952e3f5f9bbf9a0f499a6675.png图解MySQL原理

图解MySQL | MySQL DDL为什么成本高?

图解MySQL | [原理解析] XtraBackup增量备份还原

[原理解析] XtraBackup全量备份还原

[原理解析] MySQL使用固定的server_id导致数据丢失

[原理解析] MySQL组提交(group commit)

[原理解析] 设置字符集的参数控制了哪些行为

1916a6e3c8ecd2c7382f01228cae2cd0.gif

近期社区动态

第三期 社区技术内容征稿?

所有稿件,一经采用,均会为作者署名。

征稿主题:MySQL、分布式中间件DBLE、数据传输组件DTLE相关的技术内容

活动时间:2019年6月11日 - 7月11日

本期投稿奖励

投稿成功:京东卡200元*1

优秀稿件:京东卡200元*1+社区定制周边(包含:定制文化衫、定制伞、鼠标垫)

优秀稿件评选,文章获得“好看数量排名前三的稿件为本期优秀稿件。

09fa8fc94ca4c67beb884868309bdece.pngf4e2ea96874d4251fd6afc01102970fc.gif

喜欢点分享”,不行就看”

7a28ead373b833841eac2c442415feeb.gif

多喝热水,重启试试

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

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

相关文章

GCC for Win32开发环境介绍

GCC for Win32开发环境介绍(1) 第一章 在视窗操作系统下的GCC 第一节GCC家族概览 GCC是一个原本用于Unix-like系统下编程的编译器。不过,现在GCC也有了许多Win32下的移植版本。所以,也许对于许多Windows开发者来说,GCC还是一个比较陌生的东西…

包装函数

function wrap(object,method,wrapper){ //object:包装方法所属对象 method:方法名 wrapper:替换函数var fn object[method];return object[method] function(){return wrapper.apply(this,[fn.bind(this)].concat(Array.prototype.slice.call(arguments)));}; } 转载于…

JAR——pinyin4j-2.5.0

简介:将中文转为拼音; 使用: 123//返回的是字符串String pinyin[] PinyinHelper.toHanyuPinyinStringArray(chinese);//eg:你----ni3本文转自wauoen51CTO博客,原文链接:http://blog.51cto.com/7183397/1605894&#…

Android高效加载大图、多图解决方案,有效避免程序OOM

http://blog.csdn.net/guolin_blog/article/details/9316683转载于:https://www.cnblogs.com/jianglijs/p/7827524.html

Flask 上下文源码解析

简单来说,上下文包括request_ctx(封装了request和session),app_request(封装了app和g),两个ctx都储存在一个叫做Local的数据结构中,这个结构的作用就是会自动根据不同的线程id返回对应的数据,然后通过一个叫做 LocalStark 的结构把…

reg型变量怎么赋值_UiPath变量介绍和使用

1 变量变量主要用于存储数据,它在RPA中扮演重要的数据传递角色,是RPA编程不可或缺的一部分。它包括变量名称和变量的值,变量的值支持多种数据类型,包括从通用值,文本,数字,数据表,时…

gcc 使用教程

gcc 使用教程 目 录 gcc makefile写法 gcc_egcs使用 gdb使用 gcc常用选项对代码的影响 一般情况 -O 编译选项 -O2 编译选项 -fomit-frame-pointer 编译选项-fomit-frame-pointer && -O2-fPIC 编译选项 -static 编译选项 AT&T的汇编格式 x86内联汇编 简述 内联汇编…

Struts2教程9:实现自已的拦截器

在上一篇中介绍了Struts2拦截器的原理,在这一篇中我们将学习一下如何编写自己的拦截器。一、拦截器的实现实现一个拦截器非常简单。实际上,一个拦截器就是一个普通的类,只是这个类必须实现com.opensymphony.xwork2.interceptor.Interceptor接…

标准C程序设计七---66

Linux应用 编程深入 语言编程标准C程序设计七---经典C11程序设计 以下内容为阅读: 《标准C程序设计》(第7版) 作者:E. Balagurusamy(印), 李周芳译 清华大学出版社…

深度学习之概述

深度学习的应用场景 1、图像应用: 1.1 大规模(大数据量)图片识别(聚类/分类),如人脸识别,车牌识别,OCR等。人脸识别算法:① faceID ② faceNet 1.2 以图搜图,图像分割 1.3 目标检测&#xff0…

如何根据对象获取到对应的表名_Excel VBA 常用对象二

下面继续讲解上一节中未讲完的内容:Excel VBA编程中常常使用的那些对象到底是什么,如何在代码中表示它们。Worksheet对象Worksheet对象代表工作表。工作簿中的每个工作表都是一个Worksheet对象,所有Worksheet对象构成了Worksheets集合。我们使…

PIX525故障一例,求解

IDC机房网络拓朴如下:IDC核心交换机-----通过一条网线-------机柜D-LNKI交换机------PIX 525------CISCO交换机------各WEB服务器。其中D-LINK交换机的IP为192.168.2.11,也就是下面日志中的IP。另外,之所以IDC和PIX之间再加一台DLINK是因为有…

gcc教程(转)

gcc 目 录 gcc makefile写法 gcc_egcs使用 gdb使用 gcc常用选项对代码的影响 一般情况 -O 编译选项 -O2 编译选项 -fomit-frame-pointer 编译选项 -fomit-frame-pointer && -O2 -fPIC 编译选项 -static 编译选项 AT&T的汇编格式 x86内联汇编 简述 内联汇编 程序模…

深度学习之 BP 算法

神经网络的一种求解W的算法,分为信号“正向传播(FP)”求损失,“反向传播(BP)”回传误差;根据误差值修改每层的权重,继续迭代。 BP算法也叫做δ算法。以三层的感知器为例(假定现在隐层和输出层均存在相同类型的激活函数…

python自带的解释器叫做_python学习

一、PYTHON中的元素1.基本元素运算符: - * / %等等除法:" / " 表示浮点数除法,返回浮点结果;" // " 表示整数除法,返回不大于结果的一个最大的整数运算顺序:先乘除 再加减 括号最优先变量:就是一…

IE打印空白

今天碰到HR经理碰到一个问题,就是windows 7 64位操作系统,但是打印空白,打印出来像白纸一样!经过查看和总结,确认是:由于保护模式下 %Temp%\Low 文件夹工作不正常引起的!故障打印白纸下面会出现…

Python Matplotlib.plot Update image Questions

1. 最近在测试一款设备,采集了一些设备后需要一帧一帧显示图像,经常使用Python,所以选用了Matplotlib进行图像操作 数据结构: timesatamp polar_distance horizontal_angle refelectivity_intensity,所有数据类型都是 float,储存在…

深度学习之 RBF神经网络

RBF神经网络通常只有三层,即输入层、中间层和输出层。其中中间层主要计算输入x和样本矢量c(记忆样本)之间的欧式距离的Radial Basis Function (RBF)的值,输出层对其做一个线性的组合。 径向基函数: RBF神经网络的训练…

redis 队列_Redis与Rabbitmq消息队列的区别

将redis发布订阅模式用做消息队列和rabbitmq的区别:可靠性 redis :没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中;rabbit…

EasyUI中那些不容易被发现的坑——EasyUI重复请求2次的问题

问题控件:datagrid、combobox、所有能设置url属性的控件 问题版本:1.4.4、1.4.5(之前的版本没测) 问题如图: 重复请求2次,错误代码如图: 错误问题分析:html加载的时候回请求url加载数…