1つのデータベースと約150のテーブルを持つ大きなSQLファイルがあります。 mysqlimport
を使用してそのデータベースをインポートしたいのですが、インポートプロセスでいくつかのテーブルを無視またはスキップしたいです。すべてのテーブルをインポートするための適切な構文は何ですか?ありがとうございました。
mysqlimport
は、SQLステートメントをインポートするための適切なツールではありません。このツールは、CSVなどのフォーマットされたテキストファイルをインポートするためのものです。あなたがしたいことは、次のようなコマンドでSQLダンプをmysql
クライアントに直接フィードすることです:
bash > mysql -D your_database < your_sql_dump.sql
mysql
もmysqlimport
も必要な機能を提供しません。ダンプ全体をインポートしてから、不要なテーブルを削除するのが最善のチャンスです。
ダンプの取得元のサーバーにアクセスできる場合は、mysqldump --ignore-table=database.table_you_dont_want1 --ignore-table=database.table_you_dont_want2 ...
を使用して新しいダンプを作成できます。
RandomSeedが受け入れた回答には時間がかかる可能性があります。テーブルのインポート(後で削除するため)は、サイズによっては非常に無駄です。
を使用して作成されたファイルの場合
mysqldump -u user -ppasswd --opt --routines DBname > DBdump.sql
現在、約7GBのファイルを取得していますが、そのうち6GBはログテーブルのデータであり、そこにある必要はありません。このファイルの再読み込みには数時間かかります。リロードが必要な場合(開発目的、またはライブリカバリに必要な場合)、このようにファイルをスキミングします。
sed '/INSERT INTO `TABLE_TO_SKIP`/d' DBdump.sql > reduced.sql
そしてリロード:
mysql -u user -ppasswd DBname < reduced.sql
これにより、「不要な」テーブルが作成されたが空の完全なデータベースが作成されます。テーブルがまったく必要ない場合は、ロードが完了した後に空のテーブルをドロップするだけです。
複数のテーブルの場合、次のようなことができます。
sed '/INSERT INTO `TABLE1_TO_SKIP`/d' DBdump.sql | \
sed '/INSERT INTO `TABLE2_TO_SKIP`/d' | \
sed '/INSERT INTO `TABLE3_TO_SKIP`/d' > reduced.sql
IS a 'gotcha'-「INSERT INTO TABLE_TO_SKIP」を含む可能性のあるダンプ内のプロシージャに注意してください。
Mysqlダンプからいくつかのテーブルを除外するためのスクリプトは次のとおりです。注文と支払いのデータを保持する必要がある場合は、これを使用してDBを復元します
exclude_tables_from_dump.sh
#!/bin/bash
if [ ! -f "$1" ];
then
echo "Usage: $0 mysql_dump.sql"
exit
fi
declare -a TABLES=(
user
order
order_product
order_status
payments
)
CMD="cat $1"
for TBL in "${TABLES[@]}";do
CMD+="|sed 's/DROP TABLE IF EXISTS \`${TBL}\`/# DROP TABLE IF EXIST \`${TBL}\`/g'"
CMD+="|sed 's/CREATE TABLE \`${TBL}\`/CREATE TABLE IF NOT EXISTS \`${TBL}\`/g'"
CMD+="|sed -r '/INSERT INTO \`${TBL}\`/d'"
CMD+="|sed '/DELIMITER\ \;\;/,/DELIMITER\ \;/d'"
done
eval $CMD
テーブルのDROPおよび再作成を避け、このテーブルにデータを挿入します。また、DELIMITERの間に保存されたすべての関数と手順を削除します;;およびDELIMITER;
必要に応じて、一度に1つのテーブルを作成できます。
mysqldump -p sourceDatabase tableName > tableName.sql
mysql -p -D targetDatabase < tableName.sql
.sql.gzファイルで作業する人向け。次のソリューションが非常に役立つことがわかりました。データベースは25GB以上で、ログテーブルを削除する必要がありました。
gzip -cd "./mydb.sql.gz" | sed -r '/INSERT INTO `(log_table_1|log_table_2|log_table_3|log_table_4)`/d' | gzip > "./mydb2.sql.gz"
Donの回答とXosofoxのコメントおよびこの関連記事に感謝します。 zcatとsedまたはawkを使用して、圧縮された.gzテキストファイルを編集します
少し古いですが、それはまだ役に立つかもしれないと考えています...
私は@Donの答えが好きでした( https://stackoverflow.com/a/26379517/1446005 )が、最初に別のファイルに書き込む必要があるのは非常に迷惑です...
私の特定のケースでは、これには時間がかかりすぎ、ディスクスペースがかかります
そこで、私は小さなbashスクリプトを書きました。
#!/bin/bash
tables=(table1_to_skip table2_to_skip ... tableN_to_skip)
tableString=$(printf "|%s" "${tables[@]}")
trimmed=${tableString:1}
grepExp="INSERT INTO \`($trimmed)\`"
zcat $1 | grep -vE "$grepExp" | mysql -uroot -p
これは新しいSQLスクリプトを生成しませんが、データベースに直接パイプします
また、テーブルを作成しますが、データはインポートしません(巨大なログテーブルで問題になりました)
mysqldump --ignore-table=database.unwanted_table
を使用してダンプ中にテーブルを無視した場合を除き、スクリプトまたはツールを使用して、mysql
クライアントに渡す前にダンプファイルからインポートしたくないデータを除外する必要があります。 。
不要なテーブルをその場で(パイプ経由で)SQLダンプから除外するbash/sh関数を次に示します。
# Accepts one argument, the list of tables to exclude (case-insensitive).
# Eg. filt_exclude '%session% action_log %_cache'
filt_exclude() {
local excl_tns;
if [ -n "$1" ]; then
# trim & replace /[,;\s]+/ with '|' & replace '%' with '[^`]*'
excl_tns=$(echo "$1" | sed -r 's/^[[:space:]]*//g; s/[[:space:]]*$//g; s/[[:space:]]+/|/g; s/[,;]+/|/g; s/%/[^\`]\*/g');
grep -viE "(^INSERT INTO \`($excl_tns)\`)|(^DROP TABLE (IF EXISTS )?\`($excl_tns)\`)|^LOCK TABLES \`($excl_tns)\` WRITE" | \
sed 's/^CREATE TABLE `/CREATE TABLE IF NOT EXISTS `/g'
else
cat
fi
}
次のように作成されたダンプがあるとします。
MYSQL_PWD="my-pass" mysqldump -u user --hex-blob db_name | \
pigz -9 > dump.sql.gz
そして、インポートする前にいくつかの不要なテーブルを除外したい:
pigz -dckq dump.sql.gz | \
filt_exclude '%session% action_log %_cache' | \
MYSQL_PWD="my-pass" mysql -u user db_name
または、DBにインポートする前に、ファイルまたは他のツールにパイプすることができます。
本番環境では使用しませんが、インポートに数時間かかる可能性のある多くの小さなテーブルと1つの大きなモンスターテーブルを含むバックアップをすばやくインポートする必要がある場合、「grep -v望ましくないテーブル名original.sql>還元.sql
そして、mysql -f <還元.sql