Ignorer certaines tables avec mysqldump

559

Existe-t-il un moyen de restreindre certaines tables à partir de la commande mysqldump?

Par exemple, j'utiliserais la syntaxe suivante pour vider uniquement table1 et table2:

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

Mais existe-t-il un moyen similaire de vider toutes les tables sauf table1 et table2? Je n'ai rien trouvé dans la documentation mysqldump, donc la force brute (en spécifiant tous les noms de table) est-elle la seule solution?

Zac
la source

Réponses:

942

Vous pouvez utiliser l' option --ignore-table . Donc tu pourrais faire

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

Il n'y a pas d'espaces après -p (ce n'est pas une faute de frappe).

Si vous souhaitez ignorer plusieurs tables, vous pouvez utiliser un script simple comme celui-ci

#!/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}
Paul Sheldrake
la source
4
Je vous remercie! A parfaitement fonctionné ... Je ne sais pas comment j'ai raté ça.
Zac
20
existe-t-il un moyen de sauter le contenu du tableau? la structure que je veux sauvegarder.
Andres SK
5
Vous pouvez utiliser l'option --no-data = true, mais je ne sais pas si vous pouvez le faire au niveau de chaque table.
Brian Fisher
60
si le nom de la base de données n'est pas défini pour chaque --ignore-table, vous obtiendrez une erreur «Utilisation illégale de l'option --ignore-table = <base de données>. <table>». Assurez-vous de toujours déclarer la base de données!
supajb
26
si vous voulez ignorer certaines données de tables, mais toujours vider leur structure, vous pouvez réexécuter mysqldump pour ces tables et les concaténer sur la sauvegarde que vous venez de créer
carpii
119

En s'appuyant sur la réponse de @ Brian-Fisher et en répondant aux commentaires de certaines personnes sur ce post, j'ai un tas d'énormes tables (et inutiles) dans ma base de données, donc je voulais ignorer leur contenu lors de la copie, mais garder la structure :

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

Les deux fichiers résultants sont structurellement solides, mais les données sous-évaluées sont désormais d'environ 500 Mo au lieu de 9 Go, ce qui est bien mieux pour moi. Je peux maintenant importer ces deux fichiers dans une autre base de données à des fins de test sans avoir à me soucier de manipuler 9 Go de données ou de manquer d'espace disque.

DuffJ
la source
Testé et utilisé sous MySQL 5.5.43 (pour debian-linux-gnu (x86_64)) Merci
Abdel
Simple et élégant. Une excellente solution.
Greg Glockner
4
excellente solution. J'ai dû ajouter --skip-triggers à la deuxième instruction pour que le vidage fonctionne plus tard (en supposant que vous ayez des déclencheurs), mais sinon: parfait
Rainer Mohr
Merci, cela fonctionne et est très utile.
Himalaya Garg
59

pour plusieurs bases de données:

mysqldump -u user -p --ignore-table=db1.tbl1 --ignore-table=db2.tbl1 --databases db1 db2 ..
utilisateur1219736
la source
5
Il y a déjà une réponse à ce fil qui dit que c'est mieux.
alxgb
19
C'est vrai, mais cette solution fonctionne avec plusieurs bases de données.
Alex
Intéressant - j'ai d'abord pensé mysqldet mysqldumpserait les mêmes programmes.
Martin Thoma
4
c'est ce que je recherche - une réponse à une ligne avec la solution qui ne m'oblige pas à lire quelque chose pendant 2-3 minutes: P
jebbie
43

Un autre exemple pour ignorer plusieurs tables

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

utiliser --ignore-tableet créer un tableau de tables, avec des syntaxes commedatabase.table

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

Liens avec des informations qui vous aideront

compresser la sortie mysqldump

Remarque: testé sur le serveur ubuntu avec mysql Ver 14.14 Distrib 5.5.55

Importer une base de données

 mysql -uUSER  -pPASS db_test < db_test.sql

Script simple pour ignorer les tables

#!/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
DarckBlezzer
la source
Excellent moyen d'éviter d'utiliser un script lorsque vous souhaitez ignorer plusieurs tables. Cette réponse devrait recevoir plus de "+1"
svfat
réponse parfaite !!! +1 a fait ma journée :)
SagarPPanchal
7

Pour exclure certaines données de table , mais pas la structure de la table . Voici comment je le fais:

Vider la structure de la base de données de toutes les tables, sans aucune donnée:

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

Vider ensuite la base de données avec des données, à l'exception des tables exclues, et ne pas vider la structure:

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

Ensuite, pour le charger dans une nouvelle base de données:

mysql -u user -p newdatabase < database_structure.sql
mysql -u user -p newdatabase < database_data.sql
Benedikt Köppel
la source
1

Vous pouvez utiliser la mysqlpumpcommande avec le

--exclude-tables=name

commander. Il spécifie une liste de tables séparées par des virgules à exclure.

La syntaxe de mysqlpump est très similaire à mysqldump, mais sa manière est plus performante. Plus d'informations sur la façon d'utiliser l'option d'exclusion que vous pouvez lire ici: https://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#mysqlpump-filtering

ThorstenC
la source
0

Vider toutes les bases de données avec toutes les tables mais ignorer certaines tables

sur 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

Avec un peu d'aide de https://stackoverflow.com/a/17016410/1069083

Il utilise lzop qui est beaucoup plus rapide, voir: http://pokecraft.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

rubo77
la source
Le document que vous partagez indique que gzip est plus rapide que lzop.
jrosell
0

J'aime la solution de Rubo77, je ne l'avais pas vue avant de modifier celle de Paul. Celui-ci sauvegarde une seule base de données, à l'exclusion de toutes les tables dont vous ne voulez pas. Il le compressera ensuite et supprimera tous les fichiers de plus de 8 jours. J'utiliserai probablement 2 versions de cela qui font une table complète (moins les journaux) une fois par jour, et une autre qui sauvegarde simplement les tables les plus importantes qui changent le plus chaque heure en utilisant quelques tâches 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
Alan
la source
0

Par souci d'exhaustivité, voici un script qui pourrait en fait être une ligne pour obtenir une sauvegarde à partir d'une base de données, excluant (ignorant) toutes les vues. Le nom de la base de données est supposé être des employés:

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"   

Vous pouvez mettre à jour la logique de la requête. En général, en utilisant group_concatet concatvous pouvez générer presque n'importe quelle chaîne ou commande shell souhaitée.

hpaknia
la source
0

En général, vous devez utiliser cette fonctionnalité lorsque vous ne voulez pas ou n'avez pas le temps de traiter une énorme table. Si tel est votre cas, il est préférable d'utiliser l'option --where de mysqldump limitant le jeu de résultats. Par exemple mysqldump -uuser -ppass database --where="1 = 1 LIMIT 500000" > resultset.sql,.

mpoletto
la source