如何在导入数据库时忽略某些MySQL表?

xv8emn3q  于 2023-03-11  发布在  Mysql
关注(0)|答案(9)|浏览(365)

我有一个包含一个数据库和大约150个表的大型SQL文件。我希望使用mysqlimport导入该数据库,但是,我希望导入过程忽略或跳过几个表。导入所有表但忽略其中一些表的正确语法是什么?谢谢。

unhi4e5o

unhi4e5o1#

RandomSeed接受的答案可能需要很长时间!导入表(只是为了稍后删除它)可能会非常浪费,具体取决于大小。
对于使用创建的文件

mysqldump -u user -ppasswd --opt --routines DBname > DBdump.sql

我现在得到一个大约7 GB的文件,其中6 GB是我不需要的日志表的数据;重新加载这个文件需要几个小时。2如果我需要重新加载(为了开发目的,或者如果需要实时恢复),我会这样浏览这个文件:

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

有一个“陷阱”--注意转储中可能包含“INSERT INTO TABLE_TO_SKIP”的过程。

5us2dqdw

5us2dqdw2#

mysqlimport不是导入SQL语句的合适工具。此工具旨在导入CSV等格式化文本文件。您需要做的是使用以下命令将SQL转储直接提供给mysql客户端:

bash > mysql -D your_database < your_sql_dump.sql

mysqlmysqlimport都没有提供您需要的特性,最好的办法是导入整个转储,然后删除不需要的表。
如果您可以访问转储文件所在的服务器,则可以使用mysqldump --ignore-table=database.table_you_dont_want1 --ignore-table=database.table_you_dont_want2 ...创建新的转储文件。

  • 一个月一次 *
wh6knrhe

wh6knrhe3#

对于任何使用. sql.gz文件的人;我发现下面的解决方案非常有用。我们的数据库是25 GB+,我不得不删除日志表。

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"

感谢唐的回答和评论Xosofox和这个相关的职位:Use zcat and sed or awk to edit compressed .gz text file

du7egjpx

du7egjpx4#

有点旧了,不过我想还是会派上用场的...
我喜欢@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脚本,而是将其直接通过管道传输到数据库
此外,它确实创建了表,只是不导入数据(这是我在使用大型日志表时遇到的问题)

carvr3hs

carvr3hs5#

除非在使用mysqldump --ignore-table=database.unwanted_table转储时忽略了这些表,否则必须使用一些脚本或工具从转储文件中过滤掉不想导入的数据,然后再将其传递给mysql客户机。
下面是一个bash/sh函数,它可以动态地(通过管道)从SQL转储中排除不需要的表:

# 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之前通过管道导入文件或任何其他工具。

kknvjkwl

kknvjkwl6#

如果需要,可以一次对一个表执行此操作:

mysqldump -p sourceDatabase tableName > tableName.sql
mysql -p -D targetDatabase < tableName.sql
vi4fp9gy

vi4fp9gy7#

这是我的脚本,以排除一些表从mysql转储我用它来恢复数据库时,需要保持订单和付款数据

从转储.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

它避免了表的删除和重新创建,避免了向表中插入数据,并且剥离了所有存储在DELIMITER之间的函数和过程;;和定界器;

djmepvbi

djmepvbi8#

我不会在生产环境中使用它,但如果我必须快速导入一些备份,其中包含许多较小的表和一个可能需要数小时才能导入的大型表,我很可能会使用“grep -v unwanted_table_name original.sql〉reduced.sql
然后是mysql-f

xmq68pz9

xmq68pz99#

除了这个主题中的伟大答案,它可能是你的.sql文件没有与这每行的INSERT:

INSERT INTO `log`

但它们实际上是这样插入的:

LOCK TABLES `log` WRITE;

INSERT INTO `log` (`id`, `data`)
VALUES
  (1,'The log content'),
  (2,'The log content'),
  (3,'The log content'),
  (4,'The log content')
    
UNLOCK TABLES;

您需要排除LOCK TABLESlogWRITE;和下一个UNLOCK TABLES;之间的所有内容

gzip -dc "$1" | sed \
-e '/LOCK TABLES `log` WRITE;/,/^UNLOCK TABLES/d;' \
-e '/LOCK TABLES `some_other_table` WRITE;/,/^UNLOCK TABLES/d;' \
| gzip > reduced_$(date '+%F_%T').sql.gz

把它放在你电脑上的reduce_db. sh文件中,每次你需要它的时候,你就这样执行它

bash /folder/to/reduce_db.sh /path/to/big_db_file.sql.gz

最好只排除数据库中其他数据不依赖的数据,否则缩减后的数据库最终会不一致。

相关问题