497일 문제

1 개요

일부 구형 32비트 리눅스 시스템에서 발생하는 컴퓨터 버그 중 하나. 리눅스 컴퓨터를 497일 동안 켜 놓으면, 컴퓨터가 이상 상태에 빠지거나 오류를 감지한 운영체제가 오류를 수정하기 위해 자동으로 리부팅이 되어 버리는 현상이다.

리눅스 커널에는 내부 타이머 용도로 jiffies 라는 32비트 변수를 사용하는데, 이 변수는 1/100 초에 1씩 증가하도록 되어 있다. [1] 이 변수는 32비트로 되어 있어서 232-1 = 약 42.9억(4294967295)이 최대값이다. 그런데, 100*60*60*24*497 = 약 42.9억(4294080000)으로, 497일이 경과하면 거의 최대값에 도달하게 된다. 컴퓨터 부팅후 정확히 497일 2시간 27분 52.96초에는 이 jiffies 값이 32비트 한계를 초과하여(4294967296) 오버플로우가 발생하고 0으로 리셋된다. 이로 인해서 시스템이 오동작을 일으킨다.

Unsigned 가 아닌 signed 변수를 사용하는 경우에는 231 = 약 21.4억 이기 때문에 497일의 절반인 248.5일만에 문제가 생긴다. 비행기를 248일마다 재부팅해라란 기사도 있는데, 정확한 내용은 알 수 없지만 497일 문제와 관련이 많다. 비행중 재부팅되면 기분이 참 싸아할거다(...).

개인용 컴퓨터 사용자가 컴퓨터를 1년이 넘게 끄지 않는 일은 거의 없으므로 일반 사용자의 경우는 문제가 발생할 일이 거의 없다. 하지만 서버의 경우는 1년 내내, 혹은 그 이상의 기간 동안 끄지 않고 유지하는 경우도 많기 때문에 심각한 문제가 발생할 수 있다. 당장 은행서버가 오버플로우되어 당신의 통장잔고가 0원이 되어버린다고 생각해보자. 이 얼마나 끔찍하고 무시무시한 일인가. 하지만 통장잔고가 마이너스라면?? 다행히도 이런 서버들은 정기 백업과 정기적인 유지보수로 1년에도 몇번씩 리부팅을 하니 걱정할 필요가 없다.

변수의 오버플로우로 인하여 발생한다는 점에서 2038년 문제와 상당히 유사점이 많다.

일부 구형 윈도우 시스템에도 비슷한 버그가 있었다. 단 이쪽은 1/1000초에 1씩 증가하도록 되어 있어 약 49일만에 문제가 발생한다.

TCP/IP 프로토콜 내에서도 유사한 문제가 존재하며, 이는 윈도우 시스템에도 유사한 영향을 준다.

Windows XP에서도 유사한 버그가 있다.이쪽은 전원선까지 뽑고 몇일 있다가 다시 꼽고 키면 시간이 2003년으로 이동되어있다. Windows 7도 이 버그을 먹힌다.

2 해결책

  • 주기적으로 컴퓨터를 재시작한다.
실제로 이 이유뿐만 아니라 여러 이유로 최소 1년에 한 번씩 서버를 껐다가 켠다. 보통 한두달에 한번 정도 점검 및 리부팅을 하는 것이 보통이다.
그러니까 게임 레벨 초기화되고 싶지 않으면 서버 점검한다고 불평하지 말자[2]
  • 최신 커널로 업데이트한다.
최신 커널은 64비트 변수인 jiffies64를 쓰도록 수정되었다. 64비트 시스템에서 이 에러가 발생하려면 약 58억 4942만년[3]동안 리부팅없이 컴퓨터를 돌려야 한다. 컴퓨터가 먼저 망가진다

3 관련 문제

  1. CONFIG_HZ 라는 상수를 수정하여 변경 가능한데, 더 큰값으로 변경하여 쓰기도 한다. 예를 들어 1000 으로 하면, 타이머가 1/1000초 단위로 동작하기에, 좀더 세밀한 타이머 조정이 가능하다. 하지만 이 경우에는 약 49일+17시간만에 문제가 생긴다.
  2. 사실 게임 서버는 연산량도 무지막지하고 쌓이는 데이터도 많은데다 돌아가는 서버 프로그램도 대단히 복잡하기 때문에 주기적으로 관리를 해야 된다. 497일동안 리부팅없이 켜 둘 가능성이 거의 없는 편이다.
  3. 변수가 1초에 100씩 증가하니 2^64번 증가하는데 걸리는 시간. 이 정도의 시간이 경과하면 현재의 태양은 수명이 거의 다해 적색 거성으로 부풀어오르는 단계에 있게 된다.