PostgreSQL.Transação de preparação lenta e commit preparado
-
13-12-2019 - |
Pergunta
Acabei de encontrar um problema estranho.Fiz um relatório no pgfourine e descobri que minhas transações XA começaram a funcionar muito devagar.Preparar transação e commit preparado combinados levaram 12,55s de 13,2s.Mas por que?
##### Overall statistics #####
Number of unique normalized queries: 175
Number of queries: 268,772
Total query duration: 13m2s
##### Queries by type #####
SELECT: 116493 43.3%
INSERT: 15926 5.9%
UPDATE: 7935 3.0%
DELETE: 4923 1.8%
##### Queries that took up the most time (N) #####
1) 6m32s - 26,338 - COMMIT PREPARED ''
--
2) 6m23s - 25,972 - PREPARE TRANSACTION ''
--
3) 0.6s - 3,848 - update avatar set lfa_position=NULL where Id=0
.....
7) 0.3s - 21,514 - COMMIT
.....
Tenho uma teoria mas não tenho provas..Tenho discos lentos e desliguei o synchronous_commit.Talvez o PostgreSQL precise fazer um fsync durante a "preparação da transação", mesmo que o synchronous_commit esteja desativado?
fsync = on
synchronous_commit = off
Alguma ideia?
ATUALIZAR
Os mesmos testes com
fsync = off
synchronous_commit = off
##### Overall statistics #####
Number of unique normalized queries: 155
Number of queries: 186,838
Total query duration: 6.6s
##### Queries by type #####
SELECT: 84367 45.2%
INSERT: 9197 4.9%
UPDATE: 5486 2.9%
DELETE: 2996 1.6%
##### Queries that took up the most time (N) #####
1) 1.8s - 16,972 - PREPARE TRANSACTION ''
--
2) 1.1s - 16,965 - COMMIT PREPARED ''
--
3) 0.4s - 2,904 - update avatar set lfa_position=NULL where Id=0
--
4) 0.2s - 16,031 - COMMIT
Parece que o fsync demorou muito, mas não o tempo todo.16k commits - 0,2seg, 17k prepare+commit 2,9seg.
Triste história.Parece que o commit XA leva 15 vezes mais tempo que o commit local e não leva em consideração a configuração synchronous_commit.fsync=off não é seguro para uso em produção.Portanto, se eu quiser usar transações XA, tenho que usá-las com cuidado e usar um bom drive SSD com alto IOPS.
Solução
A teoria que PREPARE TRANSACTION
é imediatamente sincronizado está correto e é mencionado no documento:
Trecho de http://www.postgresql.org/docs/9.1/static/wal-async-commit.html :
Os comandos que suportam confirmação de duas fases, como PREPARE TRANSACTION, também são sempre síncronos.