Documentação do PostgreSQL 7.4.1 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 25. Registro prévio da escrita (WAL) | Fim | Próxima |
Existem diversos parâmetros de configuração relacionados com o WAL que afetam o desempenho do banco de dados. Esta seção explica como defini-los. Para obter detalhes gerais sobre como definir parâmetros de configuração para o servidor deve ser consultada a Seção 16.4 .
Os pontos de controle (checkpoints) são pontos na seqüência de transações onde se garante que os arquivos de dados foram atualizados com todas as informações registradas antes deste ponto. No momento do ponto de controle, todas as páginas de dados sujas (dirty) são descarregadas no disco, e é escrito um registro especial de ponto de controle no arquivo de segmento do WAL. Como resultado, no caso de uma queda o procedimento de recuperação sabe a partir de qual ponto do WAL (chamado de registro de refazer (REDO)) deve começar a operação de refazer, uma vez que todas as mudanças feitas nos arquivos de dados anteriores a este ponto já se encontram gravadas em disco. Após ter sido feito o ponto de controle, não são mais necessários nenhum dos segmentos do WAL escritos antes do registro de refazer, podendo ser reciclados ou removidos (Quando é implementado o BAR baseado no WAL, devem ser feitas cópias dos segmentos do WAL antes destes serem reciclados ou removidos).
Periodicamente o servidor lança um processo especial para realizar o próximo ponto de controle. Um ponto de controle é realizado a cada checkpoint_segments segmentos do WAL, ou a cada checkpoint_timeout segundos, o que ocorrer primeiro. As definições padrão são 3 segmentos e 300 segundos, respectivamente. Também é possível obrigar a realização de um ponto de controle utilizando o comando SQL CHECKPOINT .
Reduzir checkpoint_segments e/ou checkpoint_timeout faz os pontos de controle serem feitos com maior freqüência, permitindo uma recuperação mais rápida após a queda (uma vez que haverá menos trabalho para ser refeito). Entretanto, deve haver um balanço entre isto e o aumento de custo causado pela descarga das páginas sujas com maior freqüência. Além disso, após cada ponto de controle, para garantir a consistência das páginas de dados, a primeira modificação feita em uma página de dados ocasiona o registro de todo o conteúdo desta página. Por isso, um intervalo de ponto de controle menor aumenta o volume de saída para o WAL, negando parcialmente o objetivo de utilizar um intervalo menor e, em qualquer caso, causando mais E/S em disco.
Há pelo menos um arquivo de segmento e, normalmente, não mais de 2 * checkpoint_segments + 1 arquivos de segmento do WAL. Usualmente cada arquivo de segmento possui o tamanho de 16 MB (embora este tamanho possa ser alterado na construção do servidor). Isto pode ser utilizado para estimar a necessidade de espaço do WAL. Geralmente quando os arquivos de segmento do WAL antigos não são mais necessários, estes são reciclados (os nome são mudados para se tornarem os próximos segmentos da seqüência numerada). Se, por causa de um pico de pouca duração da taxa de saída para o WAL, existirem mais de 2 * checkpoint_segments + 1 arquivos de segmento, os arquivos de segmento desnecessários serão removidos em vez de reciclados até o sistema voltar a ficar abaixo deste limite.
Existem duas funções do WAL utilizadas com freqüência: LogInsert
e LogFlush
. A função LogInsert
é utilizada para colocar um novo registro nos buffers do WAL na memória compartilhada. Se não houver espaço para o novo registro, LogInsert
terá que escrever (mover para o cache do núcleo) uns poucos buffers do WAL cheios. Isto não é desejado, porque LogInsert
é utilizada em todas as modificações de baixo nível do banco de dados (por exemplo, inserção de linha), quando um bloqueio exclusivo é mantido nas páginas de dados afetadas, portanto esta operação precisa ser tão rápida quanto for possível. O que é pior, escrever os buffers do WAL também pode obrigar a criação de um novo arquivo de segmento, que toma mais tempo ainda. Normalmente, os buffers do WAL devem ser escritos e descarregados pela chamada LogFlush
que é feita, na maioria das vezes, na hora da efetivação da transação para garantir que os registros da transação sejam descarregados no armazenamento permanente. Nos sistemas com saída para o WAL alta, as chamadas à LogFlush
podem não ocorrer com uma freqüência suficiente para evitar que LogInsert
tenha que realizar escritas. Nestes sistemas, deve ser aumentado o número de buffers do WAL pela modificação do parâmetro wal_buffers. O número padrão de buffers do WAL é 8. O aumento deste valor aumenta de forma correspondente a utilização de memória compartilhada (Deve ser observado que no momento existe pouca evidência sugerindo que aumentar wal_buffers acima do padrão valha a pena).
Os pontos de controle são muito dispendiosos, porque forçam todos os buffers do núcleo modificados serem enviados para o disco utilizando a chamada do sistema operacional sync(). Servidores ocupados podem encher os arquivos de segmento do WAL muito rapidamente, produzindo um número excessivo de pontos de controle. Se tais pontos de controle forçados acontecerem com freqüência maior do que checkpoint_warning segundos, uma mensagem será enviada para o log do servidor recomendando aumentar checkpoint_segments.
O parâmetro commit_delay define a quantidade de microssegundos que o processo servidor vai aguardar após escrever um registro de efetivação no WAL com LogInsert
, antes de realizar o LogFlush
. Este retardo permite que outros processos servidor adicionem seus registros de efetivação ao WAL, para que todos sejam descarregados em uma única sincronização do WAL. Não ocorre nenhum retardo quando fsync não está habilitado, nem se menos de outras commit_siblings sessões estiverem com transações ativas no momento; isto evita o retardo quando é pouco provável que outras seções efetivem em breve. Deve ser observado que na maioria das plataformas a resolução de uma solicitação de retardo é de dez milissegundos, portanto qualquer definição de commit_delay diferente de zero e entre 1 e 10000 microssegundos produz o mesmo efeito. Ainda não está claro quais são os melhores valores para estes parâmetros; incentiva-se que sejam feitas experiências.
O parâmetro wal_sync_method determina como o PostgreSQL vai fazer a solicitação ao núcleo para forçar o envio das atualizações do WAL para o disco. Todas as opções devem ser idênticas em termos de confiabilidade, mas é bem específico da plataforma qual delas é a mais rápida. Deve ser observado que este parâmetro é irrelevante se fsync estiver desabilitado.
Definir o parâmetro wal_debug com qualquer valor diferente de zero faz com que todas as chamadas a LogInsert
e LogFlush
do WAL sejam registradas no log do servidor. Atualmente não faz diferença qual é este valor diferente de zero. Esta opção poderá ser substituída por um mecanismo mais geral no futuro.