Как запустить команды сценария оболочки в файле sh параллельно? - PullRequest
1 голос
/ 20 ноября 2019

Я пытаюсь создать резервную копию таблиц на сервере базы данных.

У меня около 200 таблиц. У меня есть сценарий оболочки, который содержит команды для создания резервных копий каждой таблицы, такие как:

backup.sh

psql -u username ..... table1 ... file1;
psql -u username ..... table2 ... file2;
psql -u username ..... table3 ... file3;

Я могу запустить сценарий и создать резервные копии в моеммашина. Но поскольку существует 200 таблиц, команды будут выполняться последовательно и отнимут много времени. Я хочу запускать команды резервного копирования параллельно. Я видел статьи, в которых предлагалось использовать && после каждой команды или использовать команду nohup или wait.

Но я не хочу редактировать скрипт и включатьоколо 200 таких команд.

Есть ли способ параллельно запустить этот список команд сценария оболочки? что-то вроде nodejs делает? Возможно ли это сделать? Или я неправильно смотрю?

Пример команды в скрипте:

psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.tablename TO "/home/username/Desktop/PostgresFiles/tablename.csv" with DELIMITER ","';

Ответы [ 3 ]

2 голосов
/ 20 ноября 2019

Вы можете использовать xargs для параллельного запуска команды и управления количеством одновременных заданий. Выполнение 200 заданий резервного копирования может привести к перегрузке базы данных и снижению производительности до оптимального.

При условии, что у вас есть файл backup.sh с одной командой резервного копирования на строку

xargs -P5 -I{} bash -c "{}" < backup.sh

Команды в файле backup.shдолжно быть изменено, чтобы разрешить цитирование (используя одинарную кавычку, когда это возможно, избегая двойной кавычки):

psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.tablename TO \"/home/username/Desktop/PostgresFiles/tablename.csv\" with DELIMITER \",\"';

Где -P5 контролирует количество одновременных заданий. Это позволит обрабатывать командные строки БЕЗ двойных кавычек. Для приведенного выше сценария вы меняете "\copy ..." на '\copy ...'

Более простой альтернативой будет использование помощника backup-table.sh, который будет принимать два параметра (таблица, файл), и использования

xargs -P5 -I{} backup-table.sh "{}" < tables.txt

И поместите все сложные цитаты в backup-table.sh

1 голос
/ 07 декабря 2019
doit() {
  table=$1
  psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.'$table' TO "/home/username/Desktop/PostgresFiles/'$table'.csv" with DELIMITER ","';
}
export -f doit

sql --listtables -n postgresql://user:pass@host:5490/db | parallel -j0 doit
0 голосов
/ 20 ноября 2019

Есть ли в скрипте какая-либо логика, кроме отдельных команд? (Например: а if или обработка вывода?).

Если это просто файл со списком сценариев, вы можете написать оболочку для сценария (или цикл из CLI), например:

$ cat help.txt
echo 1
echo 2
echo 3

$ while read -r i;do bash -c "$i" &done < help.txt
[1] 18772
[2] 18773
[3] 18774
1
2
3
[1]   Done                    bash -c "$i"
[2]-  Done                    bash -c "$i"
[3]+  Done                    bash -c "$i"

$ while read -r i;do bash -c "$i" &done < help.txt
[1] 18820
[2] 18821
[3] 18822
2
3
1
[1]   Done                    bash -c "$i"
[2]-  Done                    bash -c "$i"
[3]+  Done                    bash -c "$i"

Каждая строка help.txtсодержит команду, и я запускаю цикл, где я беру каждую команду и запускаю ее в подоболочке. (это простой пример, в котором я просто справляюсь с каждой работой. Вы можете усложнить использование чего-то вроде xargs -p или parallel, но это отправная точка)

...