File 을 읽고 쓸 때 `.tmp` 파일은 왜 필요할까

2026. 7. 1. 23:23·LINUX/Linux

요구사항

애플리케이션에서 어떤 파일을 쓰고, 읽을 수 있어야한다.
파일은 반드시 완결된 내용을 갖춰야한다.

즉, "쓰는 중" 과 같은 상태는 허용하지 않는다.

구현 방법

/data/
 |--- data.snapshot
 |--- data.snapshot.tmp
  1. data.snapshot.tmp 파일에 데이터를 쓴다.
  2. data.snapshot.tmp 파일 쓰기를 완료한다.
  3. data.snapshot.tmp 파일을 data.snapshot 파일로 이름을 변경한다.
  4. data.snapshot 파일이 있는 경우, 덮어쓰기한다.

이런 순서로 구현할 수 있다.

.tmp 는 왜 필요할까?
.tmp 파일 이름은 temporary 임시파일로부터 왔다.
그럼 '임시' 파일이란게 왜 필요한지를 생각해보자.

파일의 완결성과 가시성

파일에 데이터를 '쓰는 중'이라면 어떻게될까?

문자열 "a b c d e" 를 3차례 걸쳐서 써보자

a b
a b c
a b c d e

문자열 "a b c d e" 를 모두 쓰고 나서는 반드시 파일을 저장해야한다.

저장된 파일을 열면 다음과 같이 써있을 것이다.

a b c d e

근데, a b c 까지만 쓴 상황에서 누군가 파일을 열었다고 가정해보자

a b c

이런 상태를 허용해선 안된다.
요구사항에서 파일은 완결된 상태를 가져야 한다고 했다.
여기서 완결이란, "모든 데이터가 파일에 쓰고 저장한 상태" 를 의미한다.

.tmp 파일이 필요한 이유

파일을 읽는 프로세스는 파일명 data.snapshot 를 읽는다.
파일을 읽는 프로세스에서는 이 파일이 쓰다만 파일인지, 완결된 파일인지 모른다. 그저 읽을 뿐이다.

읽기 프로세스는 .tmp 파일에 대한 visibility (가시성) 이 없는 상태다.

data.snapshot -> 완결된 상태만 허용
data.snapshot.tmp -> 쓰는 '중' 인 상태 허용

읽기 프로세스는 data.snapshot.tmp 파일에 접근하지 않는다.

대신 쓰기 프로세스가 data.snapshot.tmp 파일에 다음과 같이 쓸 수 있다.

a b
a b c
a b c d e

data.snapshot.tmp 파일에 a b c d e 를 모두 입력 완료하여 파일을 저장했다.

이제 간단하다.
data.snapshot.tmp 파일을 data.snapshot 파일로 덮어쓰면 끝이다.
기존 data.snapshot.tmp 파일은 제거하면 된다.

이런 식으로, 일부만 써진 상태 (Write In Process) 를 없애 완결된 파일만 쓰고, 읽을 수 있도록 제한할 수 있다.

실전 코드

위에서 설명한 방식을 Kotlin 코드로 작성해보자.

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption

class FileManager {
  fun saveSnapshot() {
    Files.createDirectories(baseDir)

    val tmp = baseDir.resolve(SNAPSHOT_TMP)
    val target = baseDir.resolve(SNAPSHOT)

    DataOutputStream(BufferedOutputStream(
      Files.newOutputStream(tmp),
      BUFFER_SIZE)
    ).use { out ->
      out.write() // ..
      }
    }

    // Atomic rename within the same dir: a reader sees either the old snapshot or the complete new one.
    // No fsync — the snapshot is a startup optimization, rebuildable from the Kafka dedup-store topic.
    Files.move(
      tmp,
      target,
      StandardCopyOption.ATOMIC_MOVE,
      StandardCopyOption.REPLACE_EXISTING
    )
  }

  companion object {
    const val SNAPSHOT = "data.snapshot"
    const val SNAPSHOT_TMP = "data.snapshot.tmp"
  }
}

위 함수는 data.snapshot.tmp 파일에서 data.snapshot 파일로 bytes 를 복사하지 않는다.
파일명 변경 명령어 (rename)는 메타데이터 명령어로, 기존에 data.snapshot 파일의 inode/data 를 원자적으로 새로운 data.snapshot 파일을 가리키도록 변경한다.
Windows, Linux 등의 운영체제는 rename 명령어를 Atomic 하게 설계해놓았다.

이렇게하면 아래 2가지 상황만 가능하다.

  1. 덮어쓰기 전에 파일 읽기 -> 이전 버전의 data.snapshot 파일 읽기
  2. 덮어쓰기 후 파일 읽기 -> 새로운 버전의 data.snapshot 파일 읽기

어느쪽이든 완결된 파일을 읽는다.
Atomic 한 연산으로 써지기 때문에 "일부만 써진" 파일이 존재할 수 있는 시간이 아예 없다.

저작자표시 (새창열림)

'LINUX > Linux' 카테고리의 다른 글

[Linux] 중복 파일 제거 솔루션 'fdupes'  (0) 2024.04.28
[Linux] ufw 방화벽 설정  (0) 2021.12.20
[Linux] AppImage 파일  (0) 2021.12.02
[Linux] node.js 최신버전 설치  (0) 2021.05.20
rpm package with command  (0) 2020.11.10
'LINUX/Linux' 카테고리의 다른 글
  • [Linux] 중복 파일 제거 솔루션 'fdupes'
  • [Linux] ufw 방화벽 설정
  • [Linux] AppImage 파일
  • [Linux] node.js 최신버전 설치
M_Falcon
M_Falcon
  • M_Falcon
    Falcon
    M_Falcon
  • 전체
    오늘
    어제
    • 분류 전체보기 (434) N
      • Web (16)
        • Nodejs (14)
        • Javascript (23)
        • FrontEnd (4)
      • DataBase (39)
        • Fundamental (1)
        • Redis (4)
        • PostgreSQL (10)
        • NoSQL (4)
        • MySQL (9)
        • MSSQL (3)
        • Error (4)
      • Algorithm (79)
        • Algorithm (문제풀이) (56)
        • Algorithm (이론) (23)
      • JVM (65)
        • Spring (13)
        • JPA (5)
        • Kotlin (13)
        • Java (24)
        • Error (7)
      • 기타 (71)
        • Kafka (3)
        • Kubernetes (3)
        • Docker (14)
        • git (19)
        • 잡동사니 (27)
      • 재테크 (11)
        • 세무 (4)
        • 투자 (3)
        • 보험 (0)
      • BlockChain (2)
        • BitCoin (0)
      • C (32)
        • C (10)
        • C++ (17)
        • Error (3)
      • Low Level (8)
        • OS (3)
        • 시스템 보안 (5)
      • 네트워크 (3)
      • LINUX (31) N
        • Linux (27) N
        • Error (4)
      • 저작권과 스마트폰의 이해 (0)
      • 생각 뭉치 (6)
      • 궁금증 (2)
      • Private (4)
        • 이직 경험 (0)
        • 꿈을 찾아서 (1)
      • Android (21)
        • OS (4)
  • 블로그 메뉴

    • 홈
    • WEB
    • 알고리즘
    • DataBase
    • Linux
    • Mobile
    • C
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    java
    android
    Programmers
    linux
    javascript
    PostgreSQL
    프로그래머스
    백준
    Bitcoin
    알고리즘
    docker
    ubuntu
    Spring
    kafka
    Kotlin
    Git
    algorithm
    database
    C++
    JPA
  • hELLO· Designed By정상우.v4.10.3
M_Falcon
File 을 읽고 쓸 때 `.tmp` 파일은 왜 필요할까
상단으로

티스토리툴바