usando o PostgreSQL 9.1.2
Estou vendo uso excessivo da CPU e grandes quantidades de gravações no disco a partir de tarefas do postmaster. Isso acontece mesmo enquanto meu aplicativo não faz quase nada (10s de inserções por MINUTE). No entanto, há um número razoável de conexões abertas.
Eu tenho tentado determinar o que no meu aplicativo está causando isso. Sou bem novato no postgresql e ainda não cheguei a lugar algum. Ativei algumas opções de log no meu arquivo de configuração e observei as conexões na tabela pg_stat_activity, mas todas estão ociosas. No entanto, cada conexão consome ~ 50% da CPU e grava ~ 15M / s no disco (não está lendo nada).
Basicamente, estou usando o postgresql.conf com muito poucos ajustes. Agradeço qualquer conselho ou dicas sobre o que posso fazer para rastrear isso.
Aqui está uma amostra do que top / iotop está me mostrando:
Cpu(s): 18.9%us, 14.4%sy, 0.0%ni, 53.4%id, 11.8%wa, 0.0%hi, 1.5%si, 0.0%st
Mem: 32865916k total, 7263720k used, 25602196k free, 575608k buffers
Swap: 16777208k total, 0k used, 16777208k free, 4464212k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17057 postgres 20 0 236m 33m 13m R 45.0 0.1 73:48.78 postmaster
17188 postgres 20 0 219m 15m 11m R 42.3 0.0 61:45.57 postmaster
17963 postgres 20 0 219m 16m 11m R 42.3 0.1 27:15.01 postmaster
17084 postgres 20 0 219m 15m 11m S 41.7 0.0 63:13.64 postmaster
17964 postgres 20 0 219m 17m 12m R 41.7 0.1 27:23.28 postmaster
18688 postgres 20 0 219m 15m 11m R 41.3 0.0 63:46.81 postmaster
17088 postgres 20 0 226m 24m 12m R 41.0 0.1 64:39.63 postmaster
24767 postgres 20 0 219m 17m 12m R 41.0 0.1 24:39.24 postmaster
18660 postgres 20 0 219m 14m 9.9m S 40.7 0.0 60:51.52 postmaster
18664 postgres 20 0 218m 15m 11m S 40.7 0.0 61:39.61 postmaster
17962 postgres 20 0 222m 19m 11m S 40.3 0.1 11:48.79 postmaster
18671 postgres 20 0 219m 14m 9m S 39.4 0.0 60:53.21 postmaster
26168 postgres 20 0 219m 15m 10m S 38.4 0.0 59:04.55 postmaster
Total DISK READ: 0.00 B/s | Total DISK WRITE: 195.97 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
17962 be/4 postgres 0.00 B/s 14.83 M/s 0.00 % 0.25 % postgres: aggw aggw [local] idle
17084 be/4 postgres 0.00 B/s 15.53 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17963 be/4 postgres 0.00 B/s 15.00 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17188 be/4 postgres 0.00 B/s 14.80 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17964 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
18664 be/4 postgres 0.00 B/s 15.13 M/s 0.00 % 0.23 % postgres: aggw aggw [local] idle
17088 be/4 postgres 0.00 B/s 14.71 M/s 0.00 % 0.13 % postgres: aggw aggw [local] idle
18688 be/4 postgres 0.00 B/s 14.72 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
24767 be/4 postgres 0.00 B/s 14.93 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18671 be/4 postgres 0.00 B/s 16.14 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
17057 be/4 postgres 0.00 B/s 13.58 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
26168 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18660 be/4 postgres 0.00 B/s 15.85 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
Atualização : Muitas das gravações de arquivos parecem estar em alguns arquivos temporários (?) No diretório $ PG_DATA / base /. Meu entendimento da estrutura do arquivo aqui é que cada tabela é basicamente armazenada como um arquivo cujo nome é o OID da tabela. No entanto, existem vários arquivos nomeados tnn_nnnnnnn
e são esses arquivos que parecem ser gravados (talvez sobrescritos) constantemente. Para que são esses arquivos? Existem ~ 4700 dos arquivos e todos têm 8K de tamanho:
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t12_1430975
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t16_1432736
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439066
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436243
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436210
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t19_1393372
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439051
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t8_1430334
Atualização : A execução do rastreio nos processos do postmaster mostra basicamente muitas coisas de E / S de arquivos:
open("base/16388/t24_1435947_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
ftruncate(9, 0) = 0
lseek(9, 0, SEEK_END) = 0
open("base/16388/t24_1435941", O_RDWR) = 18
lseek(18, 0, SEEK_END) = 0
write(9, "\0\0\0\0\0\0\0\0\1\0\0\0000\0\360\37\360\37\4 \0\0\0\0b1\5\0\2\0\0\0"..., 8192) = 8192
lseek(18, 0, SEEK_END) = 0
close(9) = 0
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
close(18) = 0
close(9) = 0
open("base/16388/t24_1435944_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 0
close(9) = 0
Atualização : Portanto, esse problema parece ter tudo a ver com tabelas temporárias. Alteramos nossa configuração para que as tabelas temporárias sejam tabelas 'regulares', e toda a atividade do disco tenha desaparecido, e o desempenho esteja de volta ao que eu esperava. Agora, essa alteração foi apenas um teste rápido e sujo: se realmente vamos mudar para usar tabelas regulares, temos problemas com simultaneidade e limpeza. As mesas temporárias são realmente tão más ou estamos abusando delas?
Atualização : Um pouco mais de experiência. Estou usando um middleware de replicação baseado em instruções desenvolvido internamente . É bastante maduro e tem sido usado em vários projetos ao longo de vários anos, mas usando o MySQL. Trabalhamos apenas com o PostgreSQL nos últimos dois anos. Basicamente, estávamos usando as tabelas temporárias como parte do mecanismo de replicação. Sempre que uma nova conexão é estabelecida, criamos uma tabela temporária para cada tabela no banco de dados. Com 10 a 20 conexões (de longa duração) e ~ 50 tabelas, isso pode resultar em muitas tabelas temporárias. Todas as tabelas temporárias foram criadas com:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
A semântica das tabelas temporárias se encaixa muito bem com o nosso esquema de replicação e simplificou muito do código que tínhamos que usar no MySQL, mas parece que a implementação não foi boa também. Com base nas pesquisas que fiz, não acho que tabelas temporárias foram realmente destinadas à função para a qual as usamos.
Eu não sou o especialista interno (nem de perto) sobre esse assunto, apenas um usuário, por isso minha explicação pode não ser 100% precisa, mas acho que é bem próxima.
fonte
Respostas:
Sua configuração do PostgreSQL está muito diferente. Isso foi suspeito em sua postagem inicial,
Dos 32 GB no servidor, ~ 25 GB são gratuitos, exceto ~ 575 MB de buffer.
No seu arquivo postgresql.conf,
Estou assumindo que este é um banco de dados dedicado. Nesse caso, altere-o para os seguintes parâmetros e recarregue / reinicie,
Deixe-me saber como isso altera seu desempenho e pode ajustá-lo ainda mais, conforme necessário.
No que diz respeito às tabelas não registradas, se suas tabelas temporárias contiverem dados temporários efêmeros e, como você mencionou, são criados na sessão, é melhor usar tabelas não registradas.
Você pode truncar suas tabelas após a sessão, se isso for aceitável.
Mais informações aqui - http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/
Não sei por que você precisa de tabelas temporárias para replicação. Você não pode usar a replicação de streaming do PostgreSQL?
fonte
Usar tabelas temporárias e ter conexões de longa data (provavelmente o pool de conexões está envolvido) pode ser um fardo se o servidor não estiver preparado para isso. Um parâmetro do PostgreSQL com o
temp_buffers
qual você pode tentar jogar é o que controla a RAM alocada para tabelas temporárias. Esses buffers temporários são alocados por conexão e o valor padrão (8 MB) provavelmente é muito baixo para o seu site.Talvez você também precise alterar um pouco o comportamento do aplicativo cliente, dependendo de como você usa suas tabelas temporárias. Há uma pergunta semelhante com uma boa resposta no Stack Overflow .
fonte
temp_buffers
. Você também pode nos dizer qual é o tamanho do banco de dados que você está tentando replicar? Quantas tabelas, tamanho médio por tabela e tamanho total do banco de dados?Você poderia postar seu arquivo postgresql.conf? Seu postgresql parece estar significativamente otimizado.
Você também pode postar:
Se você estiver usando tabelas não registradas para suas tabelas temporárias?
Quantos discos e em que configuração RAID?
fonte