다른 프로세스에서 첨부한 파일을 안전하게 읽을 수 있나요?

다른 프로세스에서 첨부한 파일을 안전하게 읽을 수 있나요?

프로세스 A가 파일을 loc의 일부 위치에 복사하고 프로세스 B가 주기적으로 loc에서 다른 위치로 파일을 복사하는 경우 B는 현재 A가 loc로 복사 중인 파일을 읽을 수 있습니까?

이것이 중요한 경우 Ubuntu Linux 12.04를 사용하고 있습니다.


배경 정보: PostgreSQL 클러스터를 지속적으로 백업하고 싶습니다. PostgreSQL은 이러한 목적으로 WAL 아카이브를 제공합니다. 데이터베이스가 전체 WAL 파일을 백업 위치에 복사하는 스크립트를 호출하도록 하여 작동합니다.

백업된 WAL 파일을 주기적으로 다른 서버에 복사하는 다른 프로세스를 원합니다. 데이터베이스가 현재 WAL 파일을 복사하고 있는 경우 전체 파일이 복사되기 전에 두 번째 프로세스가 일부 EOF 조건을 만나지 않고 계속 파일을 읽을 수 있습니까?

즉, A와 B를 동기화하지 않고 다음을 수행할 수 있습니까?

A                                   B
cp pg_xlog/some_wal_file /backup/   scp /backup/* user@remote-machine:/backups/

답변1

이 경우 유일한 보장은 B가 파일이나 파일의 접두사를 복사하지 않는다는 것입니다. B는 파일이 작성되고 있다는 것을 알 수 없으므로 파일의 (현재) 끝까지 읽은 다음 중지합니다.

이 함정을 피하는 일반적인 방법은 파일을 임시 이름으로 복사한 다음 이름을 바꾸는 것입니다.

dest=$(TMPDIR=/backup mktemp)
trap 'rm -f "$dest"' INT HUP ERR
cp -p pg_xlog/some_wal_file "$dest"
mv "$dest" "/backup/some_wal_file"

소비자에서 임시 파일이 복사되지 않도록 준비합니다. 귀하의 시나리오에서는 dest=$(TMPDIR=/backup mktemp .XXXXXXXXXX)위의 방법을 사용하여 도트 파일로 만들어 이를 달성할 수 있습니다 . 더 간단한 접근 방식은 기본적으로 이 전략을 사용하는 rsync대신 cp을 호출하는 것입니다.rsync

rsync -a pg_xlog/some_wal_file /backup/

B단계에서는 다음과 같은 임시 파일을 제외해야 합니다.

rsync -a --exclude='/.*' /backup/ user@remote-machine:/backups/

도트 파일에 의존하고 싶지 않다면 스테이징 디렉터리를 사용할 수 있습니다. 두 디렉터리가 동일한 파일 시스템에 있는 한 한 디렉터리에서 다른 디렉터리로 파일을 이동하는 것은 원자성입니다.

mkdir -p /backup/incoming
cp -p pg_xlog/some_wal_file /backup/incoming/
mv /backup/incoming/some_wal_file /backup/
rsync -a --exclude=/staging  /backup/ user@remote-machine:/backups/

답변2

내 생각에 가장 좋은 방법은 프로세스 B가 프로세스 A가 완전히 전송한 파일만 복사하도록 하는 것입니다. 이를 달성하는 한 가지 방법은 프로세스 A 에서 cp및 의 조합을 사용하는 것입니다. 이는 해당 프로세스가 시스템 호출을 사용하기 mv때문에 원자적입니다 (파일이 동일한 파일 시스템에 있는 경우). 이는 프로세스 B의 관점에서 볼 때 파일이 완전히 형성된 것으로 나타남을 의미합니다.mvrename

이를 수행하는 한 가지 방법은 프로세스 B partial에서 무시되는 디렉터리에 디렉터리를 만드는 것 입니다. /backup프로세스 A의 경우 다음을 수행할 수 있습니다.

file="some_wal_file"
cp pg_xlog/"$file" /backup/partial
mv /backup/partial/"$file" /backup

프로세스 B의 경우( 사용 bash):

shopt -s extglob
scp /backup/!(partial) user@remote-machine:/backups/

rsync프로세스 A와 프로세스 B가 수행하는 작업 을 조사하고 싶을 수도 있지만 rsync부분 파일은 기본적으로 생성되고 자동으로 해당 위치로 이동됩니다(부분 파일은 일반적으로 특정 디렉터리에 위치하지 않고 숨겨진 파일임). Rsync는 또한 불필요한 파일 전송을 방지하고 네트워크를 통해 업데이트해야 하는 파일의 관련 부분만 전송하기 위한 특수 델타 알고리즘을 갖추고 있습니다( 전송은 기본적으로 계속 발생 rsync하지만 두 위치 모두에 설치해야 함 ). 프로세스 A ssh의 경우 rsync:

rsync -a --partial-dir=/backup/partial pg_xlog/some_wal_file /backup/

프로세스 B의 경우:

rsync -a --exclude=/partial/ /backup/ user@remote-machine:/backups/

관련 정보