Tag: "alwayson"

Performance/ Management Data Warehouse Data Collector & AlwaysOn Availability Groups

Verwaltungs-Data Warehouse Datensammler & AlwaysOn Hochverfügbarkeitsgruppen

(EN)
This time, we are dealing with the „MDW“, short for Management Data Warehouse,(msdn.microsoft.com/en-us/library/bb677306.aspx), which I like to recommend as a minimal performance logging-approach.

From time to time, and most recently in the context of my PASS Essential „SQL Server Analysis tools & Techniques for Performance und general Monitoring“, the question arises as to whether the MDW operates together with the High Availability technologies Database Mirroring and AlwaysOn Availability Groups, and if so, how so.

(DE)
Diesmal geht es um das Management Data Warehouse, kurz „MDW“ (msdn.microsoft.com/de-de/library/bb677306.aspx), welches ich gerne als minimalen Performance-Protokollierungs-Ansatz empfehle.

Hin und wieder, zuletzt im Zusammenhang mit meinem PASS Essential „SQL Server Analysetools & Techniken für Performance und allg. Monitoring“ kommt die Frage auf, ob das MDW mit den Hochverfügbarkeitstechnologien Datenbankspiegelung und AlwaysOn Hochverfügbarkeitsgruppen zusammenspielt, und wenn, wie.

The short answer is: Yes, it does.
The MDW operates both with Database Mirroring as well as with AlwaysOn Availability Groups.

The following graph illustrates a possible setup using the latter:

Die kurze Antwort lautet: Ja.
Das MDW funktioniert sowohl mit Datenbankspiegelung als auch mit den AlwaysOn Hochverfügbarkeitsgruppen.

Das folgende Schaubild zeigt ein mögliches Setup unter Verwendung der letzteren Variante:

 

 

 

The server (0) holding the MDW database is located outside of the high availability nodes. The databases to be monitored are located in the AlwaysOn Availability Groups in the servers 1-3.
Keeping the MDW highly available is not the objective. It is simply about being able to see the performance data of all databases, no matter in which server they are active at the moment.

Der Server (0), der die MDW-Datenbank vorhält, liegt außerhalb der Hochverfügbarkeitsknoten. Die zu überwachenden Datenbanken liegen in AlwaysOn Hochverfügbarkeitsgruppen auf den Servern 1-3.
Das MDW hochverfügbar zu halten ist nicht das Ziel. Es geht nur darum, die Performance-Daten aller Datenbanken einsehen zu können, gleich auf welchem Server sie gerade aktiv sind.

Part 1: Databases in secondary role

If you set up the MDW as standard you will realize that after a failover, the data of the respective databases disappear from the “Disc Usage” reports of the server, while these were previously still present in the primary role.

The background to this is that after a failover, the respective databases now are present in a different server in the primary role, and now are no longer readable in the secondary, in the standard setting.

In this moment, the System Data Collection Set “Disc Usage”, or the underlying job “collection_set_1_noncached_collect_and_upload” cannot collect data for this database. In contrast on the new primary node these database will now reappear as long as they are active in the primary role there. In principle, this behavior is comprehensible: The Data Collector can no longer find any information on this database and assumes that the latter is no longer relevant – as if it was deleted. One may certainly wish for a possibility of intervention here; however, the MDW is currently not flexible in this regard.

The new report “Transaction Performance Analysis Overview” which is enriched through the newly existent “Transaction Performance Collection Set” in SQL Server 2014 also displays data for no longer active databases.

Having clarified this background, the possible solution is self-evident: The databases must remain readable.

With AlwaysOn High Availability Groups, this is in principal easily done:

Part 1: Datenbanken in Secondary-Rolle

Wenn man nun das MDW standardmäßig einrichtet, wird man feststellen, dass nach einem Failover die Daten der jeweiligen Datenbanken aus den „Disk Usage“-Berichten des Servers verschwinden, wo diese bis zuvor noch in der Primary-Role vorlagen.

Hintergrund ist, dass nach einem Failover die jeweiligen Datenbanken nun auf einem anderen Server in der Primary-Role vorliegen, und auf dem nun Secondary, in der Standardeinstellung nicht lesbar sind.

In diesem Moment kann das System Data Collection Set „Disk Usage“, bzw. der dahinterliegende Job „collection_set_1_noncached_collect_and_upload“ zu dieser Datenbank keine Daten auslesen. Auf dem neuen Primary-Knoten hingegen werden diese Datenbanken nun neu erscheinen, solange sie dort in der primären Rolle aktiv sind.

Prinzipiell ist dieses Verhalten nachvollziehbar: Der Data Collector kann keine Informationen zu dieser Datenbank mehr finden und geht davon aus, dass diese nicht mehr relevant ist – als ob sie gelöscht sei. Sicherlich kann man sich hier eine Eingriffsmöglichkeit wünschen, derzeit ist das MDW aber in dieser Hinsicht nicht flexibel.
- Der neue Bericht „Transaction Performance Analysis Overview“, der über das neu im SQL Server 2014 existierende „Transaction Performance Collection Set“ angereichert wird, zeigt auch Daten für bereits nicht mehr aktive Datenbanken an.

Wenn nun dieser Hintergrund klar ist, liegt die mögliche Lösung nahe: Die Datenbanken müssen lesbar bleiben.
Mit AlwaysOn Hochverfügbarkeitsgruppen (Availability Groups) ist das prinzipiell auch leicht gemacht:

 

 

However, one needs to be aware of the fact that these databases are now released for all reading access – which should be taken into consideration in respect to application architecture, performance as well as in terms of license. Hence, for the purpose of data collection for performance evaluation alone I CANNOT recommend it.

If however the business applications are supposed to maintain reading access to the secondary point anyway, the data collector is covered with this as well.

One more advice: The setting “Read-Intent only” unfortunately does not work with the MDW since one cannot manually adapt the Connection String accordingly.
Database Mirroring does not support this option at all.

Jedoch muss man sich hierüber im Klaren sein, dass diese Datenbanken nun für sämtliche Lesezugriffe freigegeben sind, was sowohl hinsichtlich Applikationsarchitektur, Performance als auch Lizenztechnisch genau bedacht werden sollte. Allein zum Zweck der Datensammlung zu Performance-Auswertung kann ich das also NICHT empfehlen.
Wenn die Geschäftsanwendungen aber ohnehin Lesezugriffe auf den Sekundärknoten erhalten sollen, dann ist damit der Datensammler ebenfalls abgedeckt.
Noch ein Hinweis: Die Einstellung „Read-Intent only“ funktioniert mit dem MDW bisher leider nicht, da man den Connection String nicht entsprechend manuell anpassen kann.
Datenbankspiegelung unterstützt diese Option gar nicht.

Part 2: Configuration of the MDW-Clients

Since the databases run on a different node after a failover, the MDW reports must be set up in all servers in which the Availability Group is running. Here, one needs to ensure that access to the central MDW-Server is possible from all servers.

To do this (before SQL Server 2014) the SQL Server Agent Account of the client-instance must be included in the mdw_writer role on the MDW-Server (mdw_admin is not necessary) when configuring the MDW through the “Configure Management Data Warehouse Wizard:

Part 2: Konfiguration der MDW-Clients

Da die Datenbanken nach einem Failover auf einem anderen Knoten laufen, müssen die MDW-Berichte auf allen Servern, auf denen die Availability Group läuft, eingerichtet werden.

Dabei muss sichergestellt werden, dass von allen Servern auf den zentralen MDW-Server zugegriffen werden kann.

Dazu muss (vor SQL Server 2014) bei der Konfiguration des MDW über den „Configure Management Data Warehouse Wizard“ der SQL Server Agent Account der Client-Instanz auf dem MDW-Server in die mdw_writer-Rolle aufgenommen werden (mdw_admin ist nicht notwendig):

 

 

 

 

From SQL Server 2014, at the configuration of the data collection in the client, it is possible to provide a SQL Server Agent Proxy of the type “Operating System (CmdExec)” as account for the access to the central MDW-Server:

Ab SQL Server 2014 kann man bei der Konfiguration der Data Collection auf dem Client einen SQL Server Agent Proxy vom Typ „Operating System (CmdExec)“ als Konto für den Zugriff auf den zentralen MDW-Server hinterlegen:

 

 

 

In this case, it is of course required to authorize the underlying Windows account in the server, instead of the agent itself, as „mdw-writer“.

In diesem Fall muss auf dem Server natürlich der dahinterstehende Windows-Account anstelle des Agents selber als „mdw_writer“ berechtigt werden.

As soon as all clients are authorized accordingly, one can read the data of all SQL Server AG nodes in the central management server. Depending on which server a database is currently present in in the primary role, it will then appear in the according subreport.
- This proceeding also works with mirrored databases in Database Mirroring scenarios – there one can only have one “partner instance” though.

Sobald alle Clients entsprechend berechtigt sind, kann man auf dem zentralen Management Server die Daten aller SQL Server Knoten der AG auslesen. Je nachdem auf welchem Server eine Datenbank gerade in der Primary-Rolle vorliegt, erscheint diese dann in dem entsprechenden Subreport.
- Diese Vorgehensweise funktioniert auch mit gespiegelten Datenbanken bei Datenbankspiegelungs-Szenarien – dort gibt es jedoch maximal eine „Partner-Instanz“.

 

 

 

 

 Happy collecting

 

Andreas

Artikel „SQL Server 2014 – Neues Fundament“ in iX Ausgabe 5/2014, Richtigstellungen zu In-Memory OLTP und ColumnStore Indexes und warum AlwaysOn nicht gleich Always On ist

Article “SQL Server 2014 – New Fundament” in iX Issue 5/2014, corrections in In-Memory OLTP and ColumnStore Indexes, and why AlwaysOn is not the same as Always On.

(DE)
In der Mai-Ausgabe der iX ist auf Seite 56 ein Artikel von mir zu finden, den ich zusammen mit den Kollegen Volker Heck (Cloud- und BI-Part) und Holger Schwichtenberg (Lektorat) geschrieben habe.

(EN)
In the May-issue of the iX, on page 56, there is an article by me which I wrote together with my colleagues Volker Heck (Cloud- and BI-Part) and Holger Schwichtenberg (copy-editing).

In der finalen Version, die ich auch erst am Kiosk zu sehen bekommen habe, sind leider einige Ungenauigkeiten enthalten. Um Missverständnisse auszuschließen, möchte ich diese hier kurz geraderücken, bzw. ein korrektes Verständnis sicherstellen.

Es geht los mit der Einleitung:
1)

„…Nach zwei Jahren Entwicklungszeit stellt Microsoft die neue Version seines Datenbankservers vor...“

Richtigstellung: Ich bin mir nicht sicher, wann der Startschuss für den SQL Server 2014 war, aber ziemlich sicher war das nicht 2 Jahre vor dem Release-Datum (1.4.2014), wie dieser Satz impliziert. Dass die In-Memory OLTP Engine XTP bereits 2009 mit ihrem ersten Patent untermauert wurde, schreibe ich etwas später noch im Artikel. Wann genau feststand, dass es einen SQL Server 2014 geben würde, und der Code entsprechend gebranched wurde, ist mir nicht bekannt. Wenn ich eine Vermutung abgeben würde, wäre dies eher ca. 3 Jahre vor dem Release.

Unfortunately, in the final version, which I have actually only set eyes on at the newspaper kiosk, there are a few inaccuracies. In order to avoid misunderstandings, I will correct them here shortly, or rather ensure a correct understanding.

Starting with the introduction:
1)

”…After two years of developing, Microsoft introduces the new version of its database server…”

Correction: I am not sure as to when the starting shot was made for the SQL Server 2014, but it is quite certain that it was not 2 years before the release date (1 April 2014), as implied by this sentence. A little later, in the article I also say that the In-Memory OLTP Engine XTP was confirmed with its first patent already in 2009. I am not aware of when exactly it was certain that there would be a SQL Server 2014, and that the code would be branched accordingly. If I was to speculate, I would say it was more like 3 years before its release.

 

2)

„…Wichtigste Neuerung ist das Ablegen relationaler Daten im Hauptspeicher statt auf der Festplatte….“

Richtigstellung: Diejenigen, die sich bereits ein wenig mit dieser neuen Technologie auseinandergesetzt haben, wissen es natürlich: Die Daten werden sowohl in RAM als auch auf Festplatte gespeichert – es sei denn man arbeitet mit „Schema_Only“-Tabellen. Später im Artikel wird das auch noch deutlich, mag aber hier verwirren.

2)

„…The most important innovation is the storing of relational data in the main storage instead of the hard drive.”

Correction: Those who have already familiarized themselves a little with this new technology will know of course: The data are stored both in RAM and in the hard drive – unless you work with “schema_only”-tables. This will become clear later in the article, but may cause some confusion here.

 

3)

„…Stored Procedures in Maschinensprache
­­­… „Native Kompilierung“ ... Dafür erzeugt der Server beim ersten Ausführen aus der jeweiligen Prozedur eine DLL. Diese Bibliotheken überstehen den Neustart von Datenbank oder Server jedoch nicht, müssen also danach erneut erstellt werden…“

Das kann man leicht falsch verstehen.
Richtigstellung: Genau gesagt werden diese DLLs nach jedem Neustart von Datenbank oder Datenbankserver neu generiert (bei erster Verwendung). – Man muss diese DLLs oder gar die Prozeduren also nicht selber neu erstellen.

3)

             „…Stored Procedures in machine language.“

… “Native compiling” …”Before the first run, the server produces a DLL from the respective procedure for this. These libraries, however, do not last through the restart of database or server, so they have to be generated again afterwards…”

This can be easily misunderstood.

Correction: To be precise, these DLLs are regenerated after each restart of the database or database server (at first usage). – Thus, one does not have to generate these DLLs or even the procedures new oneself.

4)

„(Nativ kompilierte Prozeduren)…Solche Prozeduren … erlauben noch nicht alle T-SQL-Sprachelemente. Es fehlen beispielsweise Raiseerror und Begin Transaction, einige Funktionen sowie Query Hints.“

Auch das könnte jemanden auf eine falsche Fährte führen.
Richtigstellung: Besser ausgedrückt: „Zum Beispiel kann man bestimmte Befehle wie Raiseerror oder Begin Transaction, anstelle dessen ein „Atomic“-Block erforderlich ist, nicht nutzen.“ - Der Atomic-Block startet bereits eine Transaktion, daher ist ein zusätzliches „Begin Transaction“ ohnehin fehl am Platz. - Einige Query Hints werden übrigens tatsächlich unterstützt.

4)

„(Natively complied procedures) … Such procedures … do not yet allow for all T-SQL language elements. For instance, Raiseerror and Begin Transaction are missing, as well as a few functions and Query Hints.”

This, too, could be misleading.

Correction: Put more precisely: “For instance, it is not possible to use particular commands such as Raiseerror or Begin Transaction, instead of which an “atomic” block is required.” The Atomic-Block already starts a transaction, so an additional “begin transaction” is superfluous in any case. – By the way, a few Query Hints are actually supported.  

 

5)

„(neue Parallelitätskontrolle „multi-versioned, timestamped optimistic concurrency control“)… Dazu ergänzt der Server alle Datensätze um einen bei jeder Änderung automatisch aktualisierten Zeitstempel, anhand dessen er Konflikte erkennt…“

Das kann man auch leicht falsch interpretieren und einen glauben lassen, dass immer der selbe Datensatz aktualisiert wird. Der Hintergrund von „multi-versioned, timestamped optimistic concurrency control“ ist aber gerade, das es pro Version einen neuen Datensatz gibt, was sich in ausführlichen Tests von Microsoft Research in realitätsnaheren Testreihen (mit komplexeren Transaktionen im Mix mit längeren Lesezugriffen und Hotspot-Szenarien) als effizienter als „Single-version locking“ herausgestellt hat. (Quelle: „High-Performance Concurrency Control Mechanisms for Main-Memory Databases“, Microsoft, University of Wisconsin – Madison)
- Single-Version Locking wird beispielsweise von Oracle TimesTen und IBM’s solidDB eingesetzt.
Richtigstellung: Genauer ist also zu sagen, dass es pro Version einen Datensatz gibt, und die “Alten Versionen” durch ein End-Timestamp als solche markiert werden.

5)

„(new concurrency control, „multi-versioned, timestamped optimistic concurrency control“)… For this, the server complements all data sets by an automatically updated timestamp created with each change, with the help of which it recognizes conflicts…”

This can also be easily misinterpreted and may make believe that always the same data set is being updated. However, the background to “multi-versioned, timestamped optimistic concurrency control” is in fact that there is a new data set per version, which comprehensive tests in realistic test series by Microsoft Research (with more complex transactions combined with longer read access and hotspot scenarios) have shown to be more efficient than “Single-version locking.” (Source: “High-Performance Concurrency Control Mechanisms for Main-Memory Databases,” Microsoft, University of Wisconsin – Madison)

Single-Version Locking, for example, is applied by Oracle TimesTen and IBM’s solidDB.

Correction: It is thus more precise to say that there is one data set per version, and the “old versions” are marked as such by an end-timestamp.

6)

„(Clustered ColumnStore Indexe)…Diese erweiterte Variante der Hauptspeicher-Index-Technik wurde für die 2013 erschienene PDW-Variante (Parallel Data Warehouse) des SQL Server 2012 entwickelt und ist dort bereits im Einsatz…“

Die Wortwahl lässt vermuten, dass diese (Columnstore) Indexe, wie auch bei In-Memory optimierten Tabellen & Indexen, lediglich im Hauptspeicher liegen. Das stimmt natürlich nicht.
Richtigstellung: Besser sollte hier stehen: „Hauptspeicher-optimierte Indexe“

6)

 “(Clustered ColumnStore Indexes)… This enhanced type of the Main-Memory Index Technique was developed for the PDW-version (Parallel Data Warehouse) of the SQL Server 2012 made available in 2013 and is already being applied there…”

The choice of words suggests that these (Columnstore) indexes, just as with the In-Memory optimized tables & indexes, are located in the main memory only. This is of course not the case.  

Correction: More precise would be to say: “Main-Memory-optimized indexes”

7)

Und last but not least leider hat sich auch in diesem Artikel ein häufiger Fehler eingeschlichen:

Die Lösung für hohe Verfügbarkeit und Notfallwiederherstellung, welche im SQL Server 2012 neu eingeführt wurde, schreibt sich natürlich „AlwaysOn“, und weder „Always On“ noch „Always-On“.
„Always On“ (mit Leerzeichen) wurde bereits in SQL Server 2005 eingesetzt, um Speicher-Hardware für SQL Server zu zertifizieren. Dazu gehört z.B.:

  • die korrekte Umsetzung der API’s, des Write-Ahead Logging (WAL) Protokolls für sowohl Transaktionsprotokolle als auch Daten- und Backup-Dateien
  • der Optionen FILE_FLAG_WRITETHROUGH und FlushFileBuffers beim Öffnen von Dateien
  • der Unterstützung von asynchronem I/O
  • Write ordering
  • Das korrekte Übermitteln der Sektor-Größen an die Windows API’s, um Sektor-Größen-Versatz und Torn Writes zu verhindern
  • Die NTFS-Fähigkeiten wie z.B. Sparse Files, File Streams, Encryption, Compression, sämtliche Sicherheitseigenschaften

Über „Always On” lässt sich z.B. hier nachlesen: www.dell.com/downloads/global/solutions/
dell_pv_sql_always_on_tech_note_v_1_5.pdf

Im SQL Server 2008 wurde „Always On“ für die gesamte Palette der Hochverfügbarkeitstechniken verwendet. Dazu gehörten Database Mirroring, Log Shipping, Failover Clustering, Peer-to-Peer Replication, Backup und Restore (!), Database Snapshots, selbst Partitionierung und weiteres. (Hier nachzulesen: High Availability – Always On Technologies) Das hat also nicht mit dem neuen Features AlwaysOn-Verfügbarkeitsgruppen/Availability Groups und AlwaysOn-Failoverclusterinstanzen zu tun.
Und Feature-Namen werden nicht einfach „eingedeutscht“, genauso wenig wie man SharePoint auseinanderschreibt – Nein, ich werde das selbst aus Demozwecken nicht tun ;-)

7)

And last but not least, I’m afraid in this article, too, a common mistake has slipped in:

The solution for high availability and emergency restoration reintroduced in SQL Server 2012 is spelled “AlwaysOn,” of course; – neither “Always On” nor “Always-On.” “Always On” (with space) was already applied in SQL Server 2005 in order to certify storage hardware for SQL Server. It includes, for example:

  • The correct implementation of the APIs, the Write-Ahead Logging (WAL) protocol for both transaction protocols and data and backup files.
  • The options FILE_FLAG_WRITETHROUGH and FlushFileBuffers when opening files.
  • The support of asynchronous I/O.
  • Write ordering.
  • The correction transmission of the sector sizes to the Windows APIs in order to avoid sector size mismatches and Torn Writes.
  • The NTFS-abilities such as Sparse Files, File Streams, Encryption, Compression and all security properties.

You can read more on “Always On” here, for example:

www.dell.com/downloads/global/solutions/
dell_pv_sql_always_on_tech_note_v_1_5.pd

In SQL Server 2008, “Always On” was used for the entire range of high availability techniques. These include Database Mirroring, Log Shipping, Failover Clustering, Peer-to-Peer Replication, Backup and Restore (!), Database Snapshots, even partitioning, and more. (Read more here: High Availability – Always On Technologies) So this does not have anything to do with the new features AlwaysOn-Availability Groups or AlwaysOn-Failoverclusterinstances.

What is more, feature names are not simply „Germanized,“ just as you do not spell SharePoint separately – and no, I will not even do this for demonstration purposes ;-).

 

Soweit habe ich nun meinem Genauigkeitsempfinden genüge getan ;-)

 

Da das folgende Diagramm es leider nicht in den Artikel geschafft hat, möchte ich es hier zumindest mit meinen Lesern teilen:

For now, I feel like I have satisfied my sense of accuracy ;-)

 

Since the following graph has unfortunately not made it into the article, I would like to share it with my readers here at least:  

 

 

 

Das ist das Ergebnis eines Performance-Vergleiches einer schematisch so gut wie identischen „on-Disk“-Tabelle gegenüber den verschiedenen In-Memory OLTP Varianten. Der Test wurde auf Standard-Hardware durchgeführt: Intel i7-3529 (2,9Ghz), 2 Cores hyperthreaded, 16GB RAM und SSDs. Das Ergebnis kann sich sehen lassen und entspricht Microsofts Versprechung, das neue Hardware nicht zwingend erforderlich ist, um spürbare Performance-Gewinne durch den Einsatz der XTP-Engine zu erhalten.

This is the result of a performance comparison of a schematically virtually identical “on-disc”-table compared to the different In-Memory OLTP variants. The test was carried out with standard hardware: Intel i7-3529 (2,9Ghz), 2 Cores hyperthreaded, 16GB RAM and SSDs. The result is quite impressive and matches Microsoft’s promise that new hardware is not imperative in order to obtain tangible performance gains through the application of the XTP-Engine.

Und hier sind auch nochmal die begleitenden Links zu dem Artikel:

These are the corresponding links to the article:

 

 

Ich hoffe, die genannten Punkte sind für ein besseres Verständnis nicht nur des Artikels sondern auch von SQL Server 2014 allgemein hilfreich.

Kommentare oder Nachfragen können gern hier über meinen Blog hinterlassen werden.

I hope the points above are helpful for a better understanding not only of the article but also of SQL Server 2014 in general.

You are welcome to leave comments or questions in my blog.

 

 

Andreas Wolter

 

PS: Leider sind in meiner Master-Class Workshop In-Memory OLTP & ColumnStore - New Storage Engines in SQL Server 2014 (XTC) keine Plätze mehr verfügbar (!). Im Sommer wird sicher die Entscheidung für eine Neuauflage im 2. Halbjahr 2014 oder doch erst wieder im 1. HJ 2015 fallen. – Im 2. HJ stehen wieder viele Konferenzen, inklusive MVP Summit, PASS Summit und PASS Camp an, so dass es da wirklich eng wird. Aussichtsreicher ist da meist eine Inhouse-Schulung auf Anfrage.

P.S.: Unfortunately, there are no spots left (!) in my Master-Class Workshop In-Memory OLTP & ColumnStore - New Storage Engines in SQL Server 2014 (XTC). The decision for a remake either in the second half of 2014, or only in the first half of 2015, will probably be made in summer. – For the second half of 2014, many conferences, including MVP Summit, PASS Summit and PASS Camp, are lined up, so it is already quite cramped. The prospects may thus often be better for an in-house-training on request.

 

Locking & READONLY Filegroups vs READONLY Databases // Sperren & READONLY Dateigruppen vs READONLY Datenbanken

(en)
The Topic Locking and Read-Only for filegroups and databases is one of the ongoing myths around SQL Server in forums – and at least half of the information unfortunately wrong.
Since I recently fell into the trap myself, I want to write down, how it really is.

To have a definite picture, I made 3 test series under 3 different isolation levels:
  • Read Commited (the default)
  • Read Uncommitted (equal to the often misunderstood “NOLOCK”)
  • Repeatable Read

     

    The Setup:


    Tested under:
    Microsoft SQL Server 2012 - 11.0.2376
    A Test using SQL Server 2008 R2 produced identical results

    The base is a simple table, which has a Clustered Index. Altogether it consists of 36 pages
    (In case you wonder about the name – I had also tested with a single-Page table)

(de)
Das Thema Sperren im Zusammenhang mit Readonly Filegroups und Datenbanken geistert immer wieder durch die Foren - und mindestens zur Hälfte leider mit Falschinformationen angereichert. Da ich kürzlich selber in die Falle tappte, möchte ich hiermit schwarz auf weiß festhalten, wie es sich wirklich verhält.

Um ein eindeutiges Bild zu erhalten, habe ich Testreihen unter 3 verschiedenen Isolation Levels durchgeführt:

  • Read Commited (also dem Standard)
  • Read Uncommitted (gleichbedeuted mit dem ebenfalls gerne missinterpretierten “NOLOCK”)
  • Repeatable Read

    Das Setup:

    Getestet unter:
    Microsoft SQL Server 2012 - 11.0.2376
    Ein Test unter SQL Server 2008 R2 ergab identische Ergebnisse

    Basis ist eine simple Tabelle, welche mit einem Clustered Index versehen ist. Insgesamt besteht sie aus 36 Pages.
    (Falls ihr Euch über den Namen wundert: ich hatte auch Test mit einer single-Page Tabelle gemacht)

 

Databases

 

Read-Only Filegroup


USE
LockingDemo_RW
go
exec sp_help'BigTable'

Data_located_on_filegroup
PRIMARY

index_name    index_description
PK__BigTable__3213E83FFF01B718    clustered, unique, primary key located on PRIMARY

USELockingDemo_RO

Data_located_on_filegroup
PRIMARY

index_name    index_description
PK__BigTable__3213E83FFF01B718    clustered, unique, primary key located on PRIMARY

Identical structure so far except the database LockingDemo_RW_FG_RO – here the Table resides on filegroup FG_RO Also ein identischer Aufbau, bis auf die Datenbank LockingDemo_RW_FG_RO – hier ist die Tabelle auf der Filegroup FG_RO

USELockingDemo_RW_FG_RO

Data_located_on_filegroup
FG_RO

index_name    index_description
PK__BigTable__3213E83FC5587D01    clustered, unique, primary key located on FG_RO

The first/upper query shows the total amount of data, the lower is used as the test query: Die die erste/obere Abfrage zeigt die Gesamtdatenmenge, die untere wird als Testabfrage verwendet:

1)
SELECT * FROM BigTable

(1000 row(s) affected)

Table 'BigTable'. Scan count 1, logical reads 36, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 

2) – The Testquery / die Testabfrage

SELECT
* FROM BigTable

    WHERE id BETWEEN 100 AND 200

(101 row(s) affected)

Table 'BigTable'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 

This is what the test looked like (abbreviated): So sah der Testlauf aus (abgekürzt):

--====================

--  1

--====================

 SET TRANSACTION ISOLATION LEVEL READ COMMITTED

 

USELockingDemo_RW

go

 BEGINTRAN

 SELECT * FROM BigTable

    WHERE id BETWEEN 100 AND 200

 COMMITTRAN

 

USELockingDemo_RO

go

 BEGINTRAN

 

SELECT * FROM BigTable

    WHERE id BETWEEN 100 AND 200

 

COMMITTRAN

 

USELockingDemo_RW_FG_RO

go

 BEGINTRAN

 SELECT * FROM BigTable

    WHERE id BETWEEN 100 AND 200

 COMMITTRAN

 

USEmaster

 --====================

-- 2

--====================

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

 ...

 --====================

-- 3

--====================

 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

 ...

 

Parallel to that, an extended events session was running (Lock-escalation isn’t happening in this scenario) Parallel dazu lief eine Extended Events session
(Lock-Escalation tritt in diesem Szenario nicht auf)

 CREATE EVENT SESSION [Locking] ON SERVER

ADD EVENT sqlserver.lock_acquired(

    ACTION(package0.event_sequence,sqlserver.database_id,sqlserver.is_system,sqlserver.session_id)

    WHERE ([sqlserver].[database_id]>=(23) AND [sqlserver].[database_id]<=(25)))

ADD TARGET package0.event_file(SET filename=N'D:\SQLData\SQLData1\Locking.xel')

WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=1 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)

GO 

 

Results

(Locks with granularity / resource_type = DATABASE left out)

1. Read Committed

Resultate

(Sperren mit Granularität / resource_type = DATABASE ausgelassen)

1. Read Committed

  Locks under Read Committed

2. Read Uncommitted

(for obvious reason I left out the sub-totals :-)

2. Read Uncommitted

(aus offensichtlichem Grund habe ich die Zwischensummen weggelassen :-)

 Locks under Read Uncommitted

3. Repeatable Read

3. Repeatable Read

 Locks under Repeatable Read

A note about Statistics und eXclusive Locks on ReadOnly-Databases:

Yes, one can indeed watch X-Locks on Read-Only databases. And this happens when auto-created stats jump in.
This works only starting with SQL Server 2012. The statistics themselves are stored in Tempdb.
In order to create those, SQL Server generates SCH_S and METADATA locks on several system objects (here: sysallocunits, sysschobjs, sysobjvalues, syssingleobjrefs, sysobjkeycrypts):

Eine Bemerkung zu Statistiken und eXklusive-Sperren auf schreibgeschützten Datenbanken:

Ja, tatsächlich kann man auch auf Read-Only Datenbanken hin und wieder X-Locks beobachten. Und zwar wenn auto-created Statistics einspringen.
Das funktioniert erst seit SQL Server 2012. Dabei werden die Statistiken selber in der Tempdb hinterlegt.
Um sie zu erzeugen, generiert SQL Server SCH_S und METADATA Locks auf diverse Systemobjekte (hier: sysallocunits, sysschobjs, sysobjvalues, syssingleobjrefs, sysobjkeycrypts):

image

This is of course not the most common scenario, but it does happen (especially in AlwaysOn scenarios with read-only secondaries involved) and belongs to a complete picture.

-

Besides that one can see on first sight, that there is no diffference in the Locking behaviour beetween the table on a ReadWrite Filegroup (here Primary) and the table on the ReadOnly filegroup.

Only if the whole database is ReadOnly, SQL Server  saves himself the Page- and Key- locks.
Even there an Intent shared Lock is placed on the table.

Conclusion:

Putting Tables onto a ReadOnly-Filegroup does not save Locks.
But it often does make a lot of sense, to break up databases in this manner.
Just thinking of: less backup, faster restore, NTFS-compression etc.
Das ist sicherlich nicht das am meisten übliche Szenario, aber es tritt auf (insbesondere in AlwaysOn Szenarien mit read-only Secondaries) und gehört zu einem vollständigen Bild.

-

Abgesehen davon erkennt man auf den ersten Blick, das kein Unterschied im Sperrverhalten zwischen der Tabelle auf einer ReadWrite Filegroup (hier Primary) und der Tabelle auf der ReadOnly Filegroup besteht.

Nur wenn die gesamte Datenbank ReadOnly ist, spart sich SQL Server die Page- und Key- Locks. Selbst dort jedoch wird ein Intent-Share-Lock auf die Tabelle gesetzt.

Fazit:

Tabellen auf eine ReadOnly-Dateigruppe zu verlegen spart keine Sperren.
Aber es macht natürlich trotzdem oft sehr viel Sinn, Datenbanken so aufzuteilen.
Ich denke da nur an: Weniger Backup, schnellere Wiederherstellung, NTFS-Komprimmierung  etc.

Andreas

Sarpedon Quality Lab