web-dev-qa-db-fra.com

Base de données supprimée accidentellement par un script bash, sauvetage s'il vous plaît

Mon développeur a commis une énorme erreur et nous ne pouvons trouver notre base de données mongo sur le serveur. Sauvez s'il vous plaît !!!

Il s'est connecté au serveur et a enregistré le shell suivant sous ~/crontab/mongod_back.sh:

enter image description here

Et puis il a couru ./mongod_back.sh, puis il y avait beaucoup de permission denied, puis il a fait Ctrl+C. Ensuite, le serveur s'est arrêté automatiquement.

Il a essayé de redémarrer le serveur, puis il a eu une erreur grub:

enter image description here

Il a ensuite contacté AliCloud, l'ingénieur a connecté le disque à un autre serveur de travail, afin qu'il puisse vérifier le disque. Il a ensuite réalisé que certains dossiers avaient disparu, y compris /data/ où est la mongodb !!!

1) Nous ne comprenons tout simplement pas comment le bash pourrait détruire le disque, y compris /data/;

2) Et bien sûr, est-il possible d'obtenir le /data/ arrière?

PS: il n'a pas pris d'instantané du disque auparavant.

22
SoftTimur

Question 1

1) Nous ne comprenons tout simplement pas comment le bash pourrait détruire le disque, y compris/data /;

Raison: $OUT_DIR n'était pas défini

Dans bash et sh les commentaires sont écrits comme # comment, ne pas // comment.
La ligne suivante aura les effets suivants

someVariable=someValue // not a comment
  • Assignez someValue à la variable someVariable, mais uniquement pour cette seule ligne. Après cette ligne , la variable reprendra son ancienne valeur , qui est nulle dans ce cas.
  • Exécutez la "commande" // not a comment, c'est le programme // avec les paramètres not, a et comment. Puisque // n'est qu'un répertoire (identique à /) cela provoquera un message d'erreur et rien de plus.

À l'heure actuelle, ce comportement peut sembler étrange, mais vous l'avez peut-être déjà utilisé dans des idiomes bien connus comme IFS= read -r line ou LC_ALL=C sort.

En regardant votre script, les lignes suivantes ont probablement causé le problème:

OUT_DIR=/data/backup/mongodb/tmp // ...
...
rm -rf $OUT_DIR/*

Je suis désolé de vous apporter ceci, mais vous avez essentiellement exécuté rm -rf /* puisque $OUT_DIR étendu à la chaîne vide.

Risque potentiel sur d'autres systèmes

Même si $OUT_DIR n'était pas vide, l'effet pourrait étaient les mêmes depuis qu'il y a // "commentaire" après rm. Considérez la commande

rm -rf some // thing

Ceci est censé supprimer les trois fichiers/répertoires some, // et thing. Comme déjà souligné // est le même répertoire que /.

Cependant, la plupart implémentations de rm sous Linux ont une garde pour ce cas et ne supprimera pas / si facilement. Sur Ubuntu, vous obtiendrez l'avertissement suivant ( n'essayez pas cela à la maison. Serait nul si votre rm diffère. )

$ rm -rf //
rm: it is dangerous to operate recursively on '//' (same as '/')
rm: use --no-preserve-root to override this failsafe

Question 2

2) Et pour cause, est-il possible de récupérer le/data /?

Ceci est hors sujet pour StackOverflow. Cependant, vous pouvez trouver beaucoupréponsesàceciquestionsurautrestackexchangesites .

Il existe des outils de récupération que vous pouvez essayer, mais rien ne garantit que vous pouvez restaurer vos données si vous n'avez pas de sauvegarde.

54
Socowi

Changer de langue peut être délicat! // n'est pas un démarreur de commentaires dans Shell, c'est #. Toutes les commandes avec ces "commentaires" ont été mal analysées et ignorées:

$ VAR=whatever // comment
bash: //: Is a directory
[$?=126]
$ echo "($VAR)"
()

Donc, OUT_DIR=... a été ignoré et $OUT_DIR était vide. Il est facile de deviner quoi

rm -rf $OUT_DIR/*

puis a fait. C'était essentiellement équivalent à

rm -rf /*

Utilisez vos sauvegardes pour restaurer la base de données.

18
choroba

Je peux lire les libellés chinois dans le champ de commentaire, à partir de la ligne 10, l'utilisateur veut créer un dossier temporaire mais a utilisé cd, donc si /data/backup/mongodb/tmp n'existe pas en premier lieu, alors $ OUT_DIR est vide ou nul, après que la ligne 11 est devenue rm -rf /*.

4
user11275761