【问题标题】:mysql dump - exclude some table datamysql dump - 排除一些表数据
【发布时间】:2012-11-15 14:24:23
【问题描述】:

是否可以,使用mysql dump 导出整个数据库结构,但排除某些表数据导出。

假设数据库有 200 个表,我希望导出所有 200 个表的结构,但我想忽略 5 个特定表的数据。

如果可以的话,是怎么做到的?

【问题讨论】:

  • 我认为您需要进行两次备份 - 一次仅包含所有表的结构,另一次仅包含除 5 个表之外的所有表的数据。
  • 但是您可能会面临结果不一致的风险。
  • Marty,请帮助论坛。看看下面@Kantholy 的答案,并强烈考虑将其作为公认的答案。你接受的那个不是最有用的,甚至不是最相关的。

标签: mysql


【解决方案1】:

根据mysqldump docs

mysqldump name_of_db --ignore-table=name_of_db.name_of_table

【讨论】:

  • 只是要忽略的数据,我需要结构
  • 然后只使用结构进行一次转储 (--no-data),然后再进行一次转储,跳过结构但转储并跳过不需要的表。或者您只需在全局转储末尾附加一些 delete from ... 查询以从表中删除数据。
  • 是的,所以导出所有数据,存储所有数据,导入所有数据,然后删除。一个奇怪的排斥定义。
  • 这个答案并没有真正满足 OP 的要求(即转储所有表的结构,但跳过一个表的数据)
  • 是的,不是所要求的,我喜欢 AmitP 的回答,因为它可以在一个命令中使用并生成一个文件
【解决方案2】:

这将生成export.sql,其中包含所有表的结构和除table_name 之外的所有表的数据

mysqldump --ignore-table=db_name.table_name db_name > export.sql
mysqldump --no-data db_name table_name >> export.sql

【讨论】:

  • 非常适合 bash 脚本 :) 谢谢
  • 这是一个更好的答案,因为它跳过了不需要的数据但得到了想要的模式,我喜欢它仍然制作一个文件。请注意,您可以多次使用--ignore-table 选项来忽略多个表。
  • 这个 export.sql 将创建一个带有空表的数据库。调用应该以另一种方式执行:首先是带有--no-data 的调用,然后是带有--ignore-table 的调用
  • @cheneym 第一个命令只是将整个数据库转储到 export.sql,不包括名为“table_name”的表。第二个命令只是添加了“table_name”的结构而没有它的数据。请对其进行测试,看看它是如何工作的,或者至少解释一下你关于空表的陈述。
  • 对于多个表:mysqldump ---ignore-table=db_name.table1 --ignore-table=db_name.table2 [...] db_name > export.sql
【解决方案3】:

我认为 AmitP 的解决方案已经很棒 - 为了进一步改进它,我认为首先创建所有表(结构)然后用数据填充它是有意义的,除了“排除”的那些

mysqldump --no-data db_name > export.sql
mysqldump --no-create-info --ignore-table=db_name.table_name db_name >> export.sql

如果您想排除超过 1 个表,只需更频繁地使用 --ignore-tabledirective(在 2nc 命令中) - 请参阅 mysqldump 帮助:

--ignore-table=name   Do not dump the specified table. To specify more than one
                      table to ignore, use the directive multiple times, once
                      for each table.  Each table must be specified with both
                      database and table names, e.g.,
                     --ignore-table=database.table

【讨论】:

  • @dspjm,你能解释一下为什么这个答案不如 AmitP 的答案吗? :)
  • 事实上,这远远优于 AmitP 的答案。如果需要,这是解决问题并创建具有更可读顺序的文件的更合乎逻辑的方法。
  • 我同意这个答案比 AmitP 的更好,但它有一个相同的问题,即如果将一行添加到两个 mysqldump 之间的表中,存储在架构部分中的自动增量值将不正确。我不确定是否有一个“真正的”解决方案......
  • @Mala 在之前执行:FLUSH TABLES WITH READ LOCK; 在之后执行:UNLOCK TABLES;
  • @kantholy 我明白了。这不会导致应用程序在数据库转储期间无响应吗?
【解决方案4】:

我是新用户,没有足够的声誉来投票或评论答案,所以我只是将其作为答案分享。

@kantholy 显然有最好的答案。

@AmitP 的方法将所有结构和data 转储到file,最后是drop/create table 语句。生成的文件仍然需要您 import 处理所有不需要的数据,然后再将其销毁。

@kantholy 的方法首先转储所有结构,然后只转储data 用于您不忽略的table。这意味着您以后的import 将不必花时间去import 所有您不想要的data - 如果您有大量的data 要忽略以节省时间,这一点尤其重要。

总结一下,最有效的答案是:

mysqldump --no-data db_name > export.sql
mysqldump --no-create-info --ignore-table=db_name.table_name1 [--ignore-table=db_name.table_name2, ...] db_name >> export.sql

【讨论】:

  • 我很困惑,你在这个问答中添加了什么?这里没有 50 个答案需要用另一个答案来总结。有 3 个答案,其中两个非常相似,任何登陆这里寻找解决方案的人都可以轻松阅读。你不能评论太糟糕了,但老实说,即使你可以,这甚至不属于评论。这只是增加噪音。
【解决方案5】:

我使用的另一种可能性是避免将数据插入所需表的行。

原理是使用grep -v

过滤掉INSERT INTO
mysqldump name_of_db | grep -v 'INSERT INTO \`name_of_table\` VALUES'

mysqldump name_of_db | grep -v 'INSERT INTO \`name_of_db\`.\`name_of_table\` VALUES'

您可以轻松进入 gzip 文件和单独的错误文件

mysqldump name_of_db | grep -v 'INSERT INTO \`name_of_db\`.\`name_of_table\`' | gzip > /path/dumpfile.sql.gz 2> /path/name_of_db.err

因此可以很好地备份您想要的内容,并知道失败的原因(如果有的话):-)

【讨论】:

    【解决方案6】:

    当我们导出结构并且没有显示如何导出表格中的某些特定数据时,以前的答案无法解决 AUTO_INCREMENT 的问题。

    要走得更远,我们必须做到:

    1/ 导出结构

    mysqldump --no-data db_name | sed 's/ AUTO_INCREMENT=[0-9]*\b//g' > export-structure.sql
    

    2/ 仅导出数据并忽略某些表格

    mysqldump --no-create-info --ignore-table=db_name.table_name1 [--ignore-table=db_name.table_name2, ...] db_name >> export-data.sql
    

    3/ 将特定数据导出到一张表中

    mysqldump --no-create-info --tables table_name --where="id not in ('1', '2', ...)" > export-table_name-data.sql
    

    我尝试使用--skip-opt 选项重置AUTO_INCREMENT,但这也删除了字段上的AUTO_INCREMENT 定义,CHARSETother things

    【讨论】:

      【解决方案7】:

      在我看来,最好的答案来自 Steak,这是唯一真正适用于任何情况的答案。

      所有表明两个转储错误的答案,或者至少它们可以在某些前提下工作。

      正如上面许多人指出的那样,您可能会遇到序列问题。

      但我发现更关键数据库可以具有验证或处理信息的触发器(假设一个触发器在插入表 A 时在表 B 上插入记录) - 在这种情况下,序列创建完整架构(包括触发器)然后插入数据将创建一组不同的结果。

      【讨论】:

        【解决方案8】:

        为了进一步改进kantholy's answer,添加压缩并通过不写入未压缩数据来删除大部分磁盘写入:

        #!/bin/bash
        echo -n "db name:"
        read -r db_name
        echo -n "username:"
        read -r username
        echo -n "Exclude data from table:"
        read -r exclude_table_data
        
        {
         mysqldump "$db_name" --user="$username" --password --no-tablespaces --no-data \
         && \
         mysqldump "$db_name" --user="$username" --password --no-tablespaces --no-create-info \
         --ignore-table="${db_name}.${exclude_table_data}";
        } \
        | bzip2 -c9 \
        > "${db_name}_$(date +%y%m%d_%H%M).sql.bz2"
        

        【讨论】:

          【解决方案9】:

          在来自 MariaDB 10.1 或更高版本的mysqldump 中,您可以使用--ignore-table-data

          mysqldump --ignore-table-data="db_name.table" db_name > export.sql
          

          对于多个表,重复--ignore-table-data 选项:

          mysqldump --ignore-table-data="db_name.table_1" --ignore-table-data="db_name.table_2" db_name > export.sql
          

          来自MariaDB mysqldump docs

          --ignore-table-data=name

          不要转储指定的表数据(仅转储结构)。要指定要忽略的多个表,请多次使用该指令,每个表一次。每个表都必须指定数据库和表名。从 MariaDB 10.1.46、MariaDB 10.2.33、MariaDB 10.3.24、MariaDB 10.4.14 和 MariaDB 10.5.3。另见 --no-data。

          【讨论】:

            猜你喜欢
            • 2018-02-20
            • 1970-01-01
            • 1970-01-01
            • 2016-04-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多