在 bash 中使用 xargs parallel & psql 导出函数

Exporting function with xargs parallel & psql in bash

我正在尝试 运行 SQL 并行地针对一个或多个 psql 兼容主机,在每个主机上按顺序 SQL 运行,使用 xargs.

bash 脚本,我从另一个脚本中获取:

# Define the count of hosts (also the number of parallel processes)
export pe_fpe_hosts_line_count=$(cat $pe_fpe_hosts_file_loc | wc -l)

# Define the function that runs SQL from a file
function func_pe_exec_sql {
while read pe_sql_file; do
psql -q -t -c "\"$pe_sql_file"\"
done <$pe_fpe_sql_file_loc
  }
export -f func_pe_exec_sql

# Define the xargs parallel function
function func_pe_parallel {
while read pe_hosts_file; do
echo $pe_hosts_file | xargs -d '\n' -P $pe_fpe_hosts_line_count func_pe_exec_sql
done <$pe_fpe_hosts_file_loc
}

我得到的错误:xargs: func_pe_exec_sql: No such file or directory。这很奇怪 - 我已经导出了函数!

示例 SQL 文件:

INSERT INTO public.psql_test SELECT 1 as myint, now() as mytime;
INSERT INTO public.psql_test SELECT 2 as myint, now() as mytime;
INSERT INTO public.psql_test SELECT 3 as myint, now() as mytime;
INSERT INTO public.psql_test SELECT 4 as myint, now() as mytime;
INSERT INTO public.psql_test SELECT 5 as myint, now() as mytime;

示例SQL 主机文件:

--host=myhost1 --port=5432 --dbname=postgres --username=cooluser
--host=myhost2 --port=5432 --dbname=postgres --username=cooluser

pe_fpe_sql_file_loc 是 SQL 文件的路径,pe_fpe_hosts_file_loc 是 SQL 主机文件的路径。

SQL在单独的事务中必须始终是运行,并且SQL文件中的每一行都需要单独插入,一个接一个。 5 应该与最大的 mytime 值位于同一行。

我将它用作 ETL 框架,但函数在数据库中定义,而不是用于简单的插入:)

我认为您对 xargs 的调用不正确。您实际上并没有将行从 pe_hosts_file 传递给函数 func_pe_exec_sql.

您需要将管道的输入传递给函数,才能做到这一点;你需要有一个占位符,xargs 中的 -I 标志提供。

-I replace-str
     Replace occurrences of replace-str in the initial-arguments with names 
     read from standard input. Also, unquoted blanks do not terminate input items; 
     instead the separator is the newline character. Implies -x and -L 1.

使用需要使用类似下面的东西。

| xargs -d '\n' -I {} -P "$pe_fpe_hosts_line_count" bash -c 'func_pe_exec_sql "{}"'

其中 {} 是管道值的占位符,我们将其传递给由 bash -c 直接生成的子 shell 函数 func_pe_exec_sql. {} 周围的特殊双引号是为了确保 shell 在调用函数之前扩展值。