dump all mysql tables into separate files automagically?

后端 未结 10 901
北恋
北恋 2020-11-29 20:21

I\'d like to get dumps of each mysql table into separate files. The manual indicates that the syntax for this is

mysqldump [options] db_name [tbl_name ...]
         


        
相关标签:
10条回答
  • 2020-11-29 20:38

    You can accomplish this by:

    1. Get the list of databases in mysql
    2. dump each database with mysqldump
    # Optional variables for a backup script
    MYSQL_USER="root"
    MYSQL_PASS="something"
    BACKUP_DIR=/srv/backup/$(date +%Y-%m-%dT%H_%M_%S);
    test -d "$BACKUP_DIR" || mkdir -p "$BACKUP_DIR"
    # Get the database list, exclude information_schema
    for db in $(mysql -B -s -u $MYSQL_USER --password=$MYSQL_PASS -e 'show databases' | grep -v information_schema)
    do
      # dump each database in a separate file
      mysqldump -u $MYSQL_USER --password=$MYSQL_PASS "$db" | gzip > "$BACKUP_DIR/$db.sql.gz"
    done
    
    0 讨论(0)
  • 2020-11-29 20:41

    I'm not bash master, but I'd just do it with a bash script. Without hitting MySQL, with knowledge of the data directory and database name, you could just scan for all .frm files (one for every table in that db/directory) for a list of tables.

    I'm sure there are ways to make it slicker and accept arguments or whatnot, but this worked well for me.

    tables_in_a_db_to_sql.sh

    #!/bin/bash
    
    database="this_is_my_database"
    datadir="/var/lib/mysql/"
    datadir_escaped="\/var\/lib\/mysql\/"
    
    all_tables=($(ls $datadir$database/*.frm | sed s/"$datadir_escaped$database\/"/""/g | sed s/.frm//g))
    
    for t in "${all_tables[@]}"; do
            outfile=$database.$t.sql
            echo "-- backing up $t to $outfile"
            echo "mysqldump [options] $database $t > $outfile"
            # mysqldump [options] $database $t > $outfile
    done
    

    Fill in the [options] and desired outfile convention as you need, and uncomment the last mysqldump line.

    0 讨论(0)
  • 2020-11-29 20:43

    Here's a script that dumps table data as SQL commands into separate, compressed files. It does not require being on the MySQL server host, doesn't hard-code the password in the script, and is just for a specific db, not all db's on the server:

    #!/bin/bash
    
    # dump-tables-mysql.sh
    # Descr: Dump MySQL table data into separate SQL files for a specified database.
    # Usage: Run without args for usage info.
    # Author: @Trutane
    # Ref: http://stackoverflow.com/q/3669121/138325
    # Notes:
    #  * Script will prompt for password for db access.
    #  * Output files are compressed and saved in the current working dir, unless DIR is
    #    specified on command-line.
    
    [ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1
    
    DB_host=$1
    DB_user=$2
    DB=$3
    DIR=$4
    
    [ -n "$DIR" ] || DIR=.
    test -d $DIR || mkdir -p $DIR
    
    echo -n "DB password: "
    read -s DB_pass
    echo
    echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"
    
    tbl_count=0
    
    for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
    do 
        echo "DUMPING TABLE: $DB.$t"
        mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t | gzip > $DIR/$DB.$t.sql.gz
        tbl_count=$(( tbl_count + 1 ))
    done
    
    echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"
    
    0 讨论(0)
  • 2020-11-29 20:45

    See the following article by Pauli Marcus:

    Howto split a SQL database dump into table-wise files

    Splitting a sql file containing a whole database into per-table files is quite easy: Grep the .sql for any occurence of DROP TABLE. Generate the file name from the table name that is included in the DROP TABLE statement. Echo the output to a file. Here is a little script that expects a .sql file as input:

    #!/bin/bash
    
    file=$1 # the input file
    directory="$file-splitted" # the output directory
    output="$directory/header" # the first file containing the header
    GREP="DROP TABLE" # what we are looking for
    
    mkdir $directory # create the output directory
    
    while read line
    do
       # if the current line contains the wanted statement
       if [ $(echo "$line" | grep -c "$GREP") == "1" ]
       then
          # extract the file name
          myfile=$(echo $line | awk '{print $5}' | sed -e 's/`//g' -e 's/;//g')
          # set the new file name
          output="$directory/$myfile"
       fi
           echo "$line" >> $output # write to file
    done < $file
    
    0 讨论(0)
  • 2020-11-29 20:46

    If You want to dump all tables from all databases just combine Elias Torres Arroyo's and Trutane's answer: And if You don't want to give Your password on terminal, just store Your password in an extra config file (chmod 0600)- see Mysqldump launched by cron and password security

    #!/bin/bash
    
    # this file
    # a) gets all databases from mysql
    # b) gets all tables from all databases in a)
    # c) creates subfolders for every database in a)
    # d) dumps every table from b) in a single file
    
        # this is a mixture of scripts from Trutane (http://stackoverflow.com/q/3669121/138325) 
        # and Elias Torres Arroyo (https://stackoverflow.com/a/14711298/8398149)
    
    # usage: 
    # sk-db.bash parameters
    # where pararmeters are:
    
    # d "dbs to leave"
    # t " tables to leave"
    # u "user who connects to database"
    # h "db host"
    # f "/backup/folder"
    
    
    
    user='root'
    host='localhost'
    backup_folder=''
    leave_dbs=(information_schema mysql)
    leave_tables=()
    while getopts ":d:t:u:h:f:" opt; do
      case $opt in
        d) leave_dbs=( $OPTARG )
        ;;
        t) leave_tables=( $OPTARG )
        ;;
        u) user=$OPTARG
        ;;
        h) host=$OPTARG
        ;;
        f) backup_folder=$OPTARG
        ;;
    
        \?) echo "Invalid option -$OPTARG" >&2
        ;;
      esac
    done
    echo '****************************************'
    echo "Database Backup with these options"
    echo "Host $host"
    echo "User $user"
    echo "Backup in $backup_folder"
    echo '----------------------------------------'
    echo "Databases to emit:"
    printf "%s\n" "${leave_dbs[@]}"
    echo '----------------------------------------'
    echo "Tables to emit:"
    printf "%s\n" "${leave_tables[@]}"
    echo '----------------------------------------'
    
    
    BACKUP_DIR=$backup_folder/$(date +%Y-%m-%dT%H_%M_%S);
    CONFIG_FILE=/root/db-config.cnf
    
    function contains() {
        local n=$#
        local value=${!n}
        for ((i=1;i < $#;i++)) {
            if [ "${!i}" == "${value}" ]; then
                echo "y"
                return 0
            fi
        }
        echo "n"
        return 1
    }
    
    
    test -d "$BACKUP_DIR" || mkdir -p "$BACKUP_DIR"
    # Get the database list, exclude information_schema
    database_count=0
    tbl_count=0
    
    for db in $(mysql --defaults-extra-file=$CONFIG_FILE -B -s -u $user -e 'show databases' )
    do
        if [ $(contains "${leave_dbs[@]}" "$db") == "y" ]; then
            echo "leave database $db as requested"
        else
    
           # dump each database in a separate file
           (( database_count++ ))
           DIR=$BACKUP_DIR/$db
           [ -n "$DIR" ] || DIR=.
    
           test -d $DIR || mkdir -p $DIR
    
           echo
           echo "Dumping tables into separate SQL command files for database '$db' into dir=$DIR"
    
           for t in $(mysql --defaults-extra-file=$CONFIG_FILE -NBA -h $host -u $user -D $db -e 'show tables')
           do
               if [ $(contains "${leave_tables[@]}" "$db.$t") == "y" ]; then
                   echo "leave table $db.$t as requested"
               else
                   echo "DUMPING TABLE: $db.$t"
      #            mysqldump --defaults-extra-file=$CONFIG_FILE -h $host -u $user $db $t  > $DIR/$db.$t.sql
                   tbl_count=$(( tbl_count + 1 ))
               fi
           done
    
           echo "Database $db is finished"
           echo '----------------------------------------'
    
        fi
    done
    echo '----------------------------------------'
    echo "Backup completed"
    echo '**********************************************'
    

    And also, this helped:

    Check if bash array contains value

    arrays in bash

    named arguments in script

    0 讨论(0)
  • 2020-11-29 20:50

    Here is the corresponding import.

    #!/bin/bash
    
    # import-files-mysql.sh
    # Descr: Import separate SQL files for a specified database.
    # Usage: Run without args for usage info.
    # Author: Will Rubel
    # Notes:
    #  * Script will prompt for password for db access.
    
    [ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1
    
    DB_host=$1
    DB_user=$2
    DB=$3
    DIR=$4
    
    DIR=$DIR/*
    
    
    echo -n "DB password: "
    read -s DB_pass
    echo
    echo "Importing separate SQL command files for database '$DB' into '$DB'"
    
    file_count=0
    
    
    for f in $DIR
    
    do 
        echo "IMPORTING FILE: $f"
    
        gunzip -c $f | mysql -h $DB_host -u $DB_user -p$DB_pass $DB
    
        (( file_count++ ))
    done
    
    echo "$file_count files importing to database '$DB'"
    
    0 讨论(0)
提交回复
热议问题