sql >> Database >  >> RDS >> Database

Uitbreiding van het gebruik van DBCC CLONEDATABASE

Service Pack 2 voor SQL Server 2014 is vorige maand uitgebracht (lees de release-opmerkingen hier) en bevat een nieuwe DBCC-instructie:DBCC CLONEDATABASE . Ik was behoorlijk opgewonden om te zien dat dit commando werd geïntroduceerd, omdat het een zeer gemakkelijke . biedt manier om een ​​databaseschema te kopiëren, inclusief statistieken , die kan worden gebruikt voor het testen van de prestaties van query's zonder dat alle ruimte nodig is voor de gegevens in de database. Ik heb eindelijk wat tijd vrijgemaakt om DBCC CLONEDATABASE uit te testen en begrijp de beperkingen, en ik moet zeggen dat het best leuk was.

De basis

Ik begon met het maken van een kloon van de AdventureWorks2014-database en het uitvoeren van een query op de brondatabase en vervolgens op de kloondatabase:

DBCC CLONEDATABASE (N'AdventureWorks2014', N'AdventureWorks2014_CLONE');
GO
 
SET STATISTICS IO ON;
GO
SET STATISTICS TIME ON;
GO
SET STATISTICS XML ON;
GO
 
USE [AdventureWorks2014];
GO
 
SELECT *
FROM [Sales].[SalesOrderHeader] [h]
JOIN [Sales].[SalesOrderDetail] [d] ON [h].[SalesOrderID] = [d].[SalesOrderID]
ORDER BY [SalesOrderDetailID];
GO
 
USE [AdventureWorks2014_CLONE];
GO
 
SELECT *
FROM [Sales].[SalesOrderHeader] [h]
JOIN [Sales].[SalesOrderDetail] [d] ON [h].[SalesOrderID] = [d].[SalesOrderID]
ORDER BY [SalesOrderDetailID];
GO
 
SET STATISTICS IO OFF;
GO
SET STATISTICS TIME OFF;
GO
SET STATISTICS XML OFF;
GO

Als ik naar de I/O- en TIME-uitvoer kijk, kan ik zien dat de query op de brondatabase langer duurde en veel meer I/O genereerde, die beide worden verwacht omdat de kloondatabase geen gegevens bevat:

/* BRON-database */

Uitvoeringstijden SQL Server:
CPU-tijd =0 ms,  verstreken tijd =0 ms.

SQL Server parseer- en compileertijd:
CPU-tijd =0 ms, verstreken tijd =4 ms.

(121317 rij(en) aangetast)

Tabel 'Verkooporderkop'. Scantelling 0, logische leest 371567, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

Tafel 'Werktafel'. Scantelling 0, logische leest 0, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

Tabel 'VerkooporderDetail'. Scantelling 5, logische leest 1361, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

Tafel 'Werktafel'. Scantelling 0, logische leest 0, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

(1 rij(en) aangetast)

Uitvoeringstijden SQL Server:
CPU-tijd =686 ms,  verstreken tijd =2548 ms.

/* CLONE-database */

Uitvoeringstijden SQL Server:
CPU-tijd =0 ms,  verstreken tijd =0 ms.

SQL Server parseer- en compileertijd:
CPU-tijd =12 ms, verstreken tijd =12 ms.

(0 rij(en) aangetast)

Tafel 'Werktafel'. Scantelling 0, logische leest 0, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

Tabel 'Verkooporderkop'. Scantelling 0, logische leest 0, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

Tabel 'VerkooporderDetail'. Scantelling 5, logische leest 0, fysieke leest 0, read-ahead leest 0, lob logische leest 0, lob fysieke leest 0, lob read-ahead leest 0.

(1 rij(en) aangetast)

Uitvoeringstijden SQL Server:
CPU-tijd =0 ms,  verstreken tijd =83 ms.

Als ik naar de uitvoeringsplannen kijk, zijn ze hetzelfde voor beide databases, behalve de werkelijke waarden (de hoeveelheid gegevens die daadwerkelijk door het plan is verplaatst):

Queryplan voor AdventureWorks2014-database

Queryplan voor AdventureWorks2014_CLONE-database

Dit is waar de waarde van DBCC CLONEDATABASE is duidelijk - ik kan iedereen een lege kopie van een database bezorgen (Microsoft Product Support, mijn mede-DBA, enz.) en ze een probleem opnieuw laten maken en onderzoeken, en ze hebben mogelijk geen honderden GB schijfruimte nodig om te doen het. Melissa's T-SQL Tuesday-post van juli bevat gedetailleerde informatie over wat er gebeurt tijdens het kloonproces, dus ik raad aan dat te lezen voor meer informatie.

Is dat het?

Maar... kan ik meer doen met DBCC CLONEDATABASE ? Ik bedoel, dit is geweldig, maar ik denk dat er veel andere dingen zijn die ik kan doen met een lege kopie van de database. Als u de documentatie voor DBCC CLONEDATABASE . leest , zie je deze regel:

Microsoft Customer Support Services kan u vragen een kloon van een database te genereren met behulp van DBCC CLONEDATABASE om een ​​prestatieprobleem met betrekking tot de query-optimizer te onderzoeken.

Mijn eerste gedachte was:"query-optimizer - hmm ... kan ik dit gebruiken als een optie voor het testen van upgrades ?”

Welnu, de gekloonde database is alleen-lezen, maar ik dacht dat ik toch zou proberen enkele opties te wijzigen. Als ik bijvoorbeeld de compatibiliteitsmodus zou kunnen wijzigen, zou dat echt gaaf zijn, want dan zou ik CE-wijzigingen kunnen testen in zowel SQL Server 2014 als SQL Server 2016.

USE [master];
GO
 
ALTER DATABASE [AdventureWorks2014_CLONE] SET COMPATIBILITY_LEVEL = 110;

Ik krijg een foutmelding:

Msg 3906, niveau 16, staat 1
Kan database "AdventureWorks2014_CLONE" niet bijwerken omdat de database alleen-lezen is.
Bericht 5069, niveau 16, staat 1
ALTER DATABASE-instructie is mislukt.

Hmm. Kan ik het herstelmodel wijzigen?

ALTER DATABASE [AdventureWorks2014_CLONE] SET RECOVERY SIMPLE WITH NO_WAIT;

Ik kan. Dat lijkt niet eerlijk. Nou, het is alleen-lezen, kan ik dat veranderen?

ALTER DATABASE [AdventureWorks2014_CLONE] SET READ_WRITE WITH NO_WAIT;

JA! Voordat je te opgewonden raakt, laat me deze notitie hier uit de documentatie achterlaten:

Opmerking De nieuw gegenereerde database die is gegenereerd vanuit DBCC CLONEDATABASE wordt niet ondersteund voor gebruik als productiedatabase en is voornamelijk bedoeld voor probleemoplossing en diagnostische doeleinden. We raden aan om de gekloonde database los te koppelen nadat de database is gemaakt.

Ik ga deze regel uit de documentatie herhalen, vetgedrukt maken en rood plaatsen als een vriendelijke maar extreem belangrijke herinnering:

De nieuw gegenereerde database die is gegenereerd vanuit DBCC CLONEDATABASE wordt niet ondersteund voor gebruik als productiedatabase en is voornamelijk bedoeld voor probleemoplossing en diagnostische doeleinden.

Nou, dat vind ik prima, ik zou dit zeker niet voor productie gebruiken, maar nu kan ik het gebruiken om te testen! NU kan ik de compatibiliteitsmodus wijzigen en NU kan ik er een back-up van maken en deze op een andere instantie herstellen om te testen!

USE [master];
GO
 
BACKUP DATABASE [AdventureWorks2014_CLONE]
  TO  DISK = N'C:\Backups\AdventureWorks2014_CLONE.bak'
  WITH INIT, NOFORMAT, STATS = 10, NAME = N'AW2014_CLONE_full';
GO
 
/* restore on SQL Server 2016 */
 
 
RESTORE DATABASE [AdventureWorks2014_CLONE]
FROM  DISK = N'C:\Backups\AdventureWorks2014_CLONE.bak' WITH
MOVE N'AdventureWorks2014_Data' TO N'C:\Databases\AdventureWorks2014_Data_2684624044.mdf',
MOVE N'AdventureWorks2014_Log' TO N'C:\Databases\AdventureWorks2014_Log_3195542593.ldf',
NOUNLOAD,  REPLACE,  STATS = 5;
GO
 
ALTER DATABASE [AdventureWorks2014_CLONE] SET COMPATIBILITY_LEVEL = 130;
GO

DIT IS GROOT.

In mijn laatste bericht had ik het over traceringsvlag 2389 en testen met de nieuwe Cardinality Estimator omdat, vrienden, jullie nodig om te testen met de nieuwe CE voordat u een upgrade uitvoert. Als je niet test, en als je de compatibiliteitsmodus wijzigt naar 120 (SQL Server 2014) of 130 (SQL Server 2016) als onderdeel van je upgrade, dan loop je het risico om in een brandbestrijdingsmodus te werken als je tegenkomt regressie met de nieuwe CE. Nu zou het goed kunnen gaan, en de prestaties kunnen nog beter zijn nadat u een upgrade hebt uitgevoerd. Maar... zou je het niet zeker willen weten?

Heel vaak als ik het heb over testen vóór een upgrade, krijg ik te horen dat er geen omgeving is om het testen uit te voeren. Ik weet dat sommigen van jullie een testomgeving hebben. Sommigen van jullie hebben Test, Dev, QA, UAT en wie weet wat nog meer. Je hebt geluk.

Voor degenen onder u die zeggen dat u helemaal geen testomgeving heeft om te testen, ik geef u DBCC CLONEDATABASE . Met deze opdracht heb je geen excuus om de meest uitgevoerde zoekopdrachten en de zwaargewichten niet uit te voeren tegen een kloon van je database. Ook als je geen testomgeving hebt, heb je je eigen machine. Maak een back-up van de kloondatabase vanuit productie, verwijder de kloon, herstel de back-up naar uw lokale exemplaar en test vervolgens. De kloondatabase neemt heel weinig schijfruimte in beslag en u zult geen geheugen- of I/O-conflicten krijgen omdat er geen gegevens zijn. Je zal in staat zijn om queryplannen van de kloon te valideren met die uit uw productiedatabase. Verder, als u herstelt op SQL Server 2016, kunt u Query Store opnemen in uw testen! Schakel Query Store in, doorloop uw tests in de oorspronkelijke compatibiliteitsmodus, upgrade vervolgens de compatibiliteitsmodus en test opnieuw. U kunt Query Store gebruiken om query's naast elkaar te vergelijken! (Kun je zien dat ik nu in mijn stoel dans?)

Overwegingen

Nogmaals, dit zou niet iets moeten zijn dat je zou gebruiken in productie, en ik weet dat je dat niet zou doen, maar het is de moeite waard om te herhalen, want in de huidige staat, DBCC CLONEDATABASE is niet helemaal compleet . Dit staat vermeld in het KB-artikel onder ondersteunde objecten; objecten zoals tabellen met geoptimaliseerd geheugen en bestandstabellen worden niet gekopieerd, volledige tekst wordt niet ondersteund, enz.

Nu is de kloondatabase niet zonder nadelen. Als u per ongeluk een index-rebuild of een update van statistieken in die database uitvoert, heeft u zojuist uw testgegevens gewist. U verliest de originele statistieken, wat u waarschijnlijk in de eerste plaats echt wilde. Als ik nu bijvoorbeeld de statistieken voor de geclusterde index op SalesOrderHeader controleer, krijg ik dit:

USE [AdventureWorks2014_CLONE];
GO
DBCC SHOW_STATISTICS (N'Sales.SalesOrderHeader',PK_SalesOrderHeader_SalesOrderID);

Originele statistieken voor SalesOrderHeader

Als ik nu statistieken bijwerk voor die tabel, krijg ik dit:

UPDATE STATISTICS [Sales].[SalesOrderHeader] WITH FULLSCAN;
GO
 
DBCC SHOW_STATISTICS (N'Sales.SalesOrderHeader',PK_SalesOrderHeader_SalesOrderID);

Bijgewerkte (lege) statistieken voor SalesOrderHeader

Als extra veiligheid is het waarschijnlijk een goed idee om automatische updates voor statistieken uit te schakelen:

USE [master];
GO
ALTER DATABASE [AdventureWorks2014_CLONE] SET AUTO_UPDATE_STATISTICS OFF WITH NO_WAIT;

Als u onbedoeld statistieken bijwerkt, draait u DBCC CLONEDATABASE en het back-up- en herstelproces doorlopen is niet zo moeilijk, en je hebt het in een mum van tijd geautomatiseerd.

U kunt gegevens aan de database toevoegen. Dit kan handig zijn als u wilt experimenteren met statistieken (bijv. verschillende samplefrequenties, gefilterde statistieken) en u voldoende opslagruimte heeft om een ​​kopie van de tabelgegevens te bewaren.

Zonder gegevens in de database krijgt u uiteraard geen betrouwbaar representatieve duur- en I/O-gegevens. Dat is goed. Als u gegevens nodig heeft over het werkelijke gebruik van hulpbronnen, dan heeft u een kopie van uw database nodig met alle gegevens erin. DBCC CLONEDATABASE gaat echt over het testen van de prestaties van query's; dat is het. Het is op geen enkele manier een vervanging voor traditionele upgradetests, maar het is een nieuwe optie om te valideren hoe SQL Server een query optimaliseert met verschillende versies en compatibiliteitsmodi. Veel plezier met testen!


  1. Is het mogelijk om een ​​door komma's gescheiden kolom op te vragen voor een specifieke waarde?

  2. Bibliotheek niet geladen:libmysqlclient.16.dylib-fout bij het uitvoeren van 'rails server' op OS X 10.6 met mysql2 gem

  3. Alles wat u moet weten over SQL Server JOINS

  4. Toestemming geweigerd voor relatie