我们在Sybase bcp中使用命名管道,以便我们可以即时压缩输出。
Sybase bcp实用程序在其退出代码中不返回太多信息。 Sybase文档指示用户检查进程写入的错误消息。
这是我们使用的错误处理习惯用法的一个解释,已经删除了脚本的非bcp部分中的一些错误检查以缩短示例。
while :
do
{
rm -f $fifo
mkfifo $fifo
cat $fifo &
CatPid=$!
bcp $db.$owner.$table out $fifo -c $db_creds >$log 2>&1
grep -qi deadlock $log || break
# Must have been a deadlock, clean up.
kill $CatPid
} > $output
done
基本上,如果bcp输出消息中出现'deadlock'这个词,我们再试一次。
两个问题
我特别感兴趣的是检测瞬态bcp错误,我们可以再试一次。
我们使用复合语句,以便我们可以在压缩之前在bcp数据周围插入页眉和页脚,但我省略了它以简化示例。
答案 0 :(得分:2)
我有想法使用命名管道进行bcp输出并将数据从Sybase ASE压缩到文件,然后使用LOAD TABLE语句加载到Sybase IQ中。不幸的是,失去了很大的表现。来自命名管道的LOAD TABLE比HP-UX上的文件LOAD TABLE慢10倍:-(我投票支持将简单的压缩alghoritm直接应用到OC utils(bcp,isql)。
答案 1 :(得分:2)
所以你需要的只是可靠的失败快速bcp。某些Sybase版本的Bcp具有控制最大错误计数的命令参数。 1)如果设置错误计数= 1,那么它将更可靠地失败。 2)然后问题归结为捕获bcp进程的退出代码,在带有&的背景上启动。我不知道究竟应该使用什么shell语法,但可能有一些常见的shell技术。
答案 2 :(得分:2)
这很容易。
这种方法看起来合理吗?
不是真的。首先,shell脚本不是很好,它不需要所有的工作,但我会留下它,因为这不是问题。
其次,bcp
不会死锁,即使在活动数据库上(除非您在数据库中执行非常奇怪的操作,或运行多个并行bcp
流),它等待共享锁清除,所以没有必要检查。
第三,bcp
提供完整和完整的错误消息。使用-e bcp_err_file
调用参数。然后grep ... bcp_err_file
了解错误或模式("^[Ee]rr"
和"^Msg"
是典型的)。我单独陷入错误;例外情况;和其他消息。
第四,我永远不会在shell脚本中永远重试。潜在的无限循环,浪费资源。让它执行一次,并产生“成功”xor“失败”和错误列表。任何循环都应该仅用于要导出的表的列表。
它被编写为正确的unix实用程序/命令。 如果您没有指定错误文件,请确保所有错误消息都转到$stdout
,并且它们与进度消息混在一起。您可以陷入该流中的错误,但这是无腿的;指定一个单独的错误文件。
将$stdout
捕获到bcp_log_file
是正常的,但这与bcp_err_file
检查Unix上的退出状态是另一回事。如果bcp
成功运行(是否产生错误消息),则退出为“成功”;只有当unix程序失败时,才会获得非零退出状态。
除非您按-m max_errors
我们需要担心还有哪些其他bcp错误而不是死锁?
任何和所有错误,无法预测(它是具有固定资源的在线服务器),捕获所有错误,然后检查bcp_err_file
。您可以通过grep
自动进行检查,如上所述。
我特别感兴趣的是检测瞬态bcp错误,我们可以再试一次。
完全没问题。详细上面。暂时性错误很少见。
您还应该担心硬错误和资源错误,不再试一次(因为它会再次失败)。
我们大多数人担心导致缺少行的错误,这意味着bcp_data_file
不完整或无法使用。
答案 3 :(得分:1)
这真的会做你想要的吗?我对bcp命令行工具的理解是没有事务 - 即。如果要加载M行,但是由于任何原因(约束等)插入行N失败,则插入前N-1行。所以重新启动整个文件并不是一个好主意。
您可以使用-m X选项允许bcp在最多X个错误的情况下继续运行,然后尝试识别哪些行无法插入并重试它们。
您还可以查看Michael Peppler的Sybase :: BCP Perl模块,但我们的调查表明它可能与ASE 15有关。