大数据量生成脚本及导入策略
性能测试过程中,如果需要构造一张表大数据量基础数据时,有两点需要注意:如何生成unl文件(此文件是后缀为.unl的数据文件,格式为,按表列分割的数据记录,例如:10001|33333|),生成的unl文件是否可以一次性导入到数据库相应表中。
为了方便叙述,假设数据库存在表test(id integer,name integer,primary key(id,name))。若想为此表导入1000W条记录,手动insert不现实,一般数据库系统都会提供特定指令,实现数据的导入导出操作,我们可以预先构造好相应格式的unl文件,再调用数据库导入指令,实现数据的快速导入。以Informix数据库为例,数据导入操作的命令为:load from testdata.unl insert into test;现在,剩下的问题就是如何生成一千万行的unl文件了。
了解shell脚本的同学会很快想到使用awk实现,这里也如大家所想,使用awk实现:
[plain]
<span style="">#!/bin/sh
awk 'BEGIN{
dbfile=sprintf("testdata.unl");
for(i=0; i<1000; i++)
{
for(j=0;j<10000;j++)
{
printf "100%05d|9%08d|/n",i,j >>dbfile
}
printf "%d completed./n",i
}
}' /dev/null</span>
这样,会生成一个有1000W条记录的unl文件,于是我们兴冲冲使用“load from testdata.unl insert into test;”指令导入数据,结果发现报错了。因为一次性导入的数据太多,数据库系统的缓存、日志系统空间不够用,无法一次性记录太多的记录(或者因为操作时间太长,直接超时了“Long transaction aborted”)。
有两种解决方案:提高缓存、日志系统大小;缩小单个unl数据量。显而易见,后者更为合理。
如果将一千万的unl分成100小份,每份10W条,就好处理多了。脚本略作修改,如下:
[plain]
<span style="">#!/bin/sh
awk 'BEGIN{
for(i=0; i<100; i++)
{
dbfile=sprintf("mytable%02d.unl",i);
for(j=0;j<100000;j++)
{
printf "100%05d|9%08d|/n",i,j >>dbfile
}
printf "%d completed./n",i
}
}' /dev/null</span>
此时,面对100个文件,要操作一百次,又有点头大。本着偷懒的原则,自然想到使用自动去做。于是,自动导入到test表中的shell脚本也新鲜出炉:
[plain]
<span style="">#!/bin/sh
#生成100条的sql脚本
awk 'BEGIN{
dbfile=sprintf("loadData.sql");
for(i=0; i<100; i++)
{
printf "load from mytable%02d.unl insert into test;",i >>dbfile
}
printf "completed."
}' /dev/null
#执行脚本
dbaccess mydatabank loadData.sql
</span>
当然,如果想更深一步“偷懒”,可以把这些shell放一起,不过要注意可读性,建议再新建一个shell,顺序调用这两个shell,便于后续维护。