Question

J'ai un pari avec mon ancien patron. Je parie que SQL Server, lors de l'allocation d'une nouvelle étendue, alloue toujours à partir du pool de tampons et ne vérifie jamais s'il y a une place sur le disque où l'allocation pourrait être stockée. Essentiellement, elle conteste que SQL Server devrait vérifier l'espace disponible sur le LUN avant d'allouer une page. Cela semble mal, car je pouvais placer mon stockage sur la lune, ce qui provoquerait une latence sérieuse. Je pense qu'elle veut vraiment que SQL Server apporte toujours une page à partir du disque, puis exécuter la ou les tâches DML.

Voici ma "preuve" qu'elle a tort. Si vous n'êtes pas d'accord avec ma "preuve", veuillez répondre très certainement avec une meilleure!

Créons une base de données et un tableau triviales. Le modèle de récupération de la base de données sera défini sur simple et auto_create_statistics sera fermé, afin de minimiser le ballonnement des enregistrements du journal.

Avant de commencer, permettez-moi de divulguer la version de SQL Server que j'utilise.

SELECT @@VERSION;
-------------------------------------------------------------------------------------
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
Developer Edition (64-bit) on Windows NT 6.1  (Build 7601: Service Pack 1)

Maintenant, le code ...

USE master;
GO

IF DATABASEPROPERTYEX(N'PageAllocDemo' , N'Version') > 0 
      BEGIN
            ALTER DATABASE PageAllocDemo SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
            DROP DATABASE PageAllocDemo;
      END;
GO

CREATE DATABASE PageAllocDemo
GO

USE PageAllocDemo;
GO
SET NOCOUNT ON;
GO

-- Set the database to SIMPLE and turn off log generating crapola
ALTER DATABASE PageAllocDemo SET RECOVERY SIMPLE;
GO
ALTER DATABASE PageAllocDemo SET AUTO_CREATE_STATISTICS OFF;
GO

CREATE TABLE dbo.X
(
      c1 INT IDENTITY (1,1)
) ON [PRIMARY];
GO

Maintenant, vérifions combien de pages ont été allouées? Je soupçonne zéro, car nous n'avons créé qu'une "table logique", dans notre cas un tas vide.

-- How many pages are allocated to our table?
DBCC IND (PageAllocDemo,X,-1);
GO

Maintenant, effacez le journal.

-- Clear the log
CHECKPOINT;
GO

Qu'est-ce qui est actuellement dans le journal?

-- What is in the log right now?
SELECT * FROM fn_dblog(NULL,NULL);
GO

/*

---------------------------------------
-- Operation -------------- Context ---
---------------------------------------
LOP_BEGIN_CKPT      LCX_NULL
LOP_XACT_CKPT       LCX_BOOT_PAGE_CKPT
LOP_END_CKPT        LCX_NULL

*/

Cela est prévu, car nous sommes dans le modèle de récupération simple. Nous allons désormais créer une transaction explicite qui inséra un et un seul enregistrement dans notre tableau; mais, avant de le faire, ouvrez le moniteur de processus et le filtrage du processus pour notre fichier MDF et LDF ainsi que le PID pour le processus SQL Server.

enter image description here

Commencez la transaction:

BEGIN TRAN

    INSERT INTO dbo.X DEFAULT VALUES;
    GO

Process Monitor affiche deux écritures dans le fichier journal des transactions.enter image description here

Vérirons les enregistrements du journal.

-- What is in the log right now?
    SELECT * FROM fn_dblog(NULL,NULL);

    /*
    I omitted all the log records for PFS, GAM, SGAM, etc.
    ---------------------------------------------------------------
    -- Operation -------------- Context ------- Transaction ID  ---
    ---------------------------------------------------------------
    LOP_BEGIN_XACT      LCX_NULL                0000:0000030e
    LOP_BEGIN_XACT      LCX_NULL                0000:0000030f
    LOP_FORMAT_PAGE     LCX_HEAP                0000:0000030f
    LOP_COMMIT_XACT     LCX_NULL                0000:0000030f
    LOP_INSERT_ROWS     LCX_HEAP                0000:0000030e
    LOP_COMMIT_XACT     LCX_NULL                0000:0000030e

*/

J'omet les allocations de la carte des bits et de la PFS et nous pouvons voir qu'une page est allouée et qu'une ligne est insérée comme on pourrait s'y attendre.

Combien de pages sont allouées à notre tas?

-- How many pages are allocated to our table?
    DBCC IND (PageAllocDemo,X,-1);
    GO

    /*

    One IAM page and one data page and nothing else
    ---------------------------------
    PageFID PagePID     IAMFID IAMPID      
    ------- ----------- ------ ------ 
    1       264         NULL   NULL        
    1       231         1      264         

    */

C'est comme prévu. Nous avons une page IAM et une page de données. Maintenant, notre avant-dernière action consiste à commettre la transaction. Je m'attends à ce qu'un bouton de bloc de journal 512B se produise à ce stade.

COMMIT TRAN;

enter image description here

Termons la "preuve" avec une opération de point de contrôle. Jusqu'à présent, rien n'a été attaché au fichier de données uniquement dans le fichier journal.

CHECKPOINT;
GO

enter image description here

Cool, les pages de données sont rincées sur le disque comme prévu.

Ma conclusion, à partir des preuves de Process Monitor est que SQL Server alloue en mémoire, ajoute l'enregistrement en mémoire et commet la page pour le disque sans rien vérifier au niveau de stockage.

Quelqu'un s'oppose-t-il à cette hypothèse? Si oui, pourquoi?

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top