• MySQL-添加索引或字段时如何不锁表


    索引的添加MySQL经历了一下几个历程:

    一 .在MySQL 5.5版本之前,添加索引具体是这样的:

    1.首先创建一张临时表和原表数据结构相同,将你要添加的索引加上。

    2.把原表数据导入临时表。

    3.删除原表。

    4.将临时表重命名为原表。

    这样做有很大问题:

    首先对于大数据量的导入需要很长的时间,那么在这段时间里新增或修改的数据没办法处理。

    其次如果碰上大事务正在新增或更新更新这张原表还会锁表,你还没办法用sql去导入到临时表中。

    二 .但在InnoDB 1.0版本开始,支持一种Fast Index(快速索引创建)的方式,简称FIC,他是这样做的:

    对于辅助索引的创建,他不需要建临时表,他会直接将原表加S锁,这样就不会有数据导入的问题。

    但还是会有些其他问题:

    这意味着这加索引的这段时间里这张表只能读,不能增删改。而且不适用主键索引。

    三. 针对一,二阶段的问题,Facebook总结并实现了一种在线执行方案-OSC:

    1.初始化,检查原表所有的问题,包括主键,触发器,外键等。

    2.创建临时表,添加索引字段。

    3.创建deltas表,为下一步创建触发器做准备。

    4.对原表创建增删改的触发器,触发器产生的草所记录写入到上一步创建的deltas表。

    5.开始OSC操作的事务。

    6.删除所有辅助索引,再将原表数据通过分片文件写入临时表。

    7.将deltas表中产生的记录应用到临时表中。

    8.重新创建辅助索引。

    10.将原表和临时表交换名字,在这个过程中会锁表,但这个过程很快。

    以上便是整个OSC过程,看起来就很复杂,实际的脚本也很复杂,光是核心PHP代码就2000多行,而且有一定局限性,对于分布式无法主从同步。

    四.MySQL5.6版本开始支持在线创建--Online DDL,只需一行代码:

    以下是对辅助索引的添加:

     ALTER TABLE table_name ADD INDEX  indea_name ,ALGORITHM=INPLACE,LOCK=NONE;

    ALGORITHM指定创建或删除索引得算法,有以下几类:

    COPY:按照5.1之前的版本,创建临时表的方式。

    INPLACE:不需要创建临时表。

    DEFAULT:表示根据参数old_alter_table来判断是用COPY还是INPLACE,默认OFF,表示采用INPLACE方式。

     LOCK表示加锁情况:

    NONE:不添加任何锁,允许并发。

    SHARE:加S锁。

    EXCLUSIVE:加X锁,读写都不允许。

    DEFAULT:会先判断是否可用NONE,若不能再判断是否可用SHARE模式,最后判断EXCLUSIVE。

    Online DDL的原理是则好样的:

    1.在创建或删除索引的同时,会将这段时间发生的增删改操作的日志写入一个缓存中,待完成索引后再重新将日志应用到表上,达到数据一致性。这个缓存的小由innodb_online_alter_log_max_size控制,默认128MB。可以根据情况调整。

    需要注意的是,在这个过程中,sql不会用到正在创建的索引。

  • 相关阅读:
    Java 将数字转为16进制,然后转为字符串类型 将空格去掉。终结版
    Java 将数字转为16进制,然后转为字符串类型
    Java 数组转字符
    Apple Reject
    NSInternalInconsistencyException
    svn报错cleanup failed–previous operation has not finished; run cleanup if it was interrupted的解决办法
    CSS伪类选择器 奇偶匹配nth-child(even)
    常用css代码(scss mixin)
    织梦网站给栏目添加自定义字段图文详解
    css怎么解决表格边框线重复问题
  • 原文地址:https://www.cnblogs.com/lvqiang/p/14412493.html
Copyright © 2020-2023  润新知