Monitorando e Ajustando Log Switches – E como eles afetam Performance
O que é Log Switch?
Um “Log Switch” é o momento no qual o Banco de Dados, por qualquer que seja o motivo, interrompe a gravação que estava sendo realizada em um arquivo de REDO, partindo para o próximo REDO LOG disponível. Em condições normais, um Log Switch ocorre basicamente quando um arquivo de REDO foi completamente utilizado.
Quem realiza o Log Switch?
O processo de segundo plano LGWR é o processo responsável por escrever no “online Redo Log” todas as alterações, conhecidas neste caso como “redo entries”.
Qual a Frequência de um Log Switch?
Boa e velha resposta. Depende!
Caso não exista nenhum tratamento especial para controlar esses Switches, o tempo necessário para um Log Switch ocorrer é diretamente proporcional ao tamanho de seu REDO LOG e a quantidade de alterações existentes em sua base de dados. Quanto maior o numero de operações DML, por exemplo, mais frequente serão os switches. Por outro lado, quanto maior for o tamanho físico do arquivo de Redo, mais alterações ele poderá receber, aumentando o tempo necessário para que o switch ocorra.
Evidentemente existem maneiras de forçar um Log Switch, mas esses procedimentos não serão abordados nesse artigo.
Vale ressaltar que quando analisamos a documentação Oracle, a sugestão é para que os Switches ocorram a cada 45-60 minutos.
Como isso afeta a Performance do Oracle?
Bem, esse é o motivo deste artigo.
É muito comum encontrarmos um único Banco de Dados que faz o papel tanto de um sistema OLTP (Online Transaction Processing) quanto de um DW (Data Warehouse). Um exemplo típico são os sistemas ERP. Durante o dia os usuários trabalham normalmente, inserindo informações corporativas na base, sendo que a noite essas informações são processadas, agrupadas e liberadas para visualização em um sistema de BI, por exemplo, para a tomada de decisão dos lideres empresariais.
Esses sistemas OLTP e DW possuem uma arquitetura Oracle totalmente diferente. Cada qual tem seus detalhes e atributos, e são ajustadas especialmente para cada fim. Isso em alguns casos pode gerar conflitos de configurações e parametrizações, afetando diretamente a performance e segurança do Banco.
E onde entram os Logs Switches? Pois bem, segundo a própria Oracle, a ação de Switch deve ocorrer a cada, vamos dizer, 01 hora. Isso porque se tivermos muitos switches, se eles forem muito frequentes, teremos um impacto bastante negativo de performance, seja por stressar o processo LGWR e/ou por acarretar em uma carga de I/O elevadíssima em seu sistema, com escritas em discos constantes e desnecessárias. Dependendo do hardware você terá uma enorme fila de disco. Isso significa = Sistema Lento!
Por outro lado, se tivermos por exemplo um Log Switch a cada 06 horas, teríamos aqui um problema de segurança de informação, pois no caso de perdermos o ONLINE Redo Log seriam nada mais nada menos que 06 horas de trabalho perdidas, pois este LOG ainda não teria sido arquivado. Mesmo que seu Redo Log seja duplicado, falhas em uma controladora por exemplo, podem danificar ambos arquivos.
Então, temos aqui uma questão. Priorizar Performance ou Segurança?
Se você tiver um arquivo pequeno (50MB) mas que comporte as atividades durante o dia, o processamento massivo dos dados durante a noite será prejudicado pelos inúmeros Switches. Se você então criar arquivos maiores (01GB), otimizando o processamento noturno, terá provavelmente 01 ou 02 Logs switches durante o dia, e isso não é nada bom quando pensamos em segurança.
A primeira utilidade deste artigo para administrar essa questão é o select abaixo. Com ele você visualiza quantos Logs Switches ocorreram a cada hora e a cada dia em sua base de dados. Essa informação também pode ser obtida através do arquivo de alerta, mas não em um output tão simples assim:
------------------------
SET LINESIZE 350
SET PAGESIZE 50
select to_char(first_time,'DD-MON-YYYY') DIA,
to_char(sum(decode(to_char(first_time,'HH24'),'00',1,0)),'99') "00",
to_char(sum(decode(to_char(first_time,'HH24'),'01',1,0)),'99') "01",
to_char(sum(decode(to_char(first_time,'HH24'),'02',1,0)),'99') "02",
to_char(sum(decode(to_char(first_time,'HH24'),'03',1,0)),'99') "03",
to_char(sum(decode(to_char(first_time,'HH24'),'04',1,0)),'99') "04",
to_char(sum(decode(to_char(first_time,'HH24'),'05',1,0)),'99') "05",
to_char(sum(decode(to_char(first_time,'HH24'),'06',1,0)),'99') "06",
to_char(sum(decode(to_char(first_time,'HH24'),'07',1,0)),'99') "07",
to_char(sum(decode(to_char(first_time,'HH24'),'08',1,0)),'99') "08",
to_char(sum(decode(to_char(first_time,'HH24'),'09',1,0)),'99') "09",
to_char(sum(decode(to_char(first_time,'HH24'),'10',1,0)),'99') "10",
to_char(sum(decode(to_char(first_time,'HH24'),'11',1,0)),'99') "11",
to_char(sum(decode(to_char(first_time,'HH24'),'12',1,0)),'99') "12",
to_char(sum(decode(to_char(first_time,'HH24'),'13',1,0)),'99') "13",
to_char(sum(decode(to_char(first_time,'HH24'),'14',1,0)),'99') "14",
to_char(sum(decode(to_char(first_time,'HH24'),'15',1,0)),'99') "15",
to_char(sum(decode(to_char(first_time,'HH24'),'16',1,0)),'99') "16",
to_char(sum(decode(to_char(first_time,'HH24'),'17',1,0)),'99') "17",
to_char(sum(decode(to_char(first_time,'HH24'),'18',1,0)),'99') "18",
to_char(sum(decode(to_char(first_time,'HH24'),'19',1,0)),'99') "19",
to_char(sum(decode(to_char(first_time,'HH24'),'20',1,0)),'99') "20",
to_char(sum(decode(to_char(first_time,'HH24'),'21',1,0)),'99') "21",
to_char(sum(decode(to_char(first_time,'HH24'),'22',1,0)),'99') "22",
to_char(sum(decode(to_char(first_time,'HH24'),'23',1,0)),'99') "23"
from v$log_history group by to_char(first_time,'DD-MON-YYYY')
ORDER BY to_char(first_time,'DD-MON-YYYY');
Pois bem, quando comecei a me importar com essa questão o SELECT acima evidenciava que durante a madrugada eu tinha mais de 40, 50 Switches por hora, enquanto de dia eu conseguia seguir a orientação da Oracle. Porem, isso me gerava problemas de performance durante a madrugada e fazia, em dias de fechamento, com que os Jobs Oracle ultrapassassem a janela noturna avançando até o inicio do expediente. Era um verdadeiro caos!
Com o resultado do select em mãos, foi possível concluir que eu precisava de um equilíbrio maior.
A segunda finalidade deste artigo e apresentar como podemos controlar esse cenário. É através do parâmetro ARCHIVE_LAG_TARGET. O parâmetro ARCHIVE_LAG_TARGET basicamente limita a quantidade de dados que podem ser perdidos. Ele é muito utilizado quando temos um standby database. Seu default é 0 e deve ser parametrizado em segundos! 0 – 7200 segundos.
Então vamos lá. Para um dado não ser perdido ele precisa ser arquivado, para ele ser arquivado precisamos de um LOG SWITCH. Bingo!
Podemos então tirar proveito deste parâmetro para resolver esse dilema de Performance x Segurança.
Minha solução foi então criar arquivos de REDO LOG com o tamanho otimizado para DW, que no meu caso, foi 01GB de REDO. Porém, como o default deste parâmetro é 0, ou seja, desabilitado, eu forcei sua parametrização para 3600 segundos, ou seja 01 hora!
Que beleza, agora posso ter Logs Switches a cada 01 hora, independentemente se o arquivo foi totalmente utilizado ou não. Isso me deixa seguro! Também posso fazer com que durante os processamentos noturnos, ainda que envolvam uma massa gigante de dados, os Switches ocorram com menos frequência e atinjam as métricas e boas práticas definidas pela Oracle.
Analisar a frequência dos Logs Switches é muito importante. Em conjunto com a configuração do parâmetro os meus 02 problemas foram resolvidos, tanto a segurança para o trabalho diário dos usuários quanto a performance obtida a noite, quando a instancia assume o papel de DW.
Espero que o artigo seja útil.
Você pode encontrar mais detalhes sobre os assuntos abordados acima nos links a seguir:
- http://docs.oracle.com/cd/B19306_01/server.102/b14237/initparams009.htm
- http://docs.oracle.com/cd/B28359_01/server.111/b28310/onlineredo001.htm#ADMIN11307
- http://docs.oracle.com/cd/B28359_01/server.111/b28310/onlineredo002.htm#ADMIN11317
Obrigado!