Omitir ciertas tablas con mysqldump

559

¿Hay alguna manera de restringir ciertas tablas del comando mysqldump?

Por ejemplo, usaría la siguiente sintaxis para volcar solo table1 y table2:

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

Pero, ¿hay una forma similar de volcar todas las tablas excepto table1 y table2? No he encontrado nada en la documentación de mysqldump, entonces ¿es la fuerza bruta (especificando todos los nombres de las tablas) la única forma de hacerlo?

Zac
fuente

Respuestas:

942

Puede usar la opción --ignore-table . Entonces podrías hacer

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

No hay espacios en blanco después -p(esto no es un error tipográfico).

Si desea ignorar varias tablas, puede usar un script simple como este

#!/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
fuente
44
¡Gracias! Funcionó perfectamente ... No sé cómo me perdí eso.
Zac
20
¿Hay alguna manera de saltear el contenido de la tabla? La estructura que quiero respaldar.
Andres SK
55
Puede usar la opción --no-data = true, pero no sé si puede hacerlo en un nivel por tabla.
Brian Fisher
6060
si el nombre de la base de datos no está configurado para cada --ignore-table, obtendrá el error 'Uso ilegal de la opción --ignore-table = <database>. <table>'. ¡Asegúrese de declarar siempre la base de datos!
supajb
26
Si desea ignorar algunos datos de las tablas, pero todavía volcar su estructura, puede ejecutar mysqldump nuevo fo esas tablas, y concatenarlo en la copia de seguridad que acaba de crear
carpii
119

Basándome en la respuesta de @ Brian-Fisher y respondiendo los comentarios de algunas de las personas en esta publicación, tengo un montón de tablas enormes (e innecesarias) en mi base de datos, así que quería omitir su contenido al copiar, pero mantener la estructura :

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

Los dos archivos resultantes son estructuralmente sólidos, pero los datos volcados ahora son ~ 500 MB en lugar de 9 GB, mucho mejor para mí. Ahora puedo importar estos dos archivos a otra base de datos con fines de prueba sin tener que preocuparme por manipular 9 GB de datos o quedarse sin espacio en disco.

DuffJ
fuente
Probado y utilizado en MySQL 5.5.43 (para debian-linux-gnu (x86_64)) Gracias
Abdel
Simple y elegante Una gran solución
Greg Glockner
44
Gran solución. Tuve que agregar --skip-triggers a la segunda declaración para que el volcado funcione más tarde (suponiendo que tenga activadores), pero de lo contrario: perfecto
Rainer Mohr
Gracias, esto está funcionando y es muy útil.
Himalaya Garg
59

para múltiples bases de datos:

mysqldump -u user -p --ignore-table=db1.tbl1 --ignore-table=db2.tbl1 --databases db1 db2 ..
usuario1219736
fuente
55
Ya hay una respuesta a este hilo que dice eso, mejor.
alxgb
19
Eso es correcto, pero esta solución funciona con múltiples bases de datos.
Alex
Interesante: primero pensé mysqldy mysqldumpserían los mismos programas.
Martin Thoma
44
eso es lo que estoy buscando: una respuesta sencilla con la solución que no me obliga a leer algo durante 2-3 minutos: P
jebbie
43

Otro ejemplo para ignorar varias tablas.

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

usando --ignore-tabley crea una matriz de tablas, con sintaxis comodatabase.table

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

Enlaces con información que lo ayudará

comprimir salida mysqldump

Nota: probado en el servidor ubuntu con mysql Ver 14.14 Distrib 5.5.55

Importar base de datos

 mysql -uUSER  -pPASS db_test < db_test.sql

Script simple para ignorar tablas

#!/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
fuente
Gran manera de evitar el uso de un script cuando desea ignorar varias tablas. Esa respuesta debería recibir más "+1"
svfat
¡¡¡Respuesta perfecta!!! +1 hizo mi día :)
SagarPPanchal 05 de
7

Para excluir algunos datos de la tabla , pero no la estructura de la tabla . Así es como lo hago:

Volcar la estructura de la base de datos de todas las tablas, sin ningún dato:

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

Luego volcar la base de datos con datos, excepto las tablas excluidas, y no volcar la estructura:

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

Luego, para cargarlo en una nueva base de datos:

mysql -u user -p newdatabase < database_structure.sql
mysql -u user -p newdatabase < database_data.sql
Benedikt Köppel
fuente
0

Volcar todas las bases de datos con todas las tablas pero omitir ciertas tablas

en 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

Con un poco de ayuda de https://stackoverflow.com/a/17016410/1069083

Utiliza lzop, que es mucho más rápido, consulte: http://pokecraft.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

rubo77
fuente
El documento que comparte dice que gzip es más rápido que lzop.
jrosell
0

Me gusta la solución de Rubo77, no la había visto antes de modificar la de Paul. Esta copia de seguridad de una sola base de datos, excluyendo cualquier tabla que no desee. Luego lo comprimirá y eliminará los archivos que tengan más de 8 días. Probablemente usaré 2 versiones de esto que hacen una completa (tabla de registros menos) una vez al día, y otra que solo respalda las tablas más importantes que cambian más cada hora usando un par de trabajos 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
fuente
0

En aras de la exhaustividad, aquí hay un script que en realidad podría ser una línea para obtener una copia de seguridad de una base de datos, excluyendo (ignorando) todas las vistas. Se supone que el nombre de db son empleados:

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"   

Puede actualizar la lógica de la consulta. En general , puede usar group_concaty concatpuede generar casi cualquier cadena deseada o comando de shell.

hpaknia
fuente
0

En general, debe usar esta función cuando no quiera o no tenga tiempo para lidiar con una mesa enorme. Si este es su caso, es mejor usar la opción --where desde mysqldump que limita el conjunto de resultados. Por ejemplo, mysqldump -uuser -ppass database --where="1 = 1 LIMIT 500000" > resultset.sql.

mpoletto
fuente