Wie lange sollte SET READ_COMMITTED_SNAPSHOT ON dauern?

75

Wie lange sollte es dauern, um zu laufen

ALTER DATABASE [MySite] SET READ_COMMITTED_SNAPSHOT ON

Ich habe es gerade ausgeführt und es hat 10 Minuten gedauert.

Wie kann ich überprüfen, ob es angewendet wird?

Simon_Weaver
quelle
1
Hoppla. war die ganze Zeit nicht aktiviert !! (im Ernst!) das erklärt die Deadlocks. Siehe meine Antwort unten für vollständige Ergebnisse und ein besseres Skript zum Ausführen
Simon_Weaver
1
Die Aktion selbst wird fast sofort abgeschlossen. Der Grund, warum es nicht zurückkehrt, ist, dass es darauf wartet, dass andere Benutzer die Datenbank verlassen. Es ist nicht so, als wäre es damit beschäftigt zu denken, wegzuwerfen, Ressourcen zu verbrauchen. Es wartet darauf, dass alle den Raum verlassen, damit es den Schalter umlegt.
Ian Boyd

Antworten:

66

Sie können den Status der Einstellung READ_COMMITTED_SNAPSHOT in der sys.databasesAnsicht überprüfen . Überprüfen Sie den Wert der is_read_committed_snapshot_onSpalte. Bereits gefragt und beantwortet .

Bezüglich der Dauer gibt Books Online an, dass zu diesem Zeitpunkt keine weiteren Verbindungen zur Datenbank bestehen können, jedoch kein Einzelbenutzermodus erforderlich ist. Sie können also durch andere aktive Verbindungen blockiert werden. Führen Sie sp_who(oder sp_who2) aus, um zu sehen, was noch mit dieser Datenbank verbunden ist.

Rick
quelle
Vielen Dank. Es hat bisher 40 Minuten gedauert und zeigt 0. Es ist eine 740-MB-Datenbank. Daumen drücken, ich habe es nicht
gebrochen
3
Versuchen Sie, ein anderes Abfragefenster für diese Datenbank zu öffnen. Wenn Sie können, dann gehe ich davon aus, dass Ihre Anweisung noch nicht ausgeführt wurde.
Rick
3
Jep. Bei den meisten Datenbanken sollte es nur einige Sekunden dauern. Wenn es länger dauert, wartet es hinter einer anderen (auch nicht aktiven) Verbindung auf die Beendigung, bevor die Änderung vorgenommen werden kann. Daher müssen Sie möglicherweise alle derzeit verbundenen Spids finden und TÖTEN (nachdem Sie bewertet haben, was sie tun). DANN sollte es schnell gehen.
Michael K. Campbell
16
Ich empfehle, die Option NO_WAIT zu verwenden, um sofort fehlzuschlagen, wenn andere offene Verbindungen bestehen. ZB 'ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH NO_WAIT'
StefanR
1
Wenn Sie die anderen verbundenen SPIDs nicht finden und beenden können (oder es Ihnen einfach egal ist), können Sie die SQL Server-Instanz jederzeit neu starten.
David Murdoch
50

Versuche dies:

ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE
Hosam Aly
quelle
2
Was nützt "WITH ROLLBACK IMMEDIATE"? Bedeutet das, dass es automatisch zurückgesetzt wird, wenn die Abfrage fehlschlägt?
Senior Systems Engineer
5
Nein, "WITH ROLLBACK IMMEDIATE" bedeutet, dass alle offenen Transaktionen sofort zurückgesetzt werden, bevor die Anweisung ALTER DATABASE gestartet wird. Ich würde davon abraten, es sei denn, Sie haben bereits geprüft, welche Transaktionen offen sind und ob sie sicher zurückgesetzt werden können.
Rick
Erstaunlich, berichtet auch über Fortschritte beim Schließen von Verbindungen. Du hast unseren Speck gerettet!
Tyeth
30

OK (ich bin der ursprüngliche Fragesteller), also stellte sich heraus, dass ich die ganze Zeit nicht einmal das verdammte Ding aktiviert hatte.

Hier ist der ultimative Code , der ausgeführt werden muss, um den Snapshot-Modus zu aktivieren und sicherzustellen, dass er aktiviert ist.

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

Dies funktioniert auch bei aktiven Verbindungen (vermutlich ist es in Ordnung, wenn sie rausgeschmissen werden).

Sie können den Vorher- und Nachher-Status sehen und dieser sollte fast sofort ausgeführt werden.


WICHTIG:

Die obige Option READ_COMMITTED_SNAPSHOT entspricht IsolationLevel.ReadCommitted in .NET.
Die obige Option ALLOW_SNAPSHOT_ISOLATION entspricht IsolationLevel.Snapshot in .NET

Toller Artikel über verschiedene Versionen


.NET-Tipps:

Sieht so aus, Isolationlevel.ReadCommittedals wäre Code zulässig, auch wenn er nicht von der Datenbank aktiviert wurde. Es wird keine Warnung ausgegeben. Tun Sie sich selbst einen Gefallen und stellen Sie sicher, dass es eingeschaltet ist, bevor Sie davon ausgehen, dass es 3 Jahre lang so ist wie ich !!!

Wenn Sie C # verwenden, möchten Sie wahrscheinlich die ReadCommittedIsolationLevel und nicht Snapshot- es sei denn, Sie schreiben in dieser Transaktion.

READ COMMITTED SNAPSHOTliest optimistisch und schreibt pessimistisch. Im Gegensatz dazu werden SNAPSHOToptimistische Lesevorgänge und optimistische Schreibvorgänge ausgeführt. (von hier)

bool snapshotEnabled = true;

using (var t = new TransactionScope(TransactionScopeOption.Required,
               new TransactionOptions
{
     IsolationLevel = IsolationLevel.ReadCommitted
}))
{
     using (var shipDB = new ShipperDBDataContext())
     {

     }
}

Außerdem wird möglicherweise die Fehlermeldung angezeigt, dass eine Transaktion nicht beworben werden kann. Suchen Sie unter Einführung in System.Transactions in .NET Framework 2.0 nach "Promotion" .

Wenn Sie nichts Besonderes tun, z. B. eine Verbindung zu einer externen Datenbank (oder einer zweiten Datenbank) herstellen, kann dies durch etwas so Einfaches wie das Erstellen eines neuen DataContext verursacht werden. Ich hatte einen Cache, der bei der Initialisierung seinen eigenen Datenkontext "hochfuhr", und dies versuchte, die Transaktion zu einer vollständig verteilten Transaktion zu eskalieren.

Die Lösung war einfach:

        using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
        {
            using (var shipDB = new ShipperDBDataContext())
            { 
                 // initialize cache
            }
        }

Siehe auch DeadlockedArtikel von @CodingHorror

Simon_Weaver
quelle
4
Ich wollte erwähnen, da ich nicht sicher war: Sie könnenREAD_COMMITTED_SNAPSHOT unabhängig von einschalten ALLOW_SNAPSHOT_ISOLATION. Sie können ALLOW_SNAPSHOT_ISOLATION ausschalten und trotzdem davon profitieren READ_COMMITTED_SNAPSHOT, eingeschaltet zu sein . Getestet: Microsoft SQL Server 2012 - 11.0.2100.60
Ian Boyd
3
Diese Option ändert die Art und Weise, wie READ COMMITTED implementiert wird. Wenn diese Option deaktiviert ist, verwendet SQL Server Sperren, um den Zugriff zu steuern. Aus diesem Grund hat Ihr .NET-Code keine Warnung generiert. Sie haben das Verhalten immer noch erhalten, nur auf eine andere Art und Weise (und mit größerer Wahrscheinlichkeit als Deadlock).
Richard
Dies beantwortet nicht die ursprüngliche Frage, obwohl sie vom OP geschrieben wurde. Es implementiert eine Alternative.
Mike M
9

Versuchen Sie diesen Code:

if(charindex('Microsoft SQL Server 2005',@@version) > 0)
begin
    declare @sql varchar(8000)
    select @sql = '
    ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
    ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
    ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'

    Exec(@sql)
end
Nick Berardi
quelle
Sie sollten Ihre Aufrufe von db_name () mit quotename () umschließen, um alle Zeichen im Datenbanknamen zu berücksichtigen, die möglicherweise maskiert werden müssen (z. B. Leerzeichen).
Rick
Sie benötigen auch 'SET allow_snapshot_isolation ON', oder? (siehe meine Antwort)
Simon_Weaver
In den mssql-Dokumenten wird behauptet, dass Sie die Snapshot-Isolation festlegen müssen. Aber ich bin wirklich froh, diese funktionierende Antwort in einem Ozean von SQL Server-Rauschen zu finden.
Amalgovinus
7

Ich habe den Befehl ausprobiert:

ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

gegen eine Entwickler-Box, aber es dauerte mehr als 10 Minuten und so habe ich es getötet.

Ich habe dann folgendes gefunden:

https://willwarren.com/2015/10/12/sql-server-read-committed-snapshot/

und benutzte seinen Codeblock (der ungefähr 1:26 dauerte):

USE master
GO

/** 
 * Cut off live connections
 * This will roll back any open transactions after 30 seconds and
 * restricts access to the DB to logins with sysadmin, dbcreator or
 * db_owner roles
 */
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK AFTER 30 SECONDS
GO

-- Enable RCSI for MyDB
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

-- Allow connections to be established once again
ALTER DATABASE MyDB SET MULTI_USER
GO

-- Check the status afterwards to make sure it worked
SELECT is_read_committed_snapshot_on
FROM sys.databases
WHERE [name] = 'MyDB '
Jeff Mergler
quelle
3

Versuchen Sie, die Master-Datenbank zu verwenden, bevor Sie die aktuelle Datenbank ändern.

USE Master
GO

ALTER DATABASE [YourDatabase] SET READ_COMMITTED_SNAPSHOT ON
GO
eLVik
quelle
2

Ich habe keine Sekunde für mich gebraucht, als ich meine Datenbank auf Einzelbenutzer umgestellt habe

Yasin Kilicdere
quelle
0

Versuchen Sie, die anderen SQL-Dienste auszuschalten, damit nur der SQL Server-Dienst ausgeführt wird.

Meins lief 5 Minuten, dann habe ich es abgesagt, weil es offensichtlich war, dass nichts passierte. Es ist ein brandneuer Server, sodass keine anderen Benutzer verbunden sind. Ich habe die SQL Reporting Services heruntergefahren und dann erneut ausgeführt. Die Fertigstellung dauerte weniger als eine Sekunde.

Jeff
quelle