Estamos vendo tipos de espera PAGELATCH_EX e PAGELATCH_SH muito altos junto com esperas WRITELOG altas. Eu diagnostiquei a consulta que causa as esperas PAGELATCH e posso eliminá-las reduzindo a taxa de inserção em uma chave primária agrupada ocupada definida com um valor IDENTITY. Entendo que esse fenômeno é conhecido como contenção de trava de inserção da última página.
No entanto, minha pergunta é quando um novo registro é inserido, o SQL Server pega um PAGELATCH_EX exclusivo em uma página de buffer, insere o registro na página do buffer, grava o registro no log de transações e libera o PAGELATCH_EX exclusivo conforme detalhado https:// www.microsoft.com/en-ie/download/details.aspx?id=26665 Página 24. Ou ele grava o registro no log de transações primeiro antes de usar o PAGELATCH_EX conforme detalhado "Resolvendo a contenção de PAGELATCH em cargas de trabalho INSERT altamente simultâneas - Informações básicas Guia do SQLCAT para: Mecanismo Relacional
Se o registro for gravado fora do mecanismo de travamento, posso descartar gravações lentas no disco como causa de altas esperas de PAGELATCH. Mas se a trava for mantida até que o registro seja endurecido para log, provavelmente devo levar o WRITELOG em consideração.
Além disso, ter vários índices não clusterizados faria com que a trava PAGELATCH_* fosse mantida por mais tempo, ou seja, se uma tabela tivesse um cluster e vários índices não clusterizados fossem adicionados e liberados para cada uma das páginas do buffer de índice simultaneamente?
Atualização 1 Depois de ler o slide dois do confio-sql-server-writelog-wait e a arquitetura geral do WAL. Agora entendo que a etapa "Registrar uma entrada de log de que a linha foi modificada" detalhada em ambos os white papers refere-se ao SQL Server registrando uma alteração no cache do log de transações, não no disco. Assim que a transação for concluída ou o buffer estiver cheio, todos os registros serão imediatamente descarregados no disco.
Você deve observar que a trava protege apenas a integridade física da página enquanto ela está na memória, portanto, a trava seria tomada quando a página estivesse na memória. Suponha que um registro esteja sendo inserido e para essa página precise ser buscado. Primeiro, a página seria bloqueada e trazida para a memória, depois seria travada e as informações seriam gravadas. O processo depois disso seria
Gerar registro de log
Atualize o LSN da página para corresponder ao do registro de log
Alterar dados (sujar a página)
Trava de liberação
Confirmar início da transação
FlushToLSN do Commit
Liberar bloqueios
Confirmar transação concluída
Para obter mais detalhes e explicações sobre as etapas acima, leia o blog de apresentação I/O de Bob Dorr
As esperas Pagelatch* não são esperas de E/S e, na maioria das vezes, essas esperas são proeminentes devido à contenção de alocação. Meu palpite é que tem a ver com como
tempdb is configured
. Então, como seu tempdb está configurado?, quantos arquivos de dados tempdb estão presentes? Certifique -se de que eles tenham o mesmo crescimento automático e o mesmo tamanho. Quando uma nova página é criada, páginas do sistema como páginas GAM, SGAM e PFS precisam ser atualizadas ou acessadas e quando o SQL Server encontra contenção ao acessar essas páginas, essa espera entra em cena.