位置: 编程技术 - 正文

MySQL下使用Inplace和Online方式创建索引的教程(mysql in())

编辑:rootadmin

推荐整理分享MySQL下使用Inplace和Online方式创建索引的教程(mysql in()),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:mysql in的使用,mysql语句in的用法,mysql使用replace,mysql inodb,mysql inodb,mysql语句in的用法,mysql语句in的用法,mysql in的使用,内容如对您有帮助,希望把文章链接给更多的朋友!

MySQL各版本,对于add Index的处理方式是不同的,主要有三种:

(1)Copy Table方式这是InnoDB最早支持的创建索引的方式。顾名思义,创建索引是通过临时表拷贝的方式实现的。

新建一个带有新索引的临时表,将原表数据全部拷贝到临时表,然后Rename,完成创建索引的操作。

这个方式创建索引,创建过程中,原表是可读的。但是会消耗一倍的存储空间。

(2)Inplace方式这是原生MySQL 5.5,以及innodb_plugin中提供的创建索引的方式。所谓Inplace,也就是索引创建在原表上直接进行,不会拷贝临时表。相对于Copy Table方式,这是一个进步。

Inplace方式创建索引,创建过程中,原表同样可读的,但是不可写。

(3)Online方式这是MySQL 5.6.7中提供的创建索引的方式。无论是Copy Table方式,还是Inplace方式,创建索引的过程中,原表只能允许读取,不可写。对应用有较大的限制,因此MySQL最新版本中,InnoDB支持了所谓的Online方式创建索引。

InnoDB的Online Add Index,首先是Inplace方式创建索引,无需使用临时表。在遍历聚簇索引,收集记录并插入到新索引的过程中,原表记录可修改。而修改的记录保存在Row Log中。当聚簇索引遍历完毕,并全部插入到新索引之后,重放Row Log中的记录修改,使得新索引与聚簇索引记录达到一致状态。

与Copy Table方式相比,Online Add Index采用的是Inplace方式,无需Copy Table,减少了空间开销;与此同时,Online Add Index只有在重放Row Log最后一个Block时锁表,减少了锁表的时间。

与Inplace方式相比,Online Add Index吸收了Inplace方式的优势,却减少了锁表的时间。

1.Inplace add Index

测试表

Inplace Add Index处理流程SQL

处理流程

Inplace Add Index实现分析在索引创建完成之后,MySQL Server立即可以使用新建的索引,做查询。但是,根据以上流程,对我个人来说,有三个疑问点:

索引数据字典上,为何需要维护一个trx_id?trx_id有何作用?

遍历聚簇索引读取所有记录时,为何可跳过删除项?只读取非删除项,那么新建索引上没有版本信息,无法处理原有事务的快照读;

MySQL Server层,为何需要等待打开表的只读事务提交?等待当前表上的只读事务,可以保证这些事务不会使用到新建索引

根据分析,等待打开表的只读事务结束较好理解。因为新索引上没有版本信息,若这些事务使用新的索引,将会读不到正确的版本记录。

那么InnoDB是如何处理其他那些在创建索引之前已经开始,但却一直未提交的老事务呢?这些事务,由于前期为并未读取当前表,因此不会被等待结束。这些事务在RR隔离级别下,会读取不到正确的版本记录,因为使用的索引上并没有版本信息。

当然,InnoDB同样考虑到了此问题,并采用了一种比较简介的处理方案。在索引上维护一个trx_id,标识创建此索引的事务ID。若有一个比这个事务更老的事务,打算使用新建的索引进行快照读,那么直接报错。

考虑如下的并发处理流程(事务隔离级别为RR):

当session 1执行最后一条select时,MySQL Optimizer会选择idx_t1_b索引进行查询,但是索引上并没有b = 1的项,使用此索引会导致查询出错。那么,InnoDB是如何处理这个情况的呢?

处理流程:

MySQL Server收到InnoDB返回的错误之后,会将错误报给用户,用户会收到以下错误:

2.Online add Index

测试表

Online Add Index处理流程SQL

处理流程

Online Add Index实现分析在看完前面分析的InnoDB 5.6.7-RC版本中实现的基本处理流程之后,个人仍旧遗留了几个问题,主要的问题有:

MySQL下使用Inplace和Online方式创建索引的教程(mysql in())

Online Add Index是否支持Unique索引?

确切的答案是:支持(不过存在Bug,后面分析)。InnoDB支持Online创建Unique索引。

既然支持,就会面临Check Duplicate Key的问题。Row Log中如果存在与索引中相同的键值怎么处理?怎么检测是否存在相同键值?

InnoDB解决此问题的方案也比较简介易懂。其维护了一个row_merge_dup_t的数据结构,存储了在Row log重放过程中遇到的违反唯一性冲突的Row Log。应用完Row Log之后,外部判断是否存在Unique冲突(有多少Unique冲突,均会记录),Online创建Unique索引失败。

Row Log是什么样的结构,如何组织的?

在Online Add Index过程中,并发DML产生的修改,被记录在Row Log中。首先,Row Log不是InnoDB的Redo Log,而是每个正在被Online创建的索引的独占结构。

Online创建索引,遵循的是先创建索引数据字典,后填充数据的方式。因此,当索引数据字典创建成功之后,新的DML操作就可以读取此索引,尝试进行更新。但是,由于索引结构上的status状态为ONLINE_INDEX_CREATION,因此这些更新不能直接应用到新索引上,而是放入Row Log之中,等待被重放到索引之上。

Row Log中,以Block的方式管理DML操作内容的存放。一个Block的大小为由参数innodb_sort_buffer_size控制,默认大小为1M ()。初始化阶段,Row Log申请两个这样的Block。

在Row Log重放的过程中,到底需要多久的锁表时间?

前面的流程分析中,也提到了锁表的问题(内部为锁新建索引树的操作实现)。

在重放Row log时,有两个情况下,需要锁表:

情况一:在使用完一个Block,跳转到下一个Block时,需要短暂锁表,判断下一个Block是否为Row Log的最后一个Block。若不是最后一个,跳转完毕后,释放锁;使用Block内的row log不加锁,用户DML操作仍旧可以进行。

情况二:在使用最后一个Block时,会一直持有锁。此时不允许新的DML操作。保证最后一个Block重放完成之后,新索引与聚簇索引记录达到一致状态。

综上分析两个锁表情况,情况二会持续锁表,但是由于也只是最后一个Block,因此锁表时间也较短,只会短暂的影响用户操作,在低峰期,这个影响是可以接受的。

3. Online Add Index是否也存在与Inplace方式一样的限制?

由于Online Add Index同时也是Inplace方式的,因此Online方式也存在着Inplace方式所存在的问题:新索引上缺乏版本信息,因此无法为老事务提供快照读。

不仅如此,相对于Inplace方式,Online方式的约束更甚一筹,不仅所有小于创建此Index的事务不可使用新索引,同时,所有在新索引创建过程中开始的事务,也不能使用新索引。

这个增强的限制,在rowmerge.cc::row_merge_read_clustered_index()函数中调整,在聚簇索引遍历完成之后,将新索引的trx_id,赋值为Online Row Log中最大的事务ID。待索引创建完成之后,所有小于此事务ID的事务,均不可使用新索引。

在遍历聚簇索引读取数据时,读取的是记录的最新版本,那么此记录是否在Row Log也会存在?InnoDB如何处理这种情况?

首先,答案是肯定的。遍历聚簇索引读取记录最新版本时,这些记录有可能是新事务修改/插入的。这些记录在遍历阶段,已经被应用到新索引上,于此同时,这些记录的操作,也被记录到Row Log之中,出现了一条记录在新索引上存在,在Row Log中也存在的情况。

当然,InnoDB已经考虑到了这个问题。在重放Row Log的过程中,对于Row Log中的每条记录,首先会判断其在新索引中是否已经存在(row0log.c::row_log_apply_op_low()),若存在,则当前Row Log可以跳过(或者是将操作类型转换)。

例如:Row Log中记录的是一个INSERT操作,若此INSERT记录在新索引中已经存在,那么Row Log中的记录,可以直接丢弃(若存在项与INSERT项完全一致);或者是将INSERT转换为UPDATE操作(Row Log记录与新索引中的记录,部分索引列有不同);

Online Add Index是否存在Bug?

答案同样是肯定的,存在Bug。

其中有一个Bug,重现方案如下:

在以上的测试中,首先为表准备足够的数据,目的是session 1做Online Add Index的读取聚簇索引阶段,session 2新的记录也能够被读到。

在session 1的Online Add Index完成之后(成功),执行以下两个命令,结果如下:

可以看到,b上已经有了一个Unique索引,但是表中却存在两个相同的取值为的值。

此Bug,是处理Row Log的重放过程,未详尽考虑所有情况导致的。因此,在MySQL 5.6版本稳定之前,慎用!

Online Add Index可借鉴之处在MySQL 5.6.7中学习到两个文件操作函数:一是posix_fadvise()函数,指定POSIX_FADV_DONTNEED参数,可做到读写不Cache:Improving Linux performance by preserving Buffer Cache State unbuffered I/O in Linux;二是fallocate()函数,指定FALLOC_FL_PUNCH_HOLE参数,可做到读时清空:Linux Programmer's Manual FALLOCATE(2) 有类似需求的朋友,可试用。

posix_fadvise函数+POSIX_FADV_DONTNEED参数,主要功能就是丢弃文件在Cache中的clean blocks。因此,若用户不希望一个文件占用过多的文件系统Cache,可以定期的调用fdatasync(),然后接着posix_fadvise(POSIX_FADV_DONTNEED),清空文件在Cache中的clean blocks,不错的功能!

MySQL中InnoDB存储引擎的锁的基本使用教程 MyISAM和MEMORY采用表级锁(table-levellocking)BDB采用页面锁(page-levelocking)或表级锁,默认为页面锁InnoDB支持行级锁(row-levellocking)和表级锁,默认为行级

MySQL中二进制与重做日志文件的基本概念学习教程 二进制日志二进制日志记录了所有对数据库执行更改的操作,二进制主要有以下两种作用:1、恢复(recovery)2、复制(replication)二进制日志的启动:

讲解Linux系统下如何自动备份MySQL数据的基本教程 1.先创建一个数据库备份目录:mkdirbackupcdbackupmkdirmysqlbackupcdmysqlbackup2.创建备份脚本vimysqlautobackup3.编写脚本:filename=`date+%Y%m%d`/mysql的bin目录/mysqldump--opt

标签: mysql in()

本文链接地址:https://www.jiuchutong.com/biancheng/312372.html 转载请保留说明!

上一篇:MySQL中使用or、in与union all在查询命令下的效率对比(MySQL中使用_____语句更新表中的数据)

下一篇:MySQL中InnoDB存储引擎的锁的基本使用教程(mysql innodb存储结构)

  • 已交税金是什么类
  • 出租人融资租赁发生的初始直接费用
  • 售后维修收入怎么入账
  • 个体户4年不注销的后果消
  • 一般纳税人建筑工程税率是多少
  • 购买原材料记账凭证怎么写
  • 存款利息收入增值税是免税还是不征税
  • 购买电商平台
  • 企业租赁个人房屋怎么交税
  • 采购货款属于什么会计科目
  • 职工集资建房款属公款吗
  • 个人应纳税所得额怎么算
  • 最新出口退税申报流程
  • 增值税扣完税款还能更改吗
  • 小企业盈余公积弥补亏损分录
  • 商铺租金收入交什么税一共多少个点
  • 发票红冲退税是全额退吗
  • 三证合一号码是纳税人识别号吗
  • 小规模季度超过30万怎么填报增值税
  • 支付教育培训费
  • 支付工程款不得超60天
  • 光伏发电项目发电户是否可以享受小规模优惠政策
  • 资产减值损失怎么影响利润
  • 文件类型错误请重新选择
  • linux命令执行成功后会返回什么
  • 基金收益率
  • 请问王者荣耀是谁发明的
  • u深度u盘启动盘制作工具官网
  • 拍卖获得收入个税
  • 查补税款有未缴纳怎么办
  • SCHDPL32.EXE - SCHDPL32是什么进程 有什么用
  • 捐赠与赞助
  • php多维数组遍历输出
  • 物业费开增值税专用发票
  • 小企业会计准则2023电子版
  • 【GoF 23】23种设计模式与OOP七大原则概述
  • 学python真的好就业吗
  • php如何定义二维数组
  • 财务制度备案信息是不是可以不填
  • 哪些企业不需要做安评
  • 增值税专票只有右上角有发票号码
  • druid数据库连接池
  • linux lab安装
  • dedecms使用教程
  • 通货膨胀率怎么求
  • 固定资产清理科目有余额吗
  • 企业设立账簿
  • 投资款要不要交企业所得税?
  • 个人独资公司对外如何承担责任
  • 加计扣除适用于什么企业
  • 如果不签合同会怎么样
  • 长期股权投资应计提减值准备的金额
  • 初次申报出口退税可能会遇到哪些问题
  • 短期借款按月计提的分录
  • 直接私募如何纳税
  • 一般纳税人购买汽车会计分录
  • 母子公司无偿划转土地
  • 如何进行汇算清缴
  • 销售 返利
  • 民办非企业单位什么意思
  • 辅助核算设置后使用后还可以随时修改
  • 金税盘技术维护费
  • 免征印花税的6个项目
  • 出口退税过期怎么处理
  • 银行本票的使用仅限于
  • ubuntu中如何设置克隆屏
  • 内存不够用如何升级系统
  • ddriver进程
  • mtask.exe - mtask是什么进程 有什么用
  • linux安装步骤
  • Extjs Label的 fieldLabel和html属性值对齐的方法
  • JavaScript运算符中谁拥有最高优先级
  • easyui的表单验证
  • shell 单引号中引用变量
  • javascript声明变量的语句
  • jQuery+Ajax实现无刷新操作
  • unity script api
  • 企业自建自用房产税如何缴纳
  • 基层税收工作的建议意见
  • 交完车船税后地税局都给什么
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设