AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 44570
Accepted
ooutwire
ooutwire
Asked: 2013-06-15 13:57:08 +0800 CST2013-06-15 13:57:08 +0800 CST 2013-06-15 13:57:08 +0800 CST

O SQL Server verifica o espaço em disco antes de alocar uma nova página?

  • 772

Fiz uma aposta com meu antigo chefe. Aposto com ela que o SQL Server, ao alocar uma nova extensão, sempre aloca do buffer pool e nunca verifica se existe algum lugar no disco onde a alocação possa ser armazenada. Essencialmente, ela contesta que o SQL Server deve verificar o espaço disponível no LUN antes de alocar uma página. Isso parece errado, já que eu poderia colocar meu armazenamento na lua, o que causaria uma latência séria. Eu sinto que ela realmente deseja que o SQL Server sempre traga uma página do disco primeiro e depois execute a (s) tarefa (s) DML.

Aqui está a minha "prova" de que ela está errada. Se você discordar da minha "prova", então, por favor, responda com uma melhor!

Vamos criar um banco de dados e uma tabela triviais. O modelo de recuperação do banco de dados será definido como SIMPLE e AUTO_CREATE_STATISTICS será desativado para minimizar o inchaço do registro de log.

Antes de começarmos, deixe-me divulgar a versão do SQL Server que estou usando.

SELECIONE @@VERSÃO;
-------------------------------------------------- -----------------------------------
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Developer Edition (64 bits) no Windows NT 6.1 (Build 7601: Service Pack 1)

Agora, o código...

USE mestre;
VAI

IF DATABASEPROPERTYEX(N'PageAllocDemo' , N'Version') > 0
      COMEÇAR
            ALTER DATABASE PageAllocDemo SET SINGLE_USER COM ROLLBACK IMEDIATO;
            DROP DATABASE PageAllocDemo;
      FIM;
VAI

CREATE DATABASE PageAllocDemo
VAI

USE PageAllocDemo;
VAI
SET NOCOUNT ON;
VAI

-- Defina o banco de dados como SIMPLE e desative o crapola de geração de log
ALTER DATABASE PageAllocDemo SET RECUPERAÇÃO SIMPLES;
VAI
ALTER DATABASE PageAllocDemo SET AUTO_CREATE_STATISTICS OFF;
VAI

CRIAR TABELA dbo.X
(
      c1 IDENTIDADE INT (1,1)
) EM [PRIMÁRIO];
VAI

Agora, vamos verificar quantas páginas foram alocadas? Suspeito de zero, pois criamos apenas uma "tabela lógica", no nosso caso um heap vazio.

-- Quantas páginas estão alocadas em nossa tabela?
DBCC IND (PageAllocDemo,X,-1);
VAI

Agora, limpe o registro.

-- Limpa o registro
PONTO DE VERIFICAÇÃO;
VAI

O que está atualmente no log?

-- O que está no log agora?
SELECT * FROM fn_dblog(NULL,NULL);
VAI

/*

---------------------------------------
-- Operação -------------- Contexto ---
---------------------------------------
LOP_BEGIN_CKPT LCX_NULL
LOP_XACT_CKPT LCX_BOOT_PAGE_CKPT
LOP_END_CKPT LCX_NULL

*/

Isso é esperado, pois estamos no modelo de recuperação SIMPLES. Vamos agora criar uma transação explícita que irá inserir um e apenas um registro em nossa tabela; mas, antes disso, vamos abrir o Process Monitor e filtrar nosso arquivo MDF e LDF, bem como o PID para o processo do SQL Server.

insira a descrição da imagem aqui

Inicie a transação:

INICIAR TRAN

    INSERIR NOS VALORES PADRÃO dbo.X;
    VAI

O Process Monitor mostra duas gravações no arquivo de log de transações. insira a descrição da imagem aqui

Vamos verificar os registros de log.

-- O que está no log agora?
    SELECT * FROM fn_dblog(NULL,NULL);

    /*
    Omiti todos os registros de log para PFS, GAM, SGAM, etc.
    -------------------------------------------------- -------------
    -- Operação -------------- Contexto ------- ID da transação ---
    -------------------------------------------------- -------------
    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

*/

Eu omito o mapa de bits e as alocações de PFS e podemos ver que uma página é alocada e uma linha é inserida como seria de esperar.

Quantas páginas estão alocadas em nosso heap?

-- Quantas páginas estão alocadas em nossa tabela?
    DBCC IND (PageAllocDemo,X,-1);
    VAI

    /*

    Uma página IAM e uma página de dados e nada mais
    ----------------------------------
    PáginaFID PáginaPID IAMFID IAMPID      
    ------- ----------- ------ ------
    1 264 NULO NULO        
    1 231 1 264         

    */

Isso é como previsto. Temos uma página IAM e uma página de dados. Agora, nossa penúltima ação é confirmar a transação. Espero que ocorra uma descarga de bloco de log 512B neste ponto.

COMEÇAR TRAN;

insira a descrição da imagem aqui

Terminemos a "prova" com uma operação de ponto de verificação. Até agora, nada foi confirmado no arquivo de dados apenas no arquivo de log.

PONTO DE VERIFICAÇÃO;
VAI

insira a descrição da imagem aqui

Legal, as páginas de dados foram liberadas para o disco conforme o esperado.

Minha conclusão, a partir da evidência do Process Monitor, é que o SQL Server aloca na memória, adiciona o registro na memória e confirma a página no disco sem verificar nada no nível de armazenamento.

Alguém se opõe a esta hipótese? Se sim, por quê?

sql-server-2008-r2 storage-engine
  • 1 1 respostas
  • 964 Views

1 respostas

  • Voted
  1. Best Answer
    mrdenny
    2013-06-15T17:27:26+08:002013-06-15T17:27:26+08:00

    Não há necessidade de verificar o espaço em disco ao alocar uma nova extensão para um objeto. O SQL Server já possui esse espaço no disco. Ele sabe quais páginas dentro de seu arquivo de dados são alocadas e quais não são, então não há necessidade de verificar se nós possuímos as páginas na medida em que sabemos que já possuímos. Ele simplesmente alocará espaço no buffer pool e gravará os dados na memória e, em seguida, sobrescreverá o que estiver nesse espaço no disco quando o ponto de verificação ocorrer.

    A única vez que o SQL Server se preocupa em ver quanto espaço livre há no disco é quando ele está realmente expandindo o arquivo de dados.

    • 4

relate perguntas

  • plano de manutenção executado pelo agente

  • Quais são as razões **NÃO** para usar o mecanismo de armazenamento MEMORY no MySQL?

  • Randomizando o conteúdo da tabela e armazenando-o de volta na tabela

  • Acelerando a conversão de MyISAM para InnoDB

  • Quais são os prós e os contras de usar o Sphinx Storage Engine?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve