Numa replicação transaccional em Microsoft SQL Server 2005, pode utilizar o parâmetro
SubscriptionStreams para permitir múltiplas ligações que utiliza o serviço de distribuição para aplicar lotes de alterações em paralelo para o subscritor. Ao mesmo tempo, o serviço de distribuição podem ainda manter muitas as mesmas características transaccionais como quando o serviço de distribuição utiliza uma única ligação para aplicar as alterações.
Nota Nos seguintes secções, uma sessão relacionado com uma ligação que abre o serviço de distribuição para a instância do SQL Server no subscritor.
Este artigo descreve os seguintes tópicos:
- Como resolver o problema quando o Distribution Agent muda para utilizar apenas uma sessão.
- Como determinar um valor eficiente para SubscriptionStreams parâmetro.
O comportamento do Distribution Agent depois de especificar o parâmetro SubscriptionStreams
O serviço de distribuição mantém o número de sessões que especificar no parâmetro
SubscriptionStreams . O serviço de distribuição utiliza estas sessões para aplicar as alterações no subscritor.
No entanto, depois de especificar o parâmetro
SubscriptionStreams e o serviço de distribuição é executado durante algum tempo, o serviço de distribuição poderão mudar para utilizar apenas uma sessão para aplicar alterações para o subscritor.
Razões para o serviço de distribuição mudar para utilizar apenas uma sessão
O serviço de distribuição poderão mudar para utilizar apenas uma sessão para muitos motivos. Seguem-se as razões mais comuns:
- Quando o Distribution Agent está a aplicar as alterações, uma das sessões aumenta um erro.
Por exemplo, o serviço de distribuição insere uma linha de uma tabela subordinada utilizando uma sessão. Se esta situação ocorre antes do Distribution Agent insere a linha correspondente na tabela principal utilizando outra sessão, uma violação de restrição de chave externa gera uma mensagem de erro. - O thread de monitor bloqueio detecta bloquear. Bloquear pode ocorrer uma das seguintes razões:
- O serviço de distribuição efectua uma operação INSERT e uma operação UPDATE numa tabela no subscritor, utilizando diferentes sessões. Se a tabela contém um índice agrupado exclusivo, bloqueio entre duas sessões poderão ocorrer quando o serviço de distribuição actualiza as teclas de índice da tabela.
- No subscritor, o serviço de distribuição executa instruções DML em várias tabelas. Se uma vista indexada é definida nestas tabelas, bloqueio entre duas sessões poderão ocorrer quando a vista indexada actualiza as chaves partilhadas índice.
- O serviço de distribuição executa uma declaração DML contra uma tabela no subscritor, utilizando uma sessão. DML accionadores são definidos nesta tabela. Os accionadores DML execute instruções DML outra tabela que está a ser actualizada utilizando outra sessão. Nesta situação, o bloqueio entre duas sessões poderá ocorrer.
Recomendamos vivamente que não a utilizem os seguintes objectos de base de dados na base de dados do subscritor:
- Restrições de chave externa
- Índices exclusivos agrupados
- As vistas indexadas
- Accionadores DML que podem causar o bloqueio entre sessões
Como determinar se o serviço de distribuição mudou para utilizar apenas uma sessão
Para o fazer, utilize um dos seguintes métodos.
Nota Apesar de pode confirmar que o serviço de distribuição não mudou para utilizar uma sessão utilizando o método 1, tem de utilizar o método 2 ou o método 3 para confirmar que o serviço de distribuição mudou para utilizar uma sessão.
Método 1
Consulta as sessões de ligação à base de dados de subscrição sys.dm_exec_sessions DMV (dinâmica gestão ver). Se vir apenas uma ligação à sessão, o serviço de distribuição podem ter mudado para utilizar uma sessão. Se vir mais do que uma sessão de ligação, o Distribution Agent ainda está a utilizar o número de sessões especificado.
Para confirmar que o serviço de distribuição mudou para utilizar uma sessão, utilize o método 2 ou o método 3.
Método 2
Consulta a coluna de
comentários da tabela msdistribution_history na base de dados distribuição. Se o resultado da consulta contiver a seguinte entrada, o serviço de distribuição mudou para utilizar uma sessão:
O processo falhou concluir a última secção no modo de transmissão em sequência multi, foi reposto para o modo de ligação único e é repetir a operação.
Método 3
Examine o ficheiro de saída do serviço de distribuição. O serviço de distribuição mudou para utilizar apenas uma sessão se o ficheiro de saída contém a mesma mensagem de erro como método 2.
O ficheiro de saída seguinte é um exemplo:
<Date><Time>transacção (ões 100) com 1181 command(s) foram entregues.
<Date><Time>transacção (ões 100) com 2672 command(s) foram entregues.
<Date><Time>Recipiente 6 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 1 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 3 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 0 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 5 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 2 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 7 abortada evento preparado para consolidar, aguardar impasse encontrado entre spid 117 e 114
<Date><Time>Recipiente 4 abortada a espera para evento-se para consolidar, devido a eventos de encerramento de thread
...
<Date><Time>Número de sequências de subscrição foi reposto de 8 para 1, estado 4.
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Desligar subscritor <SQLinstance>
<Date><Time>Ligar a estação <SQLinstance>
<Date><Time>O processo falhou concluir a última secção no modo de transmissão em sequência multi, foi reposto para o modo de ligação único e é repetir a operação.
<Date><Time>21 transacção (ões) com 390 command(s) foram entregues.
Como resolver um serviço de distribuição que muda para utilizar apenas uma sessão
- Execute o SQL Server Profiler no subscritor para capturar o evento bloqueado processo de relatório e o evento de excepção . Gravar estes eventos bloquear e erros que ocorrem quando o serviço de distribuição aplica alterações.
Nota O evento de excepção pode ser provocado por qualquer tipo de erro que pode ser associado com o problema. Por exemplo, o erro pode ser causado por uma violação de restrição de chave externa. - Utilize um dos métodos na secção "Como determinar se o serviço de distribuição mudou para utilizar apenas uma sessão" para monitorizar o serviço de distribuição.
- Se o serviço de distribuição mudou para utilizar uma sessão, pare o rastreio.
- A partir de ficheiro de saída do agente de distribuição ou de coluna da tabela msdistribution_history hora_início , obter o carimbo de data da seguinte entrada:
O processo falhou concluir a última secção no modo de transmissão em sequência multi, foi reposto para o modo de ligação único e é repetir a operação.
- Abra o ficheiro rastreio (.trc) a partir do subscritor. Localize um bloqueio script ou um evento de excepção cujo carimbo de data é igual ou muito parecido com o carimbo de data obtido no passo 4.
- Se notar uma excepção, examine os detalhes da excepção para determinar a causa. Por exemplo, a excepção pode ser causada por uma violação de restrição de chave externa. Se for este o caso, a Microsoft recomenda que remova a restrição de chave externa na base de dados subscritor.
Se notar um script de bloqueio, o problema é causado por bloquear. The following is a sample blocking script:<blocked-process-report monitorLoop="41589">
<blocked-process>
<process id="process3a6d438" taskpriority="0" logused="24592" waitresource="KEY: 6:72057594375700480 (0100e420fa5a)" waittime="9937" ownerId="568644832" transactionname="user_transaction" lasttranstarted="2008-05-05T04:55:04.430" XDES="0xa5619e370" lockMode="X" schedulerid="11" kpid="6104" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2008-05-05T04:55:04.553" lastbatchcompleted="2008-05-05T04:55:04.430" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644832" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056">
<executionStack>
<frame line="5" stmtstart="642" stmtend="1600" sqlhandle="0x0300060057a14477a8c6dd00609a00000100000000000000"/>
</executionStack>
<inputbuf>
Proc [Database Id = 6 Object Id = 2000986455] </inputbuf>
</process>
</blocked-process>
<blocking-process>
<process status="sleeping" spid="68" sbid="0" ecid="0" priority="0" transcount="1" lastbatchstarted="2008-05-05T04:55:04.570" lastbatchcompleted="2008-05-05T04:55:05.103" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644998" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056">
<executionStack/>
<inputbuf>
Proc [Database Id = 6 Object Id = 1172459501] </inputbuf>
</process>
</blocking-process>
</blocked-process-report>
o bloqueio script regista uma sessão bloqueada e uma sessão de bloqueio. Inicia a sessão bloqueada da tag <blocked-process>. Inicia a sessão de bloqueio da tag <blocking-process>. - Localize o ID do objecto PROC. na sessão bloqueada e na sessão bloqueio.
No exemplo bloquear script, o ID de objecto do objecto PROC. na sessão bloqueado é 2000986455. O ID de objecto do objecto PROC. na sessão bloqueio é 1172459501. - Na base de dados de subscrição e consulta a vista sys.objects especificando a coluna object_id para ser igual ao objecto ID obtido no passo 7. Quando o fizer, pode determinar os nomes de objectos.
Por exemplo, execute a seguinte consulta no contexto da base de dados de subscrição: USE <SubDBName>
GO
SELECT name FROM sys.objects
WHERE object_id = 1172459501 OR object_id = 2000986455
notas - O <SubDBName> marcador de posição representa o nome da base de dados de subscrição.
- Normalmente, estes objectos são procedimentos armazenados que são utilizados na replicação.
- Determine o índice remissivo ou na vista indexada que faz com que o bloqueio. Para o fazer, siga estes passos:
- No script de bloqueio, localize o valor da propriedade waitresource .
No exemplo bloquear script, o valor da propriedade waitresource é 72057594375700480. - Consulta a vista sys.partitions para obter o ID de objecto e o ID de índice, especificando a coluna PARTITION_ID seja igual ao valor da propriedade waitresource obtido no passo 9a.
Por exemplo, execute a seguinte consulta: SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
- Na base de dados de subscrição e consulta a vista sys.indexes para determinar o índice utilizando o ID de objecto e o ID de índice que obtido no passo 9b.
Por exemplo, execute a seguinte consulta: nome USE <SubDBName>
GO
SELECT name, type_desc, is_unique FROM sys.indexes
WHERE object_id = <objID> and index_id = <idxID>
Nota O <objID> marcador de posição representa o ID do objecto obtida no passo 9b. O <idxID> marcador de posição representa o ID de índice que obtido no passo 9b.
- Se bloquear for causada por uma vista indexada, recomendamos que largar na vista indexada. Se bloquear for causada por um índice agrupado exclusivo, recomendamos que pode colocar o índice e, em seguida, volte a criar um índice não exclusivo.
Descrição do bloqueio thread de monitor
O serviço de distribuição mantém um bloqueio thread de monitor que detecta o bloqueio entre as sessões. Se o thread de monitor bloqueio detecta bloqueio entre as sessões, o serviço de distribuição muda para utilizar uma sessão para reaplicar a secção actual de comandos que o Distribution Agent não conseguiu aplicar anteriormente.
Para obter mais informações sobre o bloqueio thread de monitor, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956601
(http://support.microsoft.com/kb/956601/
)
Descrição do thread de monitor bloqueio no SQL Server 2005
Como o serviço de distribuição retoma várias sessões
Antes do serviço de distribuição pode retomar várias sessões, o serviço de distribuição tem de executar o procedimento
sp_MSget_repl_commands armazenados para repetir a consulta a base de dados distribuição para os comandos que não tenham sido aplicadas no subscritor. Em seguida, o serviço de distribuição tem de aplicar estes comandos no subscritor, antes do serviço de distribuição pode retomar múltiplas sessões. Num ambiente latente replicação, o Distribution Agent não é possível retomar as sessões múltiplas porque o serviço de distribuição tem de aplicar muitos dos comandos no subscritor, antes do serviço de distribuição pode retomar várias sessões.
Para controlar todo o processo, examine o ficheiro de saída do serviço de distribuição.
Para obter mais informações sobre como utilizar o parâmetro SubscriptionStreams para melhorar o débito de subsistema do disco, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956600
(http://support.microsoft.com/kb/956600/
)
Como utilizar o parâmetro SubscriptionStreams para testar para débito de subsistema de disco melhorados no SQL Server 2005