使用shell并行执行多个脚本

时间:2022-06-22
本文章向大家介绍使用shell并行执行多个脚本,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzy0623/article/details/53906996

有没有一种比较通用的并行执行多个SQL脚本的方法呢?每种数据库都提供命令行接口执行SQL语句,因此最容易想到的就是通过初始化多个并发的会话并行执行,每个会话运行一个单独的查询,用来抽取不同的数据部分。以Oracle例如,假设要从订单表抽取数据,订单表已经是按月做了范围分区,分区名称是orders_jan2008、orders_feb2008等。要从订单表抽取一年的数据,可以初始化12个并发的SQL*Plus会话,每个抽取一个分区。每个会话执行的SQL脚本应该类似:

spool order_jan.dat
select * from orders partition (orders_jan2008);
spool off

这12个SQL*Plus进程将并行导出数据到12个文件。如果需要,还可以在抽取后使用操作系统命令将12个文件合并起来(如Linux的cat命令)。即使订单表没有分区,仍然可以基于逻辑条件执行并行抽取。逻辑方法是基于列值的逻辑范围,例如:

select ... where order_date
between to_date('2008-01-01','yyyy-mm-dd') and to_date('2008-01-31','yyyy-mm-dd');

通过简单的shell脚本,可以从命令行接收并行度参数,使这些调用并行执行。

#!/bin/bash  
export NLS_LANG=american_america.AL32UTF8
for(( i = 0; i < $1; i++ ))  
do  
{  
sqlplus user1/password1 << !
start a.sql
exit;
!
cat ./result.lst >> aa.txt
} &  
done  
wait  
date

a.sql文件内容如下:

set echo off;
set heading off;
set line 1000;
set pagesize 0;
set numwidth 12;
set termout off;
set trimout on;
set trimspool on;
set feedback off;
set timing off;

spool result.lst
select * from mytable;
spool off

脚本中使用了&符号,使得{}内的命令在后台并行执行,并将每次生成的文本文件result.lst合并到一个新的文件aa.txt中。等到循环里面的命令都结束之后才执行接下来的date命令。用这个示例说明并行执行多个SQL脚本文件(这里多次执行同一个文件a.sql,当然实际中应该是多个不同的SQL文件)。mytable表有57606行记录,如果执行两次,文件中应该有115212行记录。

[oracle@data-01 ~]$ ./a.sh 2
...
[oracle@data-01 ~]$ cat result.lst | wc -l
57606
[oracle@data-01 ~]$ cat aa.txt | wc -l
115212

换做MySQL数据库,整体思路是一样的,只要把sqlplus换成mysql客户端,再针对MySQL的语法做相应的修改即可。 并行抽取一个复杂的SQL查询有时是可行的,尽管将一个单一查询分成多个部分可能是一个挑战。在并行模式下,协调多个独立的进程,保证一个整体一致的视图可能是非常困难的。而且所有并行技术都会使用更多的CPU和I/O资源,因此在执行任何并行抽取技术前需要评估对系统性能的影响。我们应该控制并发进程的个数,不然会影响系统其它进程的运行。