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 / 60830
Accepted
John Russell
John Russell
Asked: 2014-03-14 03:45:35 +0800 CST2014-03-14 03:45:35 +0800 CST 2014-03-14 03:45:35 +0800 CST

Desempenho do SQL Server: tipo de espera dominante PREEMPTIVE_OS_DELETESECURITYCONTEXT

  • 772

Recebi uma ligação ontem de um cliente reclamando do alto uso da CPU em seu SQL Server. Estamos usando o SQL Server 2012 SE de 64 bits. O servidor está executando o Windows Server 2008 R2 Standard, Intel Xeon de 2,20 GHz (4 núcleos), 16 GB de RAM.

Depois de ter certeza de que o culpado era de fato o SQL Server, dei uma olhada nas principais esperas da instância usando a consulta DMV aqui . As duas primeiras esperas foram: (1) PREEMPTIVE_OS_DELETESECURITYCONTEXTe (2) SOS_SCHEDULER_YIELD.

EDIT : Aqui está o resultado da "consulta de espera superior" (embora alguém tenha reiniciado o servidor esta manhã contra minha vontade):

insira a descrição da imagem aqui

Fazemos muitos cálculos/conversões intensos, para que eu possa entender SOS_SCHEDULER_YIELD. No entanto, estou muito curioso sobre o PREEMPTIVE_OS_DELETESECURITYCONTEXTtipo de espera e por que pode ser o mais alto.

A melhor descrição/discussão que posso encontrar sobre esse tipo de espera pode ser encontrada aqui . Ele menciona:

Os tipos de espera PREEMPTIVE_OS_ são chamadas que deixaram o mecanismo de banco de dados, geralmente para uma API Win32, e executam código fora do SQL Server para várias tarefas. Neste caso, está excluindo um contexto de segurança usado anteriormente para acesso remoto a recursos. A API relacionada é, na verdade, chamada DeleteSecurityContext()

Que eu saiba, não temos nenhum recurso externo, como servidores vinculados ou tabelas de arquivos. E não fazemos nenhuma representação, etc. Um backup pode ter causado esse pico ou talvez um controlador de domínio com defeito?

O que diabos poderia fazer com que esse seja o tipo de espera dominante? Como posso rastrear esse tipo de espera ainda mais?

Editar 2: verifiquei o conteúdo do log de segurança do Windows. Vejo algumas entradas que podem ser interessantes, mas não tenho certeza se são normais:

Special privileges assigned to new logon.

Subject:
    Security ID:        NT SERVICE\MSSQLServerOLAPService
    Account Name:       MSSQLServerOLAPService
    Account Domain:     NT Service
    Logon ID:       0x3143c

Privileges:     SeImpersonatePrivilege

Special privileges assigned to new logon.

Subject:
    Security ID:        NT SERVICE\MSSQLSERVER
    Account Name:       MSSQLSERVER
    Account Domain:     NT Service
    Logon ID:       0x2f872

Privileges:     SeAssignPrimaryTokenPrivilege
            SeImpersonatePrivilege

Editar 3 : @Jon Seigel, como você solicitou, aqui estão os resultados de sua consulta. Um pouco diferente do de Paulo:

insira a descrição da imagem aqui

Edit 4: Admito que sou um usuário de eventos estendidos pela primeira vez. Adicionei esse tipo de espera ao evento wait_info_external e vi centenas de entradas. Não há texto sql ou identificador de plano, apenas uma pilha de chamadas. Como posso rastrear ainda mais a fonte?

insira a descrição da imagem aqui

sql-server sql-server-2012
  • 2 2 respostas
  • 1968 Views

2 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2014-03-16T10:55:56+08:002014-03-16T10:55:56+08:00

    Eu sei que esta questão, com base no título, está principalmente preocupada com o tipo de espera PREEMPTIVE_OS_DELETESECURITYCONTEXT, mas acredito que seja um desvio do verdadeiro problema que é " um cliente que estava reclamando de alto uso de CPU em seu SQL Server ".

    A razão pela qual acredito que o foco nesse tipo de espera específico é uma busca inútil é porque ele aumenta a cada conexão feita. Estou executando a seguinte consulta no meu laptop (o que significa que sou o único usuário):

    SELECT * 
    FROM sys.dm_os_wait_stats
    WHERE wait_type = N'PREEMPTIVE_OS_DELETESECURITYCONTEXT'
    

    E então eu faço qualquer um dos seguintes e executo novamente esta consulta:

    • abrir uma nova guia de consulta
    • feche a nova guia de consulta
    • execute o seguinte em um prompt do DOS:SQLCMD -E -Q "select 1"

    Agora, sabemos que a CPU está alta, então devemos olhar o que está rodando para ver quais sessões têm CPU alta:

    SELECT req.session_id AS [SPID],
           req.blocking_session_id AS [BlockedBy],
           req.logical_reads AS [LogReads],
           DB_NAME(req.database_id) AS [DatabaseName],
           SUBSTRING(txt.[text],
                     (req.statement_start_offset / 2) + 1,
                     CASE
                         WHEN req.statement_end_offset > 0
                            THEN (req.statement_end_offset - req.statement_start_offset) / 2
                         ELSE LEN(txt.[text])
                     END
                    ) AS [CurrentStatement],
           txt.[text] AS [CurrentBatch],
           CONVERT(XML, qplan.query_plan) AS [StatementQueryPlan],
           OBJECT_NAME(qplan.objectid, qplan.[dbid]) AS [ObjectName],
           sess.[program_name],
           sess.[host_name],
           sess.nt_user_name,
           sess.total_scheduled_time,
           sess.memory_usage,
           req.*
    FROM sys.dm_exec_requests req
    INNER JOIN sys.dm_exec_sessions sess
            ON sess.session_id = req.session_id
    CROSS APPLY sys.dm_exec_sql_text(req.[sql_handle]) txt
    OUTER APPLY sys.dm_exec_text_query_plan(req.plan_handle,
                                            req.statement_start_offset,
                                            req.statement_end_offset) qplan
    WHERE req.session_id <> @@SPID
    ORDER BY req.logical_reads DESC, req.cpu_time DESC
    --ORDER BY req.cpu_time DESC, req.logical_reads DESC
    

    Normalmente, executo a consulta acima como está, mas você também pode alternar qual cláusula ORDER BY é comentada para ver se isso fornece resultados mais interessantes/úteis.

    Como alternativa, você pode executar o seguinte, com base em dm_exec_query_stats, para localizar as consultas de custo mais alto. A primeira consulta abaixo mostrará consultas individuais (mesmo que tenham vários planos) e é ordenada por Average CPU Time, mas você pode facilmente alterar isso para Average Logical Reads. Depois de encontrar uma consulta que parece estar consumindo muitos recursos, copie "sql_handle" e "statement_start_offset" na condição WHERE da segunda consulta abaixo para ver os planos individuais (pode ser mais de 1). Role para a extrema direita e supondo que haja um plano XML, ele será exibido como um link (no modo de grade) que o levará ao visualizador do plano se você clicar nele.

    Consulta nº 1: obter informações da consulta

    ;WITH cte AS
    (
       SELECT qstat.[sql_handle],
              qstat.statement_start_offset,
              qstat.statement_end_offset,
              COUNT(*) AS [NumberOfPlans],
              SUM(qstat.execution_count) AS [TotalExecutions],
    
              SUM(qstat.total_worker_time) AS [TotalCPU],
              (SUM(qstat.total_worker_time * 1.0) / SUM(qstat.execution_count)) AS [AvgCPUtime],
              MAX(qstat.max_worker_time) AS [MaxCPU],
    
              SUM(qstat.total_logical_reads) AS [TotalLogicalReads],
       (SUM(qstat.total_logical_reads * 1.0) / SUM(qstat.execution_count)) AS [AvgLogicalReads],
              MAX(qstat.max_logical_reads) AS [MaxLogicalReads],
    
              SUM(qstat.total_rows) AS [TotalRows],
              (SUM(qstat.total_rows * 1.0) / SUM(qstat.execution_count)) AS [AvgRows],
              MAX(qstat.max_rows) AS [MaxRows]
       FROM sys.dm_exec_query_stats  qstat
       GROUP BY qstat.[sql_handle], qstat.statement_start_offset, qstat.statement_end_offset
    )
    SELECT  cte.*,
            DB_NAME(txt.[dbid]) AS [DatabaseName],
            SUBSTRING(txt.[text],
                      (cte.statement_start_offset / 2) + 1,
                      CASE
                          WHEN cte.statement_end_offset > 0
                              THEN (cte.statement_end_offset - cte.statement_start_offset) / 2
                          ELSE LEN(txt.[text])
                      END
                     ) AS [CurrentStatement],
            txt.[text] AS [CurrentBatch]
    FROM cte
    CROSS APPLY sys.dm_exec_sql_text(cte.[sql_handle]) txt
    ORDER BY cte.AvgCPUtime DESC
    

    Consulta nº 2: obter informações do plano

    SELECT  *,
            DB_NAME(qplan.[dbid]) AS [DatabaseName],
            CONVERT(XML, qplan.query_plan) AS [StatementQueryPlan],
            SUBSTRING(txt.[text],
                      (qstat.statement_start_offset / 2) + 1,
                      CASE
                            WHEN qstat.statement_end_offset > 0
                            THEN (qstat.statement_end_offset - qstat.statement_start_offset) / 2
                            ELSE LEN(txt.[text])
                      END
                     ) AS [CurrentStatement],
            txt.[text] AS [CurrentBatch]
    FROM sys.dm_exec_query_stats  qstat
    CROSS APPLY sys.dm_exec_sql_text(qstat.[sql_handle]) txt
    OUTER APPLY sys.dm_exec_text_query_plan(qstat.plan_handle,
                                            qstat.statement_start_offset,
                                            qstat.statement_end_offset) qplan
    -- paste info from Query #1 below
    WHERE qstat.[sql_handle] = 0x020000001C70C614D261C85875D4EF3C90BD18D02D62453800....
    AND qstat.statement_start_offset = 164
    -- paste info from Query #1 above
    ORDER BY qstat.total_worker_time DESC
    
    • 3
  2. Jens W.
    2014-03-14T04:07:04+08:002014-03-14T04:07:04+08:00

    O SecurityContext é usado pelo servidor SQL em vários lugares. Um exemplo que você nomeou são os servidores vinculados e as tabelas de arquivos. Talvez você esteja usando cmdexec? Trabalhos do SQL Server Agent com contas proxy? Chamando um webservice? Recursos remotos podem ser muitas coisas engraçadas.

    Os eventos de representação podem ser registrados no evento de segurança do Windows. Pode ser que você esteja encontrando uma pista lá. Além disso, você pode querer verificar o gravador de caixa preta, também conhecido como eventos estendidos.

    Você verificou se esses Wait-Types são novos (e em conexão com a alta CPU) ou apenas normais para o seu servidor?

    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

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

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 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

    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
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • 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
    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