Meu log transacional encheu, qual processo foi o responsável por preencher o log?

Existem muitas interpretações possíveis para o termo “processo que preencheu o log”, você pode ter uma transação antiga aberta que impede o log de ser truncado, mesmo se essa transação gerou alguns poucos registros de log ou é simplesmente o marcador/ponteiro do processo do agente de replicação, ou você pode ter processos que geraram muita atividade em uma transação muito grande, ou ainda você pode ter processos que geraram muitas transações menores. Existe também o processo que usou o último espaço disponível de log e desta forma foi o primeiro a reportar o erro 1105.

Geralmente, depois do log ser truncado uma vez ou duas, uma grande transação aberta irá também ser a transação mais antiga aberta. Apenas por essa transação, uma sessão gerando um grande número de transações menores não deveria causar o preenchimento completo do log, se algum processo está sendo usado para truncar a log, embora isso poderia levar a grandes arquivos de “backup” do log transacional.

Determinar o uso do log por processos depende exatamente do que você quer mensurar (numero de registros, soma do tamanho de todos os registros e etc). Note que o espaço pode ser usado diretamente (tamanho real do registro do log) e indireto. Por exemplo, em um servidor SAP ASE cuja página de dados é 2k, uma transação inserindo um conjunto de linhas de 1100bytes irá usar uma página de log de 2k para cada linha inserida como somente um registro inserido irá se encaixar no tamanho da página.

Alguns formas possíveis de responder a questão indicada acima:

1)Transação mais antiga aberta

Esta é a transação que está impedindo o log de ser truncado, ela pode não ter usado muito espaço diretamente, mas como quaisquer outras transações anteriores no log não podem ser desalocadas, pode-se dizer que essa transação é a responsável for usar todo o espaço (ou ao menos o espaço até a próxima transação mais antiga aberta).

SELECT * FROM master..syslogshold

2)monProcessActivity summary

A partir do SAP ASE, você pode, de forma aproximada, ter uma idéia de quantos bytes uma conexão escreveu no log apartir da tabela de monitoração “monProcessActivity”. (ULC = “User Log Cahe”, processo que acumulou registros de log no “ULC” e os descarrega para a log em grupos.)

SELECT TOP 5

SPID,

ULCBytesWritten,

Transactions,

Commits,

Rollbacks

FROM

  1. master..monProcessActivity

ORDER BY ULCBytesWritten DESC

Porém, nem todas as atividades de log registradas na coluna “ULCBytesWritten”, e o número de transações, “commits”, e “rollbacks” dizem tudo a respeito do tamanho individual das transações ou qual banco de dados elas ocorreram. Os valores também são válidos pela existência das conexões e, devido a isso, incluem atividades que possam ter sido truncadas no log há algum tempo atrás. Logo, a query acima é mais útil se você somente tem um banco de dados principal em uso no SAP ASE e as aplicações clientes não ficam conectadas por muito tempo.

3)Transações com muitos registros

Na realidade você pode estar mais interessado em simplesmente identificar quem está executando a maior transação no log e o que essa transação faz na verdade. Isso poderia ser considerado uma problema fácil de se identificar.

A tabela de sistema que contém as informações do log transacional de um banco de dados (“syslogs”) somente expõe duas colunas para os usuários, embora cada registro de log contenha muito mais informação. A coluna “xactid” é o identificador da sessão, com dois campos (página (tipo de dado “int”), linha (tipo de dado “smallint”), concatenados no formato hexadecimal. O identificador da sessão identifica o número da página e a linha contendo o registro de log “BEGINXACT” para a transação e aparece em todos os registros de log para essa transação. A seguinte “query” identifica as transações com o maior número de registros de log.

SELECT TOP 5 — ‘5’ é arbitrário, somente usando para limitar a saída

xactid,

convert(int,substring(xactid,1,4)) as “logpage”,

convert(smallint,substring(xactid,5,2)) as “logrow”,

count(*) as “records_in_xact”

FROM

syslogs

GROUP BY

xactid

ORDER BY

count(*) desc

xactid logpage logrow records_in_xact

————- ——— —- ————–

0x00001962000b 6498 11 9951

0x000019410010 6465 16 38

0x000019440009 6468 9 37

0x0000195d0002 6493 2 34

0x000019610003 6497 3 28

(5 rows affected)

Uma ligeira variação nesta “query” fornece apenas as transações que estão atualmente abertas:


SELECT TOP 5
xactid,
count(*) as “records_in_xact”,
FROM syslogs
GROUP BY xactid
HAVING
xactid NOT IN ( SELECT xactid FROM syslogs
WHERE op = 17 /checkpoint is atomic, no commit/
OR op = 30 /*commit tran */
)
ORDER BY count(*)

Você pode usar os valores do identificar da sessão (página, linha) no comando “dbcc log” para identificar o registro de log “BEGINXACT” para a transação e desta forma obter dados como “uid” do usuário, o número da conexão “spid”, o nome da transação e quando ela foi inicializada.


dbcc log(dbid, 1, <session page>, <session row>, 1,0)

LOG SCAN DEFINITION:

Database id : 2

Forward scan: starting at beginning of log

Log records for session id 935,21,0

Log operation type BEGINXACT (0)

maximum of 1 log records.

LOG RECORDS:

BEGINXACT (935,21) sessionid=935,21,0

attcnt=1 rno=21 op=0 padlen=1 sessionid=935,21,0 len=76

odc_stat=0x0000 (0x0000)

loh_status: 0x0 (0x00000000)

masterxsid=(invalid sessionid)

xstat=XBEG_ENDXACT,

spid=19 suid=1 uid=1 masterdbid=0 dtmcord=0

name=$user_transaction time=Nov 16 2010 10:42:19:910AM

Total number of log records 1

DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.

OBS: É possível gerar o comando “DBCC” executando o seguinte “script”

“dbcc log( “

+ db_name()

+ “,1, “

+ str(convert(int,xactid),10,0)

+ “, “

+ str(convert(smallint, substring(xactid,5,2)),10,0)

+ “, 1, 0)” as “dbcc command”

4)DBCC LOG

O comando “dbcc log” pode fornecer muito mais informação, como por exemplo:

Dado um “spid” você pode obter o registro do log “BEGINXACT” (e desta forma o identificar da sessão) para cada transação que esse “spid” iniciou.


set switch on 3604 — sends dbcc output to client

go

dbcc log(<dbid>, -<spid>, -3,0)

go

Para obter o registro de log “BEGINXACT” para todos os “spids” pode-se executar:


dbcc log(<dbid>, 0, 0,0, <records>,0)

Fornecendo um número positivo para “<records>” irá retornar todos os “BEGINXACT” mais antigos, fornecendo um número negativo para “<records>” irá retornar os mais recentes.

Para cada um desses identificadores de sessão, você pode gerar todos os registros de log para essa sessão com:

dbcc log(<dbid>, 1, <session page>, <session row>)

Salve a saída do comando em um arquivo e use alguma das seguintes ferramentas: “grep/awk/perl” para extrair o valor do campo “len” para cada registro de log e some-os. O resultado irá ser a quantidade total de espaço de log nos discos (“devices”) diretamente usados pelos registros de log para o “spid” indicado no comando. Esse processo não leva em conta qualquer compartilhamento de espaços não usados nas páginas do log que armazenam esses registros.

Observação: Artigo original criado por Bret Halford

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply