视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL下海量数据的迁移步骤分享_MySQL
2020-11-09 18:53:12 责编:小采
文档

bitsCN.com

公司数据中心计划将海量数据做一次迁移,同时增加某时间字段(原来是datatime类型,现在增加一个date类型),单表数据量达到6亿多条记录,数据是基于时间(月)做的partition由于比较忙,一直没有总结,所以很细节的地方都记不清楚了,此处只是简单总结下当时的情形,备忘

乱打乱撞

最初接到任务,没有明确的入手点,直接就是select * from db limit 10000,动态修改翻页数量,通过控制台看耗时情况,慢


SELECT IR_SID,IR_HKEY,IR_GROUPNAME,IR_SITENAME,IR_CHANNEL,IR_MID,IR_URLNAME,IR_STATUS_CONTENT,IR_CREATED_AT,date_format(IR_CREATED_AT,'%Y.%m.%d'),IR_LASTTIME,IR_VIA,IR_THUMBNAIL_PIC,IR_RTTCOUNT,IR_COMMTCOUNT,IR_UID,IR_SCREEN_NAME,IR_RETWEETED_UID,IR_RETWEETED_SCREEN_NAME,IR_RETWEETED_MID,IR_RETWEETED_URL,IR_STATUS_BODY FROM TB_SINA_STATUS WHERE IR_SID>40000 AND IR_SID<50001 INTO OUTFILE '/home/mysql/data/data_outfile.txt'; LOAD DATA INFILE '/home/mysql/data/data_outfile.txt' INTO TABLE NEW_TB_SINA_STATUS;

是否可以基于partition读数据呢

既然数据库是按partition做分区,是否可以按partition读数据呢,如果可以改用怎样的语法读呢?时间上只要按月读数据,mysql会自动的基于partition读,具体可以用命令:explain partition即可看到具有基于哪个partition
读大数据会十分耗时,对于数据进行到什么状态,我们可能十分想了解,可以用命令:show status查看,我印象中主要是sending data,writting to net之类的。
innodb引擎的性能较myIsam引擎到底如何?
导库实验中导出并导入一个月的数据(8G的文本量,2500w条记录),在myisam引擎下需要不到4h(测试环境为pc机),但是在innodb引擎下,却需要32小时,改善索引之类的,也需要28h,性能有8倍之差。

在网上找到了高人关于innodb与myisam区别,说需要修改innodb_buffer_pool_size、innodb_flush_log_at_trx_commit

可保证没有太大差别,尝试了没有明显改善,在本机倒是可以,为什么呢???这个折腾了我好长时间

innodb_flush_log_at_trx_commit

是否为Innodb比MyISAM慢1000倍而头大?看来也许你忘了修改这个参数了。默认值是 1,这意味着每次提交的更新事务(或者每个事务之外的语句)都会刷新到磁盘中,而这相当耗费资源,尤其是没有电池备用缓存时。很多应用程序,尤其是从 MyISAM转变过来的那些,把它的值设置为 2 就可以了,也就是不把日志刷新到磁盘上,而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去,因此通常不会丢失每秒1-2次更新的消耗。如果设置 为 0 就快很多了,不过也相对不安全了 ― MySQL服务器崩溃时就会丢失一些事务。设置为 2 只会丢失刷新到操作系统缓存的那部分事务。

innodb_buffer_pool_size

Innodb在默认的 innodb_buffer_pool_size 设置下跟蜗牛似的。由于Innodb把数据和索引都缓存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。

最后千辛万苦的、跋山涉水的,找到了另外两个参数

innodb_log_file_size

在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高,但是要注意到可能会增加恢复时间。我经常设置为 -512MB,跟据服务器大小而异。

innodb_log_buffer_size
默认的设置在中等强度写入负载以及较短事务的情况下,服务器性能还可以。如果存在更新操作峰值或者负载较大,就应该考虑加大它的值了。如果它的值设置太高了,可能会浪费内存 ― 它每秒都会刷新一次,因此无需设置超过1秒所需的内存空间。通常 8-16MB 就足够了。越小的系统它的值越小。


最终搞定,myisam与innodb的导数据的性能基本一致,2500的数据约需要3.5h,单库读数据需要2h,这个只是一个示意值仅供参考(pc上的测试),正式服务的上的测试结果更加明显

性能调优语句参考


set profiling = 1;
show profiles/G
SHOW profile CPU,BLOCK IO io FOR query 1;
show status
Show Processlist
explain

并行读取是否会更快?

如果基于partition导数据,还是不能达到既定目标,我最终是通过编写shell脚步,多进程并行基于partition导数据,即启动多个mysql -uroot -p db < exp201201.sql 、mysql -uroot -p db < exp201202.sql,每个sql下按天做读写(事件环境下是按月做partition的)


SELECT IR_SID,IR_HKEY,IR_GROUPNAME,IR_SITENAME,IR_CHANNEL,IR_MID,IR_URLNAME,IR_STATUS_CONTENT,IR_CREATED_AT,date_format(IR_CREATED_AT,'%Y.%m.%d'),IR_LASTTIME,IR_VIA,IR_THUMBNAIL_PIC,IR_RTTCOUNT,IR_COMMTCOUNT,IR_UID,IR_SCREEN_NAME,IR_RETWEETED_UID,IR_RETWEETED_SCREEN_NAME,IR_RETWEETED_MID,IR_RETWEETED_URL,IR_STATUS_BODY
INTO OUTFILE '/home/mysql/data/sinawb20120724/111101.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '//'
LINES TERMINATED BY '/n'
FROM TB_SINA_STATUS
WHERE ir_created_at >='2011-11-01 00:00:00' and ir_created_at <'2011-11-01 23:59:59'

LOAD DATA LOCAL INFILE '/home/mysql/data/sinawb20120724/111101.txt'
IGNORE INTO TABLE `NEW_TB_SINA_STATUS`
CHARACTER SET UTF8
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '//'
LINES TERMINATED BY '/n'bitsCN.com

下载本文
显示全文
专题