2010-12-03 31 views
3

J'essaye de vider un sous-ensemble d'une table dans MySQL avec mysqldump. J'ai les valeurs d'identification des lignes que je veux sélectionner dans la table, stockées dans un fichier. Lorsque j'utilise ces valeurs comme une variable comme suit:en utilisant mysqldump avec l'option where et une longue liste d'arguments dans le script bash

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

Je reçois:

x.bash: ligne x:/usr/bin/mysqldump: liste d'arguments trop longue

Je pourrais essayer de diviser la variable de ligne unique $ ids (1,2,3,4, ..) en listes plus courtes et appeler mysqldump dans une boucle mais je ne suis pas très bon avec les boucles dans les scripts bash. Ou il pourrait y avoir une meilleure façon de résoudre ce problème.

Merci d'avance pour toute aide.

EDIT

Considérant @ suggestion de ajreal, Si je

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

je reçois "liste d'arguments trop longue" à nouveau.

Je récupère les valeurs d'id d'un autre environnement. La base de données avec laquelle je lance ce script et la base de données dans laquelle j'obtiens les valeurs d'id à utiliser dans la clause where se trouvent dans des environnements distincts. En outre, avant cette étape, je crée le fichier de vidage avec l'option --ignore-table, en ignorant la table "Table" que j'utilise à l'étape suivante. Par conséquent, je préférerais utiliser mysqldump pour cette étape aussi.

+1

négatif, enregistrez-le dans le fichier et utilisé ** mysql -u root -p .. ajreal

+0

Après quelques modifications, la réponse de @Dennis a été très utile. Merci encore. – eaykin

Répondre

2

pour cette solution:

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

Le x est juste une valeur factice pour remplir $0. Autre possibilité:

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

Cela divise le fichier d'entrée en groupes de vingt lignes et exécute mysqldump une fois pour chaque groupe. Vous pouvez probablement augmenter ce nombre en toute sécurité et appliquer une limite de caractère en utilisant --max-chars. Vous pouvez utiliser xargs -a /dev/null --show-limits pour voir quelles sont les limites de votre système.

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

Edit:

Essayez ce script Bash. Définissez num à une valeur raisonnable.

#!/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 
+0

Merci Dennis. Si j'essaie: "xargs -a ids.csv -d '\ n' -n 10 --max-chars = 2394769 bash -c 'mysqldump -u racine -p db MyTable --where =" id in ($ @) ">> dump.sql 'x" avec une liste d'arguments de 20 éléments (1,2,3, .., 20) cela fonctionne très bien, cependant si je l'exécute avec le fichier réel (qui est comme 1,2,3 , 4, .. 100000), j'obtiens "xargs: bash: Liste d'arguments trop longue" pour toutes les valeurs -n que j'essaie. J'ai aussi eu cette erreur avec vos autres recommandations. Il semble que 2394769 est la limite la plus élevée que je peux utiliser pour max-chars.Il convient de rappeler que le fichier se compose d'une seule ligne sous forme de (1,2,3,4, .. 100000) – eaykin

+0

@eaykin: Voir mon édition. –

+0

@eaykin: Oui, c'était une faute de frappe. Pardon. Changez le 'c' en' list'. Je vais réparer ma réponse. –