我用Perl创建了一个ETL工具。ETL工具与三个数据库服务器通信,例如dbserver1 (OLTP服务器- Windows Box), dbserver2(暂存服务器- linux Box), dbserver3 (OLAP服务器,linux Box)。我的ETL脚本在dbserver 2上。
脚本从dbserver1读取数据并将其放入dbserver2进行一些转换,执行转换,然后将数据放入dbserver3。为了实现这一点,脚本在dbserver2上创建了一些OUTFILE数据。有两种类型的OUTFILE查询:
- OUTFILE查询在dbserver1上运行,在dbserver2和 上创建.data在dbserver2上运行的
- OUTFILE查询在dbserver2上创建.data文件。
第二个查询工作得很好,因为它在同一服务器上创建了一个文件。但是第一种类型的查询给了我以下错误:
DBD::mysql::st execute failed: Can't create/write to file 'homedbserver2dumpfile.2011-11-04-03:02.data' (Errcode: 2) at stagingtransform.pl line 223, <> line 8.
我猜这和一些用户权限有关。如果我没有错的话,那么dbserver2上的MySQL有读/写dbserver2的权限,但dbserver1上的MySQL没有。
可能是因为dbserver1是Windows而dbserver2是Linux盒子吗?
如何解决这个问题?
文件格式为:dumpfile.yyy-mm-dd-hh:mm。我还设置了dbserver2上MySQL的AppArmor设置,这是dbserver2上的MySQL。
问题是dbserver1上的outfile查询只能在本地写入,因此需要使用不同的方法。
一个非常简单的方法是使用mysqldump
(在dbserver2上)连接到dbserver1,并将输出管道到mysql客户端,该客户端将SQL注入dbserver2。
另一方面,如果您想使用DBI
:
my $source_sql = q{SELECT ...};
my $target_sql = q{INSERT ... VALUES (?, ?, ...)};
my $source = $source_dbh->prepare($source_sql);
my $target = $target_dbh->prepare($target_sql);
$source->execute;
my $qty = $target->execute_array({ArrayTupleFetch => $source});
对于大数据传输,mysqldump
方法更快。