използване на mysqldump с опция where и дълъг списък с аргументи в bash скрипта

Опитвам се да изхвърля подмножество от таблица в MySQL с mysqldump. Имам стойностите на id на редове, които искам да избера от таблицата, съхранени във файл. Когато използвам тези стойности като променлива, както следва:

ids=`cat ids.csv`
mysqldump -u root -p db Table --where="id in ($ids)" >> dump.sql

Взимам:

x.bash: ред x: /usr/bin/mysqldump: Списъкът с аргументи е твърде дълъг

Може да опитам да разделя променливата $ids (1,2,3,4,..) на един ред на по-къси списъци и да извикам mysqldump в цикъл, но в момента не съм много добър с циклите в bash скриптовете. Или може да има по-добър начин за решаване на този проблем.

Благодаря предварително за всяка помощ.

РЕДАКТИРАНЕ

Имайки предвид предложението на @ajreal, ако го направя

mysql -u root -p -e "select * into outfile ./dump.sql from db.Table where id in ($ids)"

Отново получавам „Списъкът с аргументи е твърде дълъг“.

Получавам стойностите на id от друга среда. Базата данни, срещу която изпълнявам този скрипт, и базата данни, към която получавам стойностите на id, които да използвам в клаузата where, са в отделни среди. Освен това, преди тази стъпка създавам дъмп файла с опцията --ignore-table, като пренебрегвам таблицата „Таблица“, която използвам в следващата стъпка. Затова бих предпочел да използвам mysqldump и за тази стъпка.


person eaykin    schedule 03.12.2010    source източник
comment
отрицателен, запазете го във файл и използвайте mysql -u root -p.. ‹ ВАШИЯ_ФАЙЛ   -  person ajreal    schedule 03.12.2010
comment
След някои промени отговорът на @Dennis беше много полезен. Благодаря отново.   -  person eaykin    schedule 07.12.2010


Отговори (2)


Опитайте това:

xargs -a ids.csv -d '\n' -n 20 sh -c 'mysqldump -u root -p db Table --where="id in ($@)" >> dump.sql' x

x е просто фиктивна стойност за попълване на $0. Алтернативно:

xargs -a ids.csv -d '\n' -n 20 sh -c 'mysqldump -u root -p db Table --where="id in ($0 $@)" >> dump.sql'

Това разделя входния файл на групи от двадесет реда и изпълнява mysqldump веднъж за всяка група. Вероятно можете да увеличите този брой безопасно и можете да приложите ограничение на знаците, като използвате --max-chars. Можете да използвате xargs -a /dev/null --show-limits, за да видите какви са ограниченията за вашата система.

xargs -a ids.csv -d '\n' -n 1000 --max-chars=100000 sh -c 'mysqldump -u root -p db Table --where="id in ($@)" >> dump.sql' x

Редактиране:

Опитайте този Bash скрипт. Задайте num на всяка разумна стойност.

#!/bin/bash
ids=$(< ids.csv)

saveIFS=$IFS
IFS=','
array=($ids)               # split into an array using commas as the delimiter
IFS=$saveIFS
array=(${array[@]/%/,})    # add commas back to each element

num=100                    # number of elements to process at a time

for ((i=0; i<${#array[@]}; i+=$num))
do
    list=${array[@]:$i:$num}
    # an excess trailing comma is stripped off in the next line
    mysqldump -u root -p db Table --where="id in ("${list%,}")" >> dump.sql
done
person Dennis Williamson    schedule 03.12.2010
comment
Благодаря ти Денис. Ако опитам: xargs -a ids.csv -d '\n' -n 10 --max-chars=2394769 bash -c 'mysqldump -u root -p db MyTable --where=id in ($@) ›› dump.sql' x със списък с аргументи от 20 елемента (1,2,3,..,20) това работи добре, но ако го стартирам с действителния файл (който е като 1,2,3,4,. .100000), получавам xargs: bash: Списъкът с аргументи е твърде дълъг за всички -n стойности, които опитвам. Получих тази грешка и с другите ви препоръки. Изглежда, че 2394769 е най-високата граница, която мога да използвам за макс. Струва си да напомним, че файлът се състои от един ред във формата на (1,2,3,4,..100000) - person eaykin; 06.12.2010
comment
@eaykin: Да, това беше печатна грешка. съжалявам Променете c на list. Ще поправя отговора си. - person Dennis Williamson; 06.12.2010
comment
Мисля, че c трябва да бъде списък, благодаря ви за скрипта, все още получавам списък с аргументи твърде дълъг за всяка num стойност (1000, 100, 20, 10, 5, 3 и т.н.) - person eaykin; 06.12.2010
comment
@eaykin: Променете mysqldump на echo и задайте num на 5 и вижте как изглежда резултатът (публикувайте го и тук). Освен това публикувайте изхода на echo ${#ids} и echo ${#array[@]}. - person Dennis Williamson; 06.12.2010
comment
@Dennis, мисля, че проблемът беше в добавянето на запетаи обратно към всеки елемент. Замених array=(${array[@]/%/,}) с count=0 за i в ${array[@]}; направете масив[$count]=$i,; ((count++));готово и сега изглежда работи. Също така добавих --add-drop-table=0 опция към mysqldump. - person eaykin; 07.12.2010
comment
@eaykin: Този for цикъл е без операция. Какво се случва, ако просто го оставите? - person Dennis Williamson; 07.12.2010
comment
@Dennis, цикълът изглежда работи добре. т.е. ${array[n]} се превръща в x, от x след цикъла. Друга малка промяна трябва да бъде IFS=$saveIFS - person eaykin; 09.12.2010
comment
@eaykin: Съжалявам, не видях запетаята в коментара ти. Кодът е труден за четене в коментарите, особено ако не enclose it in backticks. Плюс това, поставянето на кавичките след променливата вместо така: array[$count]="$i," прави кода по-труден за четене. Мисля, че истинският проблем беше фактът, че пропуснах въздишката на долара в IFS=$saveIFS, както посочихте. Коригирането на това и връщането към array=(${array[@]/%/,}) трябва да работи и да бъде по-бързо от вашия for цикъл. Съжалявам за правописните грешки. - person Dennis Williamson; 09.12.2010
comment
@GabrielBorgesOliveira: Опитва се да изхвърли база данни с име 91859 и нямам представа откъде идва това число. Вероятно имате липсващ или неуместен аргумент. Не мога да видя вашия скрипт, така че не мога да ви помогна повече. - person Dennis Williamson; 28.03.2018
comment
@GabrielBorgesOliveira: idk, този ред, който започва db на собствен ред ли е, както е показано? Трябва да е на същия ред като командата mysqldump. - person Dennis Williamson; 28.03.2018
comment
@GabrielBorgesOliveira: може да не е твой проблем, но разделяй присвояванията на променливи на различни редове, тъй като аз ги имам, вместо да ги комбинираш - person Dennis Williamson; 28.03.2018
comment
Нека продължим тази дискусия в чата. - person Dennis Williamson; 28.03.2018

ids.csv => 91916, 91859, 91861, 91894, 92095, 92166, 91796 ...

#!/bin/bash
ids=$(< offer_ids.csv)
saveIFS=$IFS
IFS=',' array=($ids)               # split into an array using commas as the delimiter
IFS=$saveIFS array=(${array[@]/%/,})   # add commas back to each element

num=100                    # number of elements to process at a time

for ((i=0; i<${#array[@]}; i+=$num)) do
    list=${array[@]:$i:$num}
    # an excess trailing comma is stripped off in the next line
    echo "list: " $list
    mysqldump -uroot -h host -p pw --opt --where="offer_id IN ("${list%,}")" db offer_images >> offer_images.sql 
done

bash изход:

offer_id IN (91916, 91859, 91861, 91894, 92095)
mysqldump: Got error: 1049: Unknown database '91859,' when selecting the database
person Gabriel Borges Oliveira    schedule 28.03.2018