PostgreSQL 체크 포인트는 어떻게됩니까?


22

여기 내 체크 포인트 로그의 일부가 있습니다 :

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

때로는 데이터베이스가 매우 느리다는 것을 알았습니다. 일반적으로 매우 짧은 수의 짧은 쿼리가 지금보다 훨씬 오래 걸린다는 것을 알 수 있습니다. 명확한 범인없이 정기적으로 발생합니다.

질문 : 검사 점이이 문제를 일으킬 수 있습니까? 체크 포인트의 "동기화"단계에서는 어떻게됩니까?

답변:


32

작업 중에 PostgreSQL은 변경 사항을 트랜잭션 로그 파일에 기록하지만 실제 데이터베이스 테이블로 즉시 플러시하지는 않습니다. RAM이 가득 차서 쓰기를하지 않는 한 일반적으로 메모리의 변경 사항을 유지하고 요청이있을 때 메모리에서 변경 사항을 반환합니다.

이는 충돌이 발생하면 온 디스크 테이블이 최신 상태가 아님을 의미합니다. 백업을 시작하기 전에 디스크상의 테이블에 변경 사항을 적용하여 트랜잭션 로그를 재생해야합니다. 크고 바쁜 데이터베이스에는 시간이 걸릴 수 있습니다.

이러한 이유로 트랜잭션 로그가 계속 커지지 않도록 PostgreSQL은 주기적으로 DB가 깨끗한 상태인지 확인하는 체크 포인트를 수행합니다. 디스크의 모든 보류중인 변경 사항을 비우고 변경 사항의 응급 복구 레코드를 유지하는 데 사용 된 트랜잭션 로그를 재활용합니다.

이 플러시는 두 단계로 발생합니다.

  • 테이블 write()에 더러워진 버퍼 shared_buffers; 과
  • fsync() 변경 사항이 실제로 디스크에 적용되도록 영향을받는 파일

둘 다 디스크 I / O로드를 증가시킬 수 있습니다. 이러한 쓰기로 인한 경합으로 인해 읽기 속도가 느려지고 트랜잭션 커밋에 필요한 WAL 세그먼트의 플러시 속도가 느려질 수 있습니다.

오랜 도전 이었지만 RAM이 더 많은 시스템을 볼수록 더 많은 데이터를 버퍼링하고 기록하는 데 시간이 더 오래 걸리므로 점점 더 나 빠지고 있습니다. 이 LWN.net 기사에서 논의한 바와 같이 현재이를 처리하는 방법에 대해 Linux와 PostgreSQL 커뮤니티간에 토론이 있습니다. (LWN.net은 사람들이 구독하지 않으면 이런 종류의 훌륭한 작품을 계속 쓸 수 없습니다. 유용하고 유익한 정보이므로 구독자이며이 링크를 공유하고 있습니다. 자세한 내용을 보려면 구독을 고려하십시오. 말하자면.)

현재 체크 포인트의 영향을 줄이기 위해 할 수있는 가장 중요한 일은 checkpoint_completion_target최종 체크 포인트가 도착할 때까지 더 많은 데이터가 기록되도록 체크 포인트 활동을 늘리는 것입니다. 페이지 비용을 10 번 업데이트하면 충돌 안전성을 위해 한 번만 작성해야하더라도 완료 대상이 높은 체크 포인트 전에 디스크에 여러 번 기록 될 수 있습니다. 완료 목표가 높을수록 I / O 패턴은 더 매끄럽지 만 전체적인 I / O 오버 헤드는 더 커집니다.

도움을 줄 수있는 다른 방법은 운영 체제에 버퍼링 된 쓰기가 수신되면 즉시 데이터 쓰기를 시작하도록 지시하는 것입니다. 이것은 커널 설정 checkpoint_completion_target과 유사하며 유사한 절충안을 가지고 있습니다. 참조 리눅스 VM 문서를 특히, dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.


쓰기가 오랜 시간에 걸쳐 퍼져서 문제가 발생하지 않는다고 생각합니다. 동기화는 어떻습니까?
Konrad Garus

@KonradGarus 동기화 전 세계적으로 일종의 작동이 되어서는 안되지만 , 어쨌든 종종 발생합니다. 위에 링크 된 기사를 읽으십시오. 비록 상당히 기술적 관점에서도 문제에 대한 매우시의 적절하고 유용한 요약입니다. 짧은 버전은 "Linux에서 fsync ()는 fsync ()와 동시에 모든 I / O의 성능을 완전히 버리는 경향이 있습니다"입니다. fsync로 플러시해야하는 양을 줄이기 위해 위에 나열된 튜닝 옵션을 사용하여이를 완화 할 수 있습니다.
Craig Ringer

1

초과로 인한 오염 OS 파일 시스템 버퍼 플러시 dirty_bytes또는 dirty_ratio 되는 전경 작동 차단!

커널 튜너 블 dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratiodirty_centisecs제어 디스크에 더러운 OS 파일 시스템 버퍼의 플러싱. dirty_bytes바이트 단위 dirty_ratio의 임계 값이고, 총 메모리의 비율 인 임계 값입니다. dirty_background_bytesdirty_background_ratio유사한 한계가 있지만, 홍조는 백그라운드에서 수행하고 완료 될 때까지 다른 읽기 / 쓰기 작업을 차단하지 않습니다. dirty_centisecs플러시가 시작되기 전에 몇 센티 초가 지나갈 수 있는지입니다.

최신 머신의 메모리 크기가 크게 증가함에 따라 Linux에서 이러한 튜너 블의 기본값이 낮아졌습니다. 5 및 10 %에도 비율 dirty_background_ratiodirty_ratio2백56기가바이트 머신은 I / O 시스템을 홍수 수 있습니다.

백그라운드에서 더티 버퍼 플러시를 조정 dirty_background_bytes하거나 dirty_background_ratio시작하기는 까다 롭습니다. 다행히도 PostgreSQL 또는 호스트를 중지하지 않고도 해당 파일에 새 값을 에코하여 이러한 설정을 조정할 수 있습니다.

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

예를 들어, 더티 바이트 수를 설정하여 백그라운드 플러시를 트리거합니다. 당신은 배터리 백업, 커패시터 백업, 또는 플래시 메모리 RAID 카드 (당신이 사용하는 경우 않는 당신이 충돌의 경우에 대비하여 데이터를 유지하지 싶어?) 조정에 의해 시작 dirty_background_bytes1/2 쓰기 캐시 버퍼 크기를 그리고 dirty_bytes그 크기의 3/4까지. iostats를 사용하여 I / O 프로필을 모니터링하고 여전히 지연 시간 문제가 발생하면 데이터베이스 쓰기로드가 여전히 파일 버퍼 캐시 플러시를 압도하고 있음을 의미합니다. 대기 시간이 향상 될 때까지 값을 낮추거나 I / O 하위 시스템 업그레이드를 고려하십시오. FusionIO 카드 및 SSD는 극단적 인 I / O 처리량을위한 두 가지 가능성입니다.

행운을 빕니다!


"더러운"데이터에 대한 귀하의 의견은 속도 저하와 관련이 있습니다. 기본적으로 더티 비율이 클수록 플러시가 시작되기 전에 더티 데이터에 더 많은 버퍼가 할당됩니다. 따라서 플러시 지연을 최소화하면 더티 버퍼가 증가하거나 더티 데이터가 메모리에 남아있을 수있는 시간이 늘어납니다.
피터 테오
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.