컴퓨터 데이터베이스 세상에는 'ACID'라는 원칙이 있습니다. 데이터베이스에 자료를 넣거나 뺄 때 '가급적' 지켜야 할 네 가지 원칙(원자성, 일관성, 독립성, 내구성)인데요. 예를 들어 가면서 알아보겠습니다.
[1. 원자성]
원자는 쪼갤 수 없는 최소 단위죠. 물론 쿼크나 전자가 밝혀지면서 의미가 퇴색한 감이 있지만... 아무튼 원래 의미는 그랬습니다.
한편 데이터베이스에서의 원자성은 한 마디로 요약하면 이렇습니다.
["all or nothing"]
예를 들어 알아보죠. 다음과 같은 계좌 잔고 목록이 있다고 합시다.
[A 잔고: 100, B 잔고: 200]
이때 A가 B에 50만큼의 돈을 송금하려고 합니다. 그러려면 어떻게 해야 할까요?
(1) 우선, A에서 50만큼 뺍니다.
(2) 그리고 B에 50을 더합니다.
무척 간단해 보이지만, 뜻밖의 위험이 도사리고 있습니다. 송금 과정이 한 단계가 아닌
[여러 단계로 이루어진다]는 것입니다.
여러분은 엑셀로 계좌 관리를 하고 있습니다. 위 거래를 수행하기 위해, 우선 엑셀에서 A의 잔고 셀을 클릭해서 100을 50으로 낮췄습니다. 그리고 B의 잔고 셀을 누르려는 순간, 갑자기 동료가 커피나 한 잔 하자고 부릅니다. 즐거운 커피 타임~ 그런데 돌아오니
[자기가 무슨 작업을 하고 있었는지 까먹었습니다.] 저 50이라는 돈은 그대로 잊힌 돈이 됩니다.
이런 일을 방지하려면, 어떤 거래를 수행하려면 여러 단계가 필요할 때, 그 단계들이 전부(all) 수행되거나 아니면 전혀 안(nothing) 수행된다는 것을 보장할 필요가 있습니다. 이것이 '원자성'입니다.
컴퓨터가 일할 때 '커피 타임'을 발생시키는 요인에는 여러 가지가 있습니다. 갑작스러운 정전, 네트워크 오류, 소프트웨어 버그... 물론 99.99%의 상황에서 제대로 동작하지만, 나머지 0.01%의 피해를 방지하기 위해 원자성을 보장해야 하는 것이죠.
위에서는 은행 거래를 예로 들었지만, 인터넷 게시판에도 마찬가지로 적용되는 원리입니다. 댓글 작성을 생각해 보면 다음과 같은 단계들을 생각할 수 있겠죠: (1) 댓글 목록에 현재 댓글 추가 (2) 현재 댓글이 달린 글의 댓글 개수를 1만큼 증가 (3) 현재 댓글이 계층 댓글이라면 상위 댓글에 달린 댓글 개수도 1만큼 증가
[2. 일관성]
데이터베이스에 저장된 데이터는 항상 일관성이 있어야 합니다.
소프트웨어 개발자는 데이터베이스를 이용할 때 몇 가지 규칙을 부여할 수 있습니다. 예를 들어, (1) 어떤 글의 댓글 개수는 항상 0 또는 양수여야 한다. (2) 어떤 댓글의 상위 댓글은 항상 존재해야 한다. (3) 사용자 아이디는 반드시 유일해야 한다.
프로그래머도 사람인지라
자주 가끔 실수를 합니다. 예를 들어, 아이디 중복 확인 기능을 깜빡하고 안 넣었더니 같은 아이디를 가진 사용자가 여러 명 있게 되는 경우가 있을 수 있겠죠. 데이터베이스에 저런 규칙들을 사전에 집어 넣으면, 컴퓨터가 자동으로 데이터의 무결성을 확인하므로 이런 실수를 미연에 방지할 수 있습니다.
[3. 독립성]
우리가 쓰는 컴퓨터 시스템은 멀티태스킹을 지원합니다.
[A 잔고: 100, B 잔고: 200]
다시 은행 거래를 예로 들면, (1) A가 B에게 50을 주는 동시에 (2) C도 B에게 100만큼 계좌 이체를 하는 경우를 생각해 볼 수 있습니다.
이때, 1번 거래을 처리하는 컴퓨터는 B의 최종 잔고가 200 + 50 = 250이라고 계산한 후 그것을 적용하려고 할 것입니다. 한편, 2번 거래를 담당하는 컴퓨터도 B의 잔고를 계산하게 되는데, 이미 잔고가 250으로 늘었다는 것을 알지 못하기 때문에 200 + 100 = 300이라고 생각하게 됩니다. 따라서 원래대로라면 350이었어야 할 잔고가 300밖에 안 되는 상황이 발생하게 되죠.
이를 방지하려면, 1번 거래를 수행하는 동안에는 2번 거래가 기다리도록 순서를 정해 줄 필요가 있습니다. 이런 것을 '독립성'이라고 합니다.
[4. 내구성]
내구성은 무척 간단합니다. 데이터베이스가 일단 '저장 완료'라는 사인을 보냈으면, 그 데이터는 정말로 영구히 보존되어야 한다는 것입니다. 당연한 것 아니냐고 말씀하실 수 있지만, 전원이 갑작스럽게 나간다든지 운영 체제가 뻗는다든지 하는 상황에서도 내구성을 유지하기란 생각보다 쉽지 않습니다.
이러한 4가지 원칙에 대해 알아보았습니다만, 사실 이런 원칙들이 절대적인 것은 아닙니다.
왜냐하면 ACID를 달성하려면 비용이 들기 때문이죠. 특히 성능상 제약이 걸릴 수가 있습니다. 물론 돈이 충분하다면 컴퓨터를 더 좋은 놈으로 업그레이드해서 극복할 수 있겠지만, 만사가 생각대로 되지는 않는 법이죠.
예를 들어, '나는 아이디 중복 확인 기능을 구현하는 것을 절대 까먹지 않는다'고 확신할 수 있다면 굳이 데이터베이스가 일관성을 확인하게 시킬 필요가 없습니다. 일관성 확인도 시간이 소요되는 작업이니까요.
또는, 내 서버에는 UPS가 빵빵한 놈으로 달려 있어서 결코 갑작스러운 정전이 일어나지 않는다고 생각한다면 내구성을 좀 포기하고 성능을 얻을 수도 있습니다.
특히, 요즘처럼 클라우드 컴퓨팅 시대에는 컴퓨터 여러 대를 연결해서 하나의 시스템으로 구축하는 일이 많은데, 이러면 ACID를 지원하기가 좀 버겁게 됩니다. 각 컴퓨터들이 협력해서 움직여야 하기 때문이죠. 이런 걸 분산 시스템이라고 하는데, 이러한 시스템에서 ACID를 어떻게 달성할 것인지 (또는, ACID의 일부를 포기하고도 어떻게 좋은 시스템을 만들 것인지) 연구하는 것도 개발자의 중요한 역할입니다.
지난 글에서 제로보드를 까면서, 불현듯 이 주제가 생각나서 써 보았습니다. 제로보드가 바로 ACID를 제대로 준수하지 못하는 대표적인 소프트웨어거든요.
'계층 댓글 깨짐' 같은 현상이 그래서 일어나는 것이죠. ACID가 보장된다면, 상위 댓글이 없는 댓글은 일관성에서 어긋나기 때문에 데이터베이스가 거부하게 될 것입니다. 하지만 제로보드가 사용하는 MySQL은 이러한 기능이 꺼져 있기 때문에 일관성을 보장하기가 쉽지 않습니다.
또한 재밌게도, PGR21에는 많지는 않지만 4명 정도 아이디가 같은 사용자들이 존재합니다. (!!) 이런 문제도 사전에 방지할 수 있었겠지요.