【问题标题】:using mysqldump with where option and a long argument list in bash script在 bash 脚本中使用带有 where 选项和长参数列表的 mysqldump
【发布时间】:2010-12-03 17:16:21
【问题描述】:

我正在尝试使用 mysqldump 转储 MySQL 中表的子集。我有要从表中选择的行的 id 值,存储在文件中。当我将这些值用作变量时,如下所示:

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

我明白了:

x.bash: line 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 值。我运行此脚本的数据库和我获得要在 where 子句中使用的 id 值的数据库位于不同的环境中。 此外,在此步骤之前,我使用 --ignore-table 选项创建转储文件,忽略我在下一步中使用的“表”表。因此,我也更愿意在该步骤中使用 mysqldump。

【问题讨论】:

  • 否定,保存到文件中并使用 mysql -u root -p..
  • 经过一些更改,@Dennis 的回答非常有帮助。再次感谢。

标签: mysql bash mysqldump


【解决方案1】:

试试这个:

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

【讨论】:

  • 谢谢丹尼斯。如果我尝试:“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),对于我尝试的所有 -n 值,我得到“xargs:bash:参数列表太长”。我在您的其他建议中也遇到了这个错误。似乎 2394769 是我可以用于 max-chars 的最高限制。值得提醒的是,该文件由 (1,2,3,4,..100000) 形式的单行组成
  • @eaykin:是的,这是一个错字。对不起。将c 更改为list。我会修正我的答案。
  • 我认为“c”应该是“list”,谢谢你的脚本,对于每个 num 值(1000、100、20、10、5、3),我仍然得到“Argument list too long”等)
  • @eaykin:将mysqldump 更改为echo 并将num 设置为5,然后查看输出的样子(也将其发布在这里)。另外,发布echo ${#ids}echo ${#array[@]} 的输出。
  • @Dennis,我认为问题在于将逗号添加回每个元素。我将 "array=(${array[@]/%/,})" 替换为 "count=0 for i in ${array[@]}; do array[$count]=$i","; (( count++));done" 并且它现在似乎正在工作。我还在 mysqldump 中添加了“--add-drop-table=0”选项。
【解决方案2】:
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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 2016-09-11
    • 1970-01-01
    • 2018-09-04
    • 2017-05-27
    • 2014-06-05
    相关资源
    最近更新 更多