【问题标题】:Skip certain tables with mysqldump使用 mysqldump 跳过某些表
【发布时间】:2010-09-30 07:45:14
【问题描述】:

有没有办法通过 mysqldump 命令限制某些表?

例如,我会使用以下语法转储 only table1 和 table2:

mysqldump -u username -p database table1 table2 > database.sql

但是有没有类似的方法来转储所有的表除了 table1 和 table2?我在 mysqldump 文档中没有找到任何内容,那么暴力破解(指定所有表名)是唯一的方法吗?

【问题讨论】:

    标签: sql mysql database mysqldump


    【解决方案1】:

    您可以使用--ignore-table 选项。所以你可以这样做

    mysqldump -u USERNAME -pPASSWORD DATABASE --ignore-table=DATABASE.table1 > database.sql
    

    -p 后面没有空格(这不是错字)。

    要忽略多个表,请多次使用此选项,据记录,此选项自 at least version 5.0 起有效。

    如果您想要另一种方法来忽略多个表,您可以使用如下脚本:

    #!/bin/bash
    PASSWORD=XXXXXX
    HOST=XXXXXX
    USER=XXXXXX
    DATABASE=databasename
    DB_FILE=dump.sql
    EXCLUDED_TABLES=(
    table1
    table2
    table3
    table4
    tableN   
    )
     
    IGNORED_TABLES_STRING=''
    for TABLE in "${EXCLUDED_TABLES[@]}"
    do :
       IGNORED_TABLES_STRING+=" --ignore-table=${DATABASE}.${TABLE}"
    done
    
    echo "Dump structure"
    mysqldump --host=${HOST} --user=${USER} --password=${PASSWORD} --single-transaction --no-data --routines ${DATABASE} > ${DB_FILE}
    
    echo "Dump content"
    mysqldump --host=${HOST} --user=${USER} --password=${PASSWORD} ${DATABASE} --no-create-info --skip-triggers ${IGNORED_TABLES_STRING} >> ${DB_FILE}
    

    【讨论】:

    • 谢谢!完美地工作......我不知道我是怎么错过的。
    • 有什么办法可以跳过表格内容吗?我要备份的结构。
    • 您可以使用 --no-data=true 选项,但我不知道您是否可以在每个表级别上这样做。
    • 如果没有为每个 --ignore-table 设置数据库名称,那么您将收到“非法使用选项 --ignore-table=.”错误。确保您始终声明数据库!
    • 如果你想忽略一些表数据,但仍然转储它们的结构,你可以对这些表再次运行 mysqldump,并将其连接到刚刚创建的备份中
    【解决方案2】:

    对于多个数据库:

    mysqldump -u user -p --ignore-table=db1.tbl1 --ignore-table=db2.tbl1 --databases db1 db2 ..
    

    【讨论】:

    • 已经有一个回复这个帖子说,更好。
    • 没错,但此解决方案适用于多个数据库。
    • 有趣 - 我首先认为 mysqldmysqldump 将是相同的程序。
    • 这就是我正在寻找的 - 解决方案的单行答案,不会强迫我阅读 2-3 分钟的内容:P
    【解决方案3】:

    基于@Brian-Fisher 的回答并回答了这篇文章中一些人的 cmets,我的数据库中有一堆巨大的(且不必要的)表,所以我想在复制时跳过它们的内容,但是保持结构:

    mysqldump -h <host> -u <username> -p <schema> --no-data > db-structure.sql
    mysqldump -h <host> -u <username> -p <schema> --no-create-info --ignore-table=schema.table1 --ignore-table=schema.table2 > db-data.sql
    

    生成的两个文件结构合理,但转储的数据现在约为 500MB 而不是 9GB,这对我来说要好得多。我现在可以将这两个文件导入另一个数据库进行测试,而不必担心操作 9GB 数据或耗尽磁盘空间。

    【讨论】:

    • 在 MySQL 5.5.43 下测试和使用(对于 debian-linux-gnu (x86_64))谢谢
    • 简洁优雅。一个很好的解决方案。
    • 很好的解决方案。我必须在第二个语句中添加 --skip-triggers 以便转储稍后工作(假设您有触发器),但除此之外:完美
    【解决方案4】:

    使用所有表转储所有数据库,但跳过某些表

    在github上:https://github.com/rubo77/mysql-backup.sh/blob/master/mysql-backup.sh

    #!/bin/bash
    # mysql-backup.sh
    
    if [ -z "$1" ] ; then
      echo
      echo "ERROR: root password Parameter missing."
      exit
    fi
    DB_host=localhost
    MYSQL_USER=root
    MYSQL_PASS=$1
    MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
    #MYSQL_CONN=""
    
    BACKUP_DIR=/backup/mysql/
    
    mkdir $BACKUP_DIR -p
    
    MYSQLPATH=/var/lib/mysql/
    
    IGNORE="database1.table1, database1.table2, database2.table1,"
    
    # strpos $1 $2 [$3]
    # strpos haystack needle [optional offset of an input string]
    strpos()
    {
        local str=${1}
        local offset=${3}
        if [ -n "${offset}" ]; then
            str=`substr "${str}" ${offset}`
        else
            offset=0
        fi
        str=${str/${2}*/}
        if [ "${#str}" -eq "${#1}" ]; then
            return 0
        fi
        echo $((${#str}+${offset}))
    }
    
    cd $MYSQLPATH
    for i in */; do
        if [ $i != 'performance_schema/' ] ; then 
        DB=`basename "$i"` 
        #echo "backup $DB->$BACKUP_DIR$DB.sql.lzo"
        mysqlcheck "$DB" $MYSQL_CONN --silent --auto-repair >/tmp/tmp_grep_mysql-backup
        grep -E -B1 "note|warning|support|auto_increment|required|locks" /tmp/tmp_grep_mysql-backup>/tmp/tmp_grep_mysql-backup_not
        grep -v "$(cat /tmp/tmp_grep_mysql-backup_not)" /tmp/tmp_grep_mysql-backup
    
        tbl_count=0
        for t in $(mysql -NBA -h $DB_host $MYSQL_CONN -D $DB -e 'show tables') 
        do
          found=$(strpos "$IGNORE" "$DB"."$t,")
          if [ "$found" == "" ] ; then 
            echo "DUMPING TABLE: $DB.$t"
            mysqldump -h $DB_host $MYSQL_CONN $DB $t --events --skip-lock-tables | lzop -3 -f -o $BACKUP_DIR/$DB.$t.sql.lzo
            tbl_count=$(( tbl_count + 1 ))
          fi
        done
        echo "$tbl_count tables dumped from database '$DB' into dir=$BACKUP_DIR"
        fi
    done
    

    https://stackoverflow.com/a/17016410/1069083的帮助下

    它使用lzop,速度更快,见:http://pokecraft.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

    【讨论】:

    • 你分享的文件说 gzip 比 lzop 快。
    【解决方案5】:

    排除某些表数据,但不排除表结构。这是我的做法:

    转储所有表的数据库结构,没有任何数据:

    mysqldump -u user -p --no-data database > database_structure.sql
    

    然后将数据转储到数据库中,排除的表除外,并且不转储结构:

    mysqldump -u user -p --no-create-info \
        --ignore-table=database.table1 \
        --ignore-table=database.table2 database > database_data.sql
    

    然后,将其加载到新数据库中:

    mysql -u user -p newdatabase < database_structure.sql
    mysql -u user -p newdatabase < database_data.sql
    

    【讨论】:

      【解决方案6】:

      忽略多个表的另一个示例

      /usr/bin/mysqldump -uUSER -pPASS --ignore-table={db_test.test1,db_test.test3} db_test> db_test.sql
      

      使用--ignore-table 并创建一个表数组,其语法类似于

      --ignore-table={db_test.table1,db_test.table3,db_test.table4}
      

      额外:

      导入数据库

       # if file is .sql
       mysql -uUSER  -pPASS db_test < backup_database.sql
       # if file is .sql.gz
       gzip -dc < backup_database.sql.gz | mysql -uUSER -pPASSWORD db_test
      

      忽略表格并以 .sql.gz 格式导出以节省空间的简单脚本

      #!/bin/bash
      
      #tables to ignore
      _TIGNORE=(
      my_database.table1
      my_database.table2
      my_database.tablex
      )
      
      #create text for ignore tables
      _TDELIMITED="$(IFS=" "; echo "${_TIGNORE[*]/#/--ignore-table=}")"
      
      #don't forget to include user and password
      /usr/bin/mysqldump -uUSER -pPASSWORD --events ${_TDELIMITED} --databases my_database | gzip -v > backup_database.sql.gz
      

      包含对您有帮助的信息的链接

      注意:在 ubuntu 服务器中使用 mysql Ver 14.14 Distrib 5.5.55 测试

      【讨论】:

      • 当您想忽略多个表时避免使用脚本的好方法。这个答案应该得到更多的“+1”
      【解决方案7】:

      我喜欢 Rubo77 的解决方案,在修改 Paul 的解决方案之前我没见过。这将备份单个数据库,不包括您不想要的任何表。然后它将 gzip 并删除超过 8 天的所有文件。我可能会使用其中的 2 个版本,它们每天执行一次完整(减去日志表),另一个版本仅使用几个 cron 作业备份每小时更改最多的最重要的表。

      #!/bin/sh
      PASSWORD=XXXX
      HOST=127.0.0.1
      USER=root
      DATABASE=MyFavoriteDB
      
      now="$(date +'%d_%m_%Y_%H_%M')"
      filename="${DATABASE}_db_backup_$now"
      backupfolder="/opt/backups/mysql"
      DB_FILE="$backupfolder/$filename"
      logfile="$backupfolder/"backup_log_"$(date +'%Y_%m')".txt
      
      EXCLUDED_TABLES=(
      logs
      )
      IGNORED_TABLES_STRING=''
      for TABLE in "${EXCLUDED_TABLES[@]}"
      do :
         IGNORED_TABLES_STRING+=" --ignore-table=${DATABASE}.${TABLE}"
      done
      
      echo "Dump structure started at $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"
      mysqldump --host=${HOST} --user=${USER} --password=${PASSWORD} --single-transaction --no-data --routines ${DATABASE}  > ${DB_FILE} 
      echo "Dump structure finished at $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"
      echo "Dump content"
      mysqldump --host=${HOST} --user=${USER} --password=${PASSWORD} ${DATABASE} --no-create-info --skip-triggers ${IGNORED_TABLES_STRING} >> ${DB_FILE}
      gzip ${DB_FILE}
      
      find "$backupfolder" -name ${DATABASE}_db_backup_* -mtime +8 -exec rm {} \;
      echo "old files deleted" >> "$logfile"
      echo "operation finished at $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"
      echo "*****************" >> "$logfile"
      exit 0
      

      【讨论】:

        【解决方案8】:

        您可以使用mysqlpump 命令与

        --exclude-tables=name
        

        命令。它指定要排除的表的逗号分隔列表。

        mysqlpump 的语法与 mysqldump 非常相似,但它的性能更高。 有关如何使用排除选项的更多信息,您可以在此处阅读:https://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#mysqlpump-filtering

        【讨论】:

          【解决方案9】:

          为了完整起见,这里有一个脚本,它实际上可以是从数据库中获取备份的单行脚本,不包括(忽略)所有视图。数据库名称假定为员工:

          ignore=$(mysql --login-path=root1 INFORMATION_SCHEMA \
              --skip-column-names --batch \
              -e "select 
                    group_concat(
                      concat('--ignore-table=', table_schema, '.', table_name) SEPARATOR ' '
                    ) 
                  from tables 
                  where table_type = 'VIEW' and table_schema = 'employees'")
          
          mysqldump --login-path=root1 --column-statistics=0 --no-data employees $ignore > "./backups/som_file.sql"   
          

          您可以更新查询的逻辑。一般来说,使用group_concatconcat 可以生成几乎任何所需的字符串或shell 命令。

          【讨论】:

            【解决方案10】:

            一般来说,当您不想或没有时间处理一张巨大的桌子时,您需要使用此功能。如果是这种情况,最好使用 mysqldump 限制结果集中的 --where 选项。例如,mysqldump -uuser -ppass database --where="1 = 1 LIMIT 500000" &gt; resultset.sql

            【讨论】:

              【解决方案11】:

              使用 mysqldump 跳过某些表

              假设某些数据库中有一些测试表,并且您想要 将它们从备份中排除;您可以使用 -- exclude-tables 选项,它将排除具有名称的表 测试所有数据库:

              shell&gt; mysqldump --exclude-tables=test --resultfile=backup_excluding_test.sql

              【讨论】:

              • 在以后的版本中似乎不可用。但是--ignore-table=database.table 是。
              猜你喜欢
              • 2016-12-07
              • 2010-11-18
              • 2020-05-18
              • 2011-07-13
              • 1970-01-01
              • 2020-12-08
              • 1970-01-01
              • 2017-07-20
              • 1970-01-01
              相关资源
              最近更新 更多