Exécuter MySQLDump sans verrouiller les tables

437

Je souhaite copier une base de données de production en direct dans ma base de données de développement locale. Existe-t-il un moyen de le faire sans verrouiller la base de données de production?

J'utilise actuellement:

mysqldump -u root --password=xxx -h xxx my_db1 | mysql -u root --password=xxx -h localhost my_db1

Mais il verrouille chaque table pendant son exécution.

Greg
la source
Autre solution tardive: vous pouvez également utiliser Percona XtraBackup pour vider votre base de données de production sans interruption concernant le traitement des transactions. Il permet de faire une sauvegarde à chaud, c'est-à-dire qu'il n'affecte pas les activités en cours. Voir ici: percona.com/software/mysql-database/percona-xtrabackup (je n'ai aucune affiliation avec Percona.)
delx

Réponses:

626

L' --lock-tables=falseoption fonctionne-t-elle?

Selon la page de manuel , si vous videz des tables InnoDB, vous pouvez utiliser l' --single-transactionoption:

--lock-tables, -l

Lock all tables before dumping them. The tables are locked with READ
LOCAL to allow concurrent inserts in the case of MyISAM tables. For
transactional tables such as InnoDB and BDB, --single-transaction is
a much better option, because it does not need to lock the tables at
all.

Pour innodb DB :

mysqldump --single-transaction=TRUE -u username -p DB
John Millikin
la source
23
pour innodb DB mysqldump --single-transaction = TRUE -u nom d'utilisateur -p DB
19
Et si vous avez innodb et myisam?
CMCDragonkai
Est-ce activé par défaut?
CMCDragonkai
évidemment sur (c.-à-d. verrouillé)?
evandrix
290

C'est trop tard, mais bon pour tous ceux qui recherchent le sujet. Si vous n'êtes pas innoDB et que vous ne vous inquiétez pas du verrouillage pendant le vidage, utilisez simplement l'option:

--lock-tables=false
Warren Krewenki
la source
1
Merci pour la réponse Warren, cela a été très utile et a fonctionné comme un charme.
Gavin
7
utiliser '--lock-table = false --quick' utilise le moins de ressources du serveur
SyntaxGoonoo
43
Mais vous devriez être inquiet au sujet des tables de verrouillage. Si plusieurs tables sont écrites pendant que mysqldump est en cours d'exécution (et que vous utilisez des clés étrangères), votre vidage peut être incohérent. Vous ne le saurez pas tant que vous ne l'aurez pas restauré et qu'il vous arrivera d'exécuter des requêtes JOIN sur les données incohérentes. La découverte des données incohérentes peut prendre un certain temps car les JOIN sont utilisés par votre application et non par Mysql (avec les tables MyISAM); la restauration fonctionnera très bien, mysql ne vous avertira pas des incohérences. Donc: MyIsam -> verrouille toujours vos tables. InnoDB -> utiliser --single-transaction.
Costa
12
@Costa Je ne pense pas que le verrouillage des tables soit même suffisant pour les tables MyISAM. Si mysqldump verrouille les tables entre les requêtes exécutées par l'application, vous vous retrouvez avec les mêmes incohérences. La réponse est encore plus simple: MyISAM -> utilisez InnoDB à la place.
cdhowie
@Costa, vous devriez certainement vous inquiéter du verrouillage des tables, mais uniquement si vous avez besoin d'un vidage cohérent . Il y a de rares cas où vous ne le faites pas. Par exemple, un fgrep brut sur le vidage à l'échelle de la base de données (débogage): je parie que l'on ne veut pas que les utilisateurs attendent ~ 20 minutes pour créer un vidage de la base de données de production (histoire vraie). Si le but est d'obtenir le vidage non seulement le plus tôt possible, mais également cohérent , il convient de vider l'esclave répliqué ou d'utiliser des instantanés de niveau inférieur (lvm, zfs, btrfs, etc.), en gardant à l'esprit les FLUSH TABLES WITH READ LOCKchoses.
Alex Offshore
44

La réponse varie en fonction du moteur de stockage que vous utilisez. Le scénario idéal est si vous utilisez InnoDB. Dans ce cas, vous pouvez utiliser l' --single-transactionindicateur, qui vous donnera un instantané cohérent de la base de données au moment où le vidage commence.

dvorak
la source
35

--skip-add-locks aidé pour moi

Azamat Tokhtaev
la source
2
ou aussi --compact pour inclure les verrous de saut avec d'autres optimisations.
ppostma1
77
Cela supprime les instructions LOCK TABLES et UNLOCK TABLES du fichier de vidage, cela n'affecte pas le verrouillage pendant l'exportation.
dabest1
11
Non, ce n'est pas ce que vous cherchez! Voir le commentaire de dabest1. Cela ne fait RIEN pour empêcher vos tables de se verrouiller pendant un mysqldump. Ce n'est PAS une réponse à la question.
orrd
@dabest et @orrd sont corrects: --skip-add-locksrendraient simplement la restauration du vidage plus rapide. Ce n'est pas une bonne réponse.
dr_
10

Honnêtement, je configurerais la réplication pour cela, car si vous ne verrouillez pas les tables, vous obtiendrez des données incohérentes du vidage.

Si le vidage prend plus de temps, les tables qui ont déjà été vidées peuvent avoir changé avec une table qui n'est que sur le point d'être vidée.

Donc, verrouillez les tables ou utilisez la réplication.

Mike
la source
L'ensemble de cette base de données est presque entièrement en lecture seule, donc je ne suis pas trop inquiet de son changement.
Greg
2
Ce commentaire est incorrect. MVCC permet de lire un état cohérent sans verrouillage sur InnoDB.
Scott Hyndman
5
Si la réplication n'est pas déjà configurée, vous devez effectuer un vidage pour la configurer. Le même problème existe.
Matt Connolly
3
Si la réplication n'est pas déjà configurée, vous devrez verrouiller les tables pour effectuer le vidage afin d'assurer l'intégrité des données. C'est donc une prise 22.
JordanC
9

C'est à peu près aussi tard par rapport au gars qui a dit qu'il était en retard qu'à la réponse d'origine, mais dans mon cas (MySQL via WAMP sur Windows 7), j'ai dû utiliser:

--skip-lock-tables
dtbarne
la source
C'est ce qui a fonctionné pour moi pour vider information_schema sans avoir l'erreur "Accès refusé pour l'utilisateur 'debian-sys-maint' @ 'localhost' à la base de données 'information_schema' lors de l'utilisation de LOCK TABLES"
Rui F Ribeiro
6
    mysqldump -uuid -ppwd --skip-opt --single-transaction --max_allowed_packet=1G -q db |   mysql -u root --password=xxx -h localhost db
naveen_sfx
la source
Up vote, celui-ci a fonctionné pour moi il suffit d'ajouter les paramètres --skip-opt --single-transaction --max_allowed_packet = 1G
Steven Lizarazo
1
Je ne recommande pas "--skip-opt" à cet effet. Cela fait beaucoup plus que ce que la question initiale demandait. Il désactive le mode rapide, il ne comprend pas le jeu de caractères, etc. , etc.
orrd
3

Lorsque vous utilisez MySQL Workbench, lors de l'exportation de données, cliquez sur Options avancées et décochez les options "tables de verrouillage".

entrez la description de l'image ici

Samuel Diogo
la source
1

Comme aucune de ces approches n'a fonctionné pour moi, j'ai simplement fait:

mysqldump [...] | grep -v "LOCK TABLE" | mysql [...]

Il exclura les commandes LOCK TABLE <x>et UNLOCK TABLES.

Remarque: Espérons que vos données ne contiennent pas cette chaîne!

augustomen
la source
2
- skip-add-locks pendant le vidage le fait aussi
codewandler
0

Une autre réponse tardive:

Si vous essayez de faire une copie chaude de la base de données de serveur (dans un environnement Linux) et le moteur de base de données de toutes les tables est MyISAM , vous devez utilisermysqlhotcopy .

Selon la documentation:

Il utilise FLUSH TABLES, LOCK TABLES et cp ou scp pour effectuer une sauvegarde de la base de données. C'est un moyen rapide de faire une sauvegarde de la base de données ou des tables individuelles, mais il ne peut être exécuté que sur la même machine où se trouvent les répertoires de la base de données. mysqlhotcopy ne fonctionne que pour la sauvegarde des tables MyISAM et ARCHIVE.

Le LOCK TABLEStemps dépend du temps que le serveur peut copier les fichiers MySQL (il ne fait pas de vidage).

Andrés Morales
la source
0

Aujourd'hui, même j'ai rencontré le même problème mais je n'avais pas accès à la ligne de commande. J'ai donc ouvert le fichier sql dans l'éditeur du bloc-notes et supprimé la ligne ci-dessous des tableaux

LOCK TABLES `yourtable name` WRITE;

puis j'ai importé dans mon environnement de développement .Fonctionne bien. j'espère qu'il aide quelqu'un

iCoders
la source