Erreur "La base de données est en transition"


12

Aujourd'hui, j'essayais de restaurer une base de données sur une base de données déjà existante, j'ai simplement fait un clic droit sur la base de données dans SSMS -> Tâches -> Déconnecter pour pouvoir restaurer la base de données.

Une petite fenêtre contextuelle est apparue et s'est affichée Query Executing.....pendant un certain temps, puis a généré une erreur en disant Database is in use cannot take it offline. À partir de laquelle j'ai recueilli, il existe des connexions actives à cette base de données, j'ai donc essayé d'exécuter la requête suivante

USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

Encore une fois, à ce stade, le SSMS a montré Query Executing.....pendant un certain temps, puis a jeté l'erreur suivante:

Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.

Après cela, je n'ai pas pu me connecter à la base de données via SSMS. et quand j'ai essayé de le mettre hors ligne en utilisant SSMS, il a lancé une erreur en disant:

Database is in Transition. Try later .....

À ce stade, je ne pouvais tout simplement pas toucher à la base de données. Tout ce que j'ai essayé a renvoyé le même message d'erreur Database is in Transition.

J'ai lu sur Google des questions où des gens avaient rencontré un problème similaire et ils ont recommandé de fermer le SSMS et de l'ouvrir à nouveau, moi aussi et comme il ne s'agissait que d'un serveur de développement, je viens de supprimer la base de données à l'aide de SSMS et de la restaurer sur une nouvelle base de données.

Ma question est qu'est-ce qui aurait pu causer cela ?? et comment je peux éviter que cela se produise à l'avenir et si jamais je me retrouve dans la même situation à l'avenir, y a-t-il un autre moyen de le réparer, puis de supprimer toute la base de données ???

Je vous remercie

Réponses:


24

Repro

  1. Ouvrez SSMS
  2. Tapez ce qui suit dans une nouvelle fenêtre de requête

    use <YourDatabase>;
    go
    
  3. Accédez à l'Explorateur d'objets (SSMS) et cliquez avec le bouton droit sur <YourDatabase>-> Tasks->Take Offline
  4. Ouvrez une deuxième nouvelle fenêtre de requête et tapez ce qui suit:

    use <YourDatabase>;
    go
    

Vous serez invité avec le message suivant:

Msg 952, niveau 16, état 1, la
base de données de la ligne 1 «TestDb1» est en transition. Essayez la déclaration plus tard.

La raison pour laquelle cela se produit peut être trouvée à partir d'une requête de diagnostic similaire à celle ci-dessous:

select
    l.resource_type,
    l.request_mode,
    l.request_status,
    l.request_session_id,
    r.command,
    r.status,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    request_sql_text = st.text,
    s.program_name,
    most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;

Pour ce que ça vaut, vous n'avez pas besoin de l'Explorateur d'objets pour reproduire cette erreur. Vous avez juste besoin d'une demande bloquée qui tente la même opération (dans ce cas, mettez la base de données hors ligne). Voir la capture d'écran ci-dessous pour les trois étapes de T-SQL:

entrez la description de l'image ici

Ce que vous verrez probablement, c'est que votre session Object Explorer est bloquée par une autre session (indiquée par blocking_session_id). Cette session Object Explorer essaiera d'obtenir un verrou exclusif ( X) sur la base de données. Dans le cas de la repro ci-dessus, la session Object Explorer a obtenu un verrou de mise à jour ( U) et a tenté de se convertir en verrou exclusif ( X). Il y avait un wait_type de LCK_M_X, bloqué par notre session qui était représenté par la première fenêtre de requête (la use <YourDatabase>capture un verrou partagé ( S) sur la base de données).

Et puis cette erreur est survenue à partir d'une autre session essayant d'obtenir un verrou, et ce message d'erreur entraîne le refus d'une session pour accéder à une base de données qui tente de passer à un état différent (dans ce cas, l'état de connexion en ligne à la transition hors ligne).

Que devez-vous faire la prochaine fois?

Tout d'abord, ne paniquez pas et ne commencez pas à supprimer des bases de données . Vous devez adopter une approche de dépannage (avec une requête de diagnostic similaire à celle ci-dessus) pour savoir pourquoi vous voyez ce que vous voyez. Avec un message comme ça, ou quand quelque chose apparaît "bloqué", vous devez automatiquement supposer un manque de simultanéité et commencer à creuser dans le blocage ( sys.dm_tran_locksc'est un bon début).

En passant, je crois vraiment que vous êtes mieux de découvrir la racine d'un problème avant de prendre une mesure aléatoire. Pas seulement avec cette opération, mais cela vaut pour tous les comportements auxquels vous ne vous attendez pas. Sachant ce qui a vraiment causé votre problème, il est évident que ce n'était vraiment pas grave. Vous aviez essentiellement une chaîne de blocage, et le bloqueur parent était quelque chose que vous auriez probablement pu émettre KILL, ou si c'était une demande de session que vous ne vouliez pas, KILLvous auriez pu attendre la fin. Quoi qu'il en soit, vous auriez eu les connaissances nécessaires pour prendre la bonne décision et prudente compte tenu de votre scénario particulier (restauration ou attente de validation).

Une autre chose à noter, c'est l'une des raisons pour lesquelles j'ai toujours opté pour l'alternative T-SQL au lieu d'une interface graphique. Vous savez exactement ce que vous exécutez avec T-SQL et ce que fait SQL Server. Après tout, vous avez lancé la commande explicite. Lorsque vous utilisez une interface graphique, le T-SQL réel sera une abstraction. Dans ce cas, j'ai regardé la tentative bloquée de l'Explorateur d'objets de mettre la base de données hors ligne et elle l'a été ALTER DATABASE <YourDatabase> SET OFFLINE. Il n'y a eu aucune tentative de retour en arrière, c'est pourquoi il attendait indéfiniment. Dans votre cas, si vous vouliez restaurer des sessions qui avaient des verrous sur cette base de données, ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEcela aurait probablement suffi si vous aviez déterminé initialement que la restauration était correcte.


4

La fermeture de SQL Server Management Studio (SSMS) et la réouverture ont résolu le problème pour moi.


0

Pas besoin de faire quoi que ce soit, il suffit de tuer le processus à SqLWB.exepartir du Gestionnaire des tâches, d'ouvrir SQL Server, de cliquer avec le bouton droit sur la base de données et de le mettre hors ligne. Si cela ne fonctionne pas, après la fin de la session, tapez la commande

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

puis hors ligne. Cela fonctionnera comme cela a fonctionné pour moi aussi.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.