最近一个统计系统的大表需要加字段,表的引擎是myisam,表大小在3亿,物理文件在106G。想想都蛋疼。那么这种情况下怎么把字段撸上去呢?

1. 首先想到了《高性能MySQL》提到的直接更改表结构文件(frm),但是在经过测试以后,发现提示表损坏了,需要repair,只好放弃了。

2. 使用pt-online-schema-change,刚开始跑没有问题,后面在凌晨发现影响业务了,也只好放弃了。

3. 最近GitHub开源的gh-ost,属于新鲜玩意,还没有研究,只好放弃。

4. 创建新表,load数据,最后rename表。(前提是表只有insert,表是myisam引擎)

最后使用了第四种方案把字段加上了。那么下面就来详细说说第三种方案。

我们假设要把tb_yayun表加两个字段,uid,age。

老表(业务在使用的表):

mysql> show create table tb_yayun\G
*************************** 1. row ***************************Table: tb_yayun
Create Table: CREATE TABLE `tb_yayun` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` char(20) DEFAULT NULL,`enter_time` datetime NOT NULL,PRIMARY KEY (`id`),KEY `enter_time` (`enter_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

环境准备:

1. 一台空闲的服务器,没跑业务,安装了mysql实例的。在该服务器上面创建新表。

mysql> show create table tb_yayun_new\G
*************************** 1. row ***************************Table: tb_yayun_new
Create Table: CREATE TABLE `tb_yayun_new` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` char(20) DEFAULT NULL,`enter_time` datetime NOT NULL,`uid` int(11) DEFAULT NULL,`age` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `enter_time` (`enter_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

2. 在线上服务器导出tb_yayun表的数据(这里有一个技巧,不需要全部导出,截止到某一天就行。)可以用下面下面命令:

mysql -uroot -p -q -s -e "use test;select *,'','' from tb_yayun where enter_time >= '2016-08-01 00:00:00'" > /data/tb_yayun.txt

3. 把导出的文件拷贝到上面提到的空闲服务器导入(时间会很长,我当时导入3亿的表花了6小时):

LOAD DATA INFILE '/data/tb_yayun.txt' INTO TABLE tb_yayun_new;

4. 和开发确定一个切换时间;我们的数据都是先入队列,所以是可以暂停一会儿写入的。和开发确定好一个时间以后,比如要在2016-08-02 15:00:00以后切换,那么此时还需要做下面工作。还需要补一次数据,因为新表的数据只导入到了2016-08-01 00:00:00。所以再次从线上服务器导数据。

 mysql -uroot -p -q -s -e "use test;select *,'','' from tb_yayun where enter_time >= '2016-08-02 00:00:00' and enter_time <= '2016-08-02 15:00:00' > /data/02_tb_yayun.txt

再次拷贝到空闲的服务器导入:

 LOAD DATA INFILE '/data/02_tb_yayun.txt' INTO TABLE tb_yayun_new;

5. 当导入完成以后,把tb_yayun_new表的物理文件拷贝到线上服务器。(MYD,MYI,frm),注意权限。如果线上有1主3从,那么4台服务器都需要拷贝。拷贝完成以后执行flush tables,然后每台服务器检查表是否正常。limit一下或者count一下都行。

6. 通知开发停止写入,一般是把程序停止一会儿。具体时间不会超过10分钟。当开发说已经停了导入数据的程序以后,我们要看看老表是否还有数据写入,对于myisam表来说直接count看条数是否有变化就行。如果没有数据写入以后。执行下面的命令:

(1)再次从老服务器导数据,我们需要把数据补一致。(线上服务器)

mysql -uroot -p -q -s -e "use test;select *,'','' from tb_yayun where enter_time >= '2016-08-02 15:00:00' > /data/15_tb_yayun.txt                        

(2)load数据到tb_yayun_new(注意:会导致从库延时,具体延时多久看导入的数据大小)

LOAD DATA INFILE '/data/15_tb_yayun.txt' INTO TABLE tb_yayun_new;

(3)对比新表老表数据是否一致。如果操作没有错误的话,数据肯定是一致的。新表(tb_yayun_new),老表(tb_yayun)进行count确认。
(4)老表进行rename操作

alter table tb_yayun rename to tb_yayun_old_20160802; 

(5)新表rename操作

alter table tb_yayun_new rename to tb_yayun;

7. 通知开发那边开启数据导入程序。至此大表加字段完成。

总结:

上面提到的方法有非常大的局限性,比如必须是myisam表,该表只有insert,还有就是业务能够忍受5-10分钟没有最新数据。对于前台业务当然无法忍受,不过如果是公司的统计系统,或者内部人员使用。则完全没问题,影响非常小,沟通到位就行。

转载于:https://www.cnblogs.com/gomysql/p/5747545.html

MyISAM表加字段的特殊方法相关推荐

  1. 关于Oracle.ManagedDataAccess数据库表加字段后,必须重启的问题

    关于Oracle.ManagedDataAccess数据库表加字段后,必须重启的问题,解决方法如下: 在数据库连接字串中,增加一个参数:Metadata Pooling=false 如"Da ...

  2. mysql表copy锁表吗_MySQL锁(二)表锁:为什么给小表加字段会导致整个库挂掉?...

    概述 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持.最常使用的MYISAM与INNODB都支持表级锁定.表级锁定分为表共享 ...

  3. mysql新增字段会锁表_MySQL锁(二)表锁:为什么给小表加字段会导致整个库挂掉?...

    概述 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持.最常使用的MYISAM与INNODB都支持表级锁定.表级锁定分为表共享 ...

  4. 获取sqlserver数据库中所有库、表、字段名的方法

    获取sqlserver数据库中所有库.表.字段名的方法 2009年03月12日 星期四 下午 12:51 1.获取所有数据库名: SELECT Name FROM Master..SysDatabas ...

  5. 快速给数据库大表添加字段或索引方法

    第一,基础方法 增加字段基本方法,该方法适合十几万的数据量,可以直接进行加字段操作. ALTER TABLE tbl_tpl ADD title(255) DEFAULT '' COMMENT '标题 ...

  6. mysql myisam表加索引_MyISAM和InnoDB的索引实现

    在 MySQL 中,主要有四种类型的索引,分别为: B-Tree 索引, Hash 索引, Fulltext 索引和 R-Tree 索引.我们主要分析B-Tree 索引. B-Tree 索引是 MyS ...

  7. mysql myisam表加索引_MySQL中myisam和innodb的主键索引有什么区别

    ALTER TABLE t1 ADD INDEX(or CREATE INDEX) ALTER TABLE t1 ADD FULLTEXT INDEX ALTER TABLE t1 ADD COLUM ...

  8. 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍? *(笔记)转

    数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 根据加锁的范围,MySQL 里面的锁大致 ...

  9. 六、全局锁和表锁 :给表加个字段怎么有这么 多阻碍?

    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1 全局锁 2 表级锁 2.1 表锁 2.2 元数据锁 前言 接下来聊聊 MySQL 的锁.数据库锁设计的初衷是处理并 ...

最新文章

  1. php判断版本根据版本调用不同,C#_C#自动判断Excel版本使用不同的连接字符串,用OLEDB通过设置连接字符串可 - phpStudy...
  2. 自定义函数_Access中的WorkDate自定义函数
  3. NI FlexLogger 2020 R3中文版
  4. / /* /**的区别
  5. wxpython是什么_请问wxpython中 event传递的什么参数?
  6. 树莓派小车(远程控制、PWM变速、超声波自动避障)
  7. ASP.NET Core:从ASP.NET Web API迁移的多层数据服务应用程序
  8. POJ1062 昂贵的聘礼(最短路径)
  9. C++之编写dll库
  10. CF1042F Leaf Sets
  11. 全国计算机等级考试3月份报名时间,2021年3月全国计算机等级考试报名时间公布...
  12. SVN 下载与安装(超简单)!!!
  13. android 仿QQ相册
  14. 经纬财富:亳州炒白银操作方法,谨防亏损
  15. GO语言实现用户注册方法(互亿无线)
  16. 这么写参数校验(validator)就不会被劝退了~
  17. NTL库在Win上基于MinGW的安装
  18. 吴莫愁新专辑出炉 承认哈林老师是她生命中的贵人
  19. 简单介绍使用 ssh 连接远程服务器运行图形界面程序
  20. comsol学习中心:定义与材料选择

热门文章

  1. Redis的常用命令及数据类型
  2. Spring boot Tomcat配置
  3. Git之第三方托管oschina
  4. php正规则表达式学习笔记(几个常用函数的区别)
  5. Mysql递归查询,无限级上下级菜单
  6. 2015.5.12站立会议
  7. lucene,lucene.net学习教程
  8. 网页设计师的最佳设计工具名单出炉
  9. DataList分页技术-- PagedDataSource类实现DataList和Repeater的分页效果
  10. 男生给女生最牛B的告白