데이터이야기

DB 노하우, 데이터직무, 다양한 인터뷰를 만나보세요.

단무지 시즌 IV: 단무지의 DB 운영 이야기(4회) : 희망의 불빛, DB 일일점검의 실전(2)

데이터 이야기
작성자
dataonair
작성일
2016-09-06 00:00
조회
4942


단무지 시즌 IV: 단무지의 DB 운영 이야기(4회)

희망의 불빛, DB 일일점검의 실전(2)



[필자 소개] 서윤식은 외환신용카드에서 DBA 12년, 현대하이카다이렉트에서 DA로 10년을 일했다. 금융권 데이터 분야에서 22년간을 보내며, DBMS 운영 및 튜닝, SQL 튜닝, 데이터 모델링, 데이터 품질관리 영역 등 DB의 전 영역을 고루 경험하였다. 이학사(전자계산학과), 경영학 석사를 거쳐 2015년 8월 IT 정책경영학과 박사 과정을 수료하였다. 2016년 3월부터 데이터와사람들의 대표로 있으며, 한국데이터베이스진흥원의 산업체 전문 강사로서 데이터 모델링 및 SQL 튜닝 강의를 하고 있다. 또한 ‘데이터와사람들(http://cafe.naver.com/dbstudydapsqlp)’이란 네이버 카페를 운영하며, 데이터 영역에 지식이 필요한 사람들과 다양한 방법으로 소통하고 있다.



들어가면서

단무지는 머나먼 대리에게 오전은 DB에 대한 공부를 하고, 오후에 업무를 수행하라는 지시를 내렸습니다. 그 의미는 무딘 도끼로 나무를 열심히 패 봤자 효과가 없다는 것이겠지요. 그리고 단무지는 머나먼 대리에게 Archive log가 무엇인지 확인해 올 것을 숙제로 냈었습니다. 머나먼 대리가 최근 슬슬 DB 분야에 흥미를 갖기 시작한 것 같은데요. 어떻게 진행되고 있는지 같이 보도록 하겠습니다.



희망의 불빛

머나먼: 팀장님, 오늘은 "4. Top100 SQL의 실행계획 변경 여부"부터 설명해 주실 차례입니다.단무지: 그 전에 숙제가 있었을 텐데….



머나먼은 숙제를 잘 해왔다는 것을 자랑이라도 하듯 이 지체 없이 말을 이어나갔다. 네, 팀장님. Archive Log는 Redo-Log 파일의 복사본입니다. 그럼 Redo-Log 파일을 설명하겠습니다.



1. Redo-Log 파일 기록 내용

Redo-Log 파일은 Insert, Update, Delete, Commit을 기록합니다. 또한 DBMS가 발행하는 Check-point 등의 정보를 기록합니다.



2. Redo-Log 파일의 용도

사용자가 데이터 변경(Insert, Update, Delete) 후 commit을 했을 때 commit 한 데이터까지를 보존하기 위한 용도입니다. 따라서 메모리 상에 있는 Redo-Log Buffer의 내용을 사용자가 commit 하는 순간 Redo-Log 파일에 저장합니다. 만약 commit 직후 DBMS가 예상치 못한 상황으로 다운되었을 경우 DBMS가 살아나는 과정에서 인스턴스 리커버리를 수행하게 되는데 이때 Redo-Log 파일에 저장된 내용을 읽어 복구하게 됩니다. Redo-Log Buffer에 있는 내용을 Redo-Log 파일에 기록하는 요건은 몇 가지 더 있으며, 아래와 같습니다.

- 3초마다
- Redo-Log Buffer가 1/3이상 찼거나, 1MB가 넘을 때
- Commit을 만났을 때
- Data Buffer Cache에 있는 내용을 Data File로 기록하기 직전



3. Data File을 활용하지 않고 굳이 Redo-Log 파일에 저장하는 이유

사용자가 commit 할 때마다 Data Buffer Cache에 있는 내용 모두를 데이터 파일에 기록하려면 기록해야 할 용량이 너무 큽니다. 이유는, Data Buffer Cache는 I/O가 블럭 단위로 진행됩니다. 주로 OLTP에서는 1Block의 크기에 8KB를 사용합니다.

따라서 한 사용자가 1건의 row를 Update 하고 commit을 했더라도 DB Buffer Cache에 있는 1Block 전체를 데이터 파일로 기록해야 합니다. 만약 사용자가 3건의 데이터를 변경했고, 3건 모두 다른 Block에 존재한다면, 3Block을 모두 저장해야 합니다. 하지만 Redo Log는 변경된 기록을 레코드 단위로 쌓고 변경된 기록만 Redo-Log 파일에 저장하기 때문에 소량의 데이터를 기록할 수 있습니다. 따라서 사용자가 빠르게 commit을 할 수 있도록 하기 위해 Redo-Log 파일을 사용합니다. 이것을 fast-commit이라 부릅니다. 물론 Oracle에서는 fast-commit을 또 다른 의미로 사용하기도 하지만, 이 내용은 너무 어려운 내용이라 나중에 팀장님께 따로 질문 드리겠습니다.



4. Redo-Log 파일 구성

Redo-Log 파일은 여러 개를 복사해서 가지고 있습니다. 그만큼 중요하기 때문에 복제 본을 두고 운영을 합니다. 통상적으로 1개의 파일을 추가하여 동일한 내용을 2개의 파일에 저장을 합니다. 그리고 그 세트를 묶어 Redo-Log Group이라 합니다. 또한 Redo-Log 그룹은 여러 개를 구성하는데요. 이것도 일반적으로 3개 또는 5개로 운영합니다. 3개로 운영한다는 가정 하에 설명 드리겠습니다.



5. Log Switch

Redo-Log 파일은 서큘러하게 돌아가며 사용합니다. 즉 Redo-Log 그룹 1번에서 Full 났을 경우 그룹 2번을 사용합니다. 이렇게 넘어가는 것을 Log Switch라고 합니다. Log Switch 할 때 1번 로그파일을 Archive Log 디렉터리에 복사해 놓습니다. 그리고 다시 2번 로그 그룹이 Full 났을 경우 3번 로그 그룹을 사용하며, 2번 로그 그룹을 또 Archive Log 디렉터리에 복사해 놓습니다.



6. Log Switch가 안 될 때

3번 로그 그룹을 다 썼을 때 서버는 다시 1번 로그 그룹을 사용하려 합니다. 이때 1번 로그 그룹을 Archive Log 디렉터리로 복제 완료하지 못하였을 경우 서버는 아무런 응답을 하지 못하고, 그저 1번 그룹이 Archive Log 파일로 복제가 완료될 때까지 무한정 대기하게 됩니다.



7. Log Switch가 안되는 원인

- Archive Log 디스크 Full: 디스크가 가득 찼기 때문에 더 이상의 Archive Log를 복사할 수 없는 경우 입니다.
- 트랜잭션이 너무 활발하게 발생하여 Redo-Log 그룹을 Archive Log 디렉터리에 복제하는 속도보다 Redo-Log에 트랜잭션 내용을 적재하는 속도가 더 빠른 경우, 즉 Log Switch가 한 순번을 다 돌았는데, 아직까지 Archive Log 디렉터리에 복제가 안 된 경우입니다. 이때는 Archive Log가 존재하는 디스크를 보다 좋은 성능의 디스크로 교체해 주어야 합니다.
- 이것 이외에 다양한 경우가 있겠으나, 주로 위의 2가지 사유입니다.



8. Archive Log 파일의 용도

백업 받은 Data File을 Restore 후 Recovery 할 경우 사용합니다. Restore 후 백업된 시점의 Archive Log를 이용하여 Database Recovery 할 때 사용합니다.

독자 여러분, 백업 및 복구와 관련된 서적을 찾아 보시면 상세한 정보를 얻을 수 있습니다. 더 자세한 내용을 다룰 수 없을 듯 하니 양해 부탁드립니다.

머나먼 대리는 구글링 및 오라클 매뉴얼을 이용하여 Archive Log 및 Redo-Log에 관한 내용을 찾아 보았다. 그 내용을 토대로 본인이 이해하고 있다는 것을 단무지에게 자랑이라도 하듯

단무지: 오~~~ 거의 완벽하게 이해하였는데! 좋아! 그 정도면 아주 훌륭해.
저 내용을 일주일 만에 이해한 것을 보니, 꽤나 열심히 공부했다는 이야기인데… 며칠 밤을 세웠나머나먼: 아닙니다, 팀장님. 오전에 공부하고, 오후에 업무하고요. 일주일 술 끊고 퇴근 후 5시간,
주말 15시간씩 지난 주에 총 55시간 투자했습니다. 예전엔 책을 봐도 무슨 내용인지 몰랐었는데,
팀장님께서 지나가다 한 마디씩 해 주시는 것이 정말 많은 도움이 되었습니다.단무지: (이놈 봐라 아주 지독한 놈일세! 꼭 7~8년 전 나를 보는 것 같아. 하하) 음~~ 불이 붙었군.
좋아 불이 붙었을 때 계속 밀어 부쳐 보자고. 이제 "4. Top 100 SQL의 실행계획 변경 여부"에 대해 진행해 보자.머나먼: 넵. 알겠습니다, 팀장님.단무지: SQL의 튜닝 우선순위가 무엇인지 맞춰 봐.
1. 응답속도가 오래 걸리는 순서로 SQL 튜닝 대상을 선정해야 한다.
2. 자주 수행되는 SQL 중 최적화되지 않은 SQL을 튜닝 대상으로 선정해야 한다.

머 대리, 둘 중 어느 것이 맞는 내용일까머나먼: 어~~ 글쎄요. 응답 속도가 오래 걸리는 것을 튜닝 대상으로 잡아야 하지 않을까요단무지: 음~~~ 아주 틀린 이야기는 아닌데. 그럼 다시 물어 볼게. 한 달에 한 번 수행되는
SQL인데 속도가 매우 늦어. 또 하나는 초당 3회 이상 수행되는 SQL인데, 3초 이상이 걸려.
튜닝하면 5ms(5/1000초) 이하로 낮출 수가 있어. 그럼 어느 SQL을 튜닝해 줘야 할까머나먼: 아~~~ 이제야 알겠습니다. 당연히 자주 수행되는 SQL을 튜닝해 줘야 하는군요.
자주 수행되기 때문에 시스템에 부하도 많이 줄 것이고요.단무지: 역시, 머나먼 자네는 내 부사수가 되기에 충분한 자질을 가지고 있어.
하하 즉 자주 수행되는 순서로 100위까지 선정을 하여 선정된 SQL은 특별관리를 해 줘야 해



단무지는 이야기를 계속 이어 나갔다.



1. Top100 SQL 선정하기 (매일 수행)

독자 여러분 다음의 SQL은 지면의 폭이 좁은 관계로 들여쓰기 등이 잘 안되어 보일 수 있으니, 복사 후 여러분들의 PC에서 들여쓰기를 재 조정 후 읽으시면 편하게 보실 수 있습니다.



-- Create Table은 최초 1회 수행 후 매일 수행하지 않는다.
CREATE TABLE TOP100
(일자 VARCHAR2(8),
SQL_ID VARCHAR2(13),
EXECUTIONS NUMBER
);-- 매일 수행
INSERT INTO TOP100
SELECT TO_CHAR(SYSDATE, 'YYYYMMDD') 일자, SQL_ID, 일별실행수
FROM (
SELECT *
FROM (
select SQL_ID,
round(executions
/ decode(round(sysdate - to_date(last_load_time, 'yyyy-mm-dd/hh24:mi:ss')),
0, 1, round(sysdate - to_date(last_load_time, 'yyyy-mm-dd/hh24:mi:ss')))) 일별실행수
from v$sql where PARSING_SCHEMA_NAME IN ('ORANGE')
)
ORDER BY 일별실행수 DESC
)
WHERE ROWNUM < = 100;



2. 선정된 SQL의 실행계획 저장 (매일 수행)

-- 저장 테이블 생성 (최초 한번 실행)
CREATE TABLE YOON.TOP100_PLAN
(일자 VARCHAR2(8) ,
SQL_ID VARCHAR2(13) ,
ID NUMBER ,
CHILD_NUMBER NUMBER ,
OPERATION VARCHAR2(60) ,
OPTIONS VARCHAR2(60) ,
OBJECT_OWNER VARCHAR2(30) ,
OBJECT_NAME VARCHAR2(30) ,
SEARCH_COLUMNS NUMBER ,
COST NUMBER ,
BYTES NUMBER ,
ACCESS_PREDICATES VARCHAR2(4000),
FILTER_PREDICATES VARCHAR2(4000),
OPTIMIZER VARCHAR2(40) ,
DEPTH NUMBER
);-- 매일 실행
INSERT INTO YOON.TOP100_PLAN
(일자, SQL_ID, ID, CHILD_NUMBER, OPERATION,
OPTIONS, OBJECT_OWNER, OBJECT_NAME, SEARCH_COLUMNS, COST,BYTES,
ACCESS_PREDICATES, FILTER_PREDICATES, OPTIMIZER, DEPTH)
SELECT TO_CHAR(SYSDATE, 'YYYYMMDD') 일자, SQL_ID, ID, CHILD_NUMBER,
OPERATION, OPTIONS, OBJECT_OWNER, OBJECT_NAME, SEARCH_COLUMNS, COST,BYTES,
ACCESS_PREDICATES,FILTER_PREDICATES, OPTIMIZER, DEPTH
FROM V$SQL_PLAN
WHERE SQL_ID IN (SELECT SQL_ID
FROM YOON.TOP100
WHERE 일자 = TO_CHAR(SYSDATE, 'YYYYMMDD')
);



3. 어제의 실행계획과 변경된 것 찾기

SELECT TOD.SQL_ID, TOD.ID, TOD.OPERATION, TOD.OBJECT_NAME,
YES.SQL_ID, YES.ID, YES.OPERATION, YES.OBJECT_NAME
FROM (
SELECT SQL_ID, ID, OPERATION, OBJECT_NAME
FROM TOP100_PLAN
WHERE 일자 = TO_CHAR(SYSDATE-1, 'YYYYMMDD')
)YES,
(SELECT SQL_ID, ID, OPERATION, OBJECT_NAME
FROM TOP100_PLAN
WHERE 일자 = TO_CHAR(SYSDATE, 'YYYYMMDD')
)TOD
WHERE TOD.SQL_ID = YES.SQL_ID (+)
AND TOD.ID = YES.ID (+)
AND TOD.OPERATION <> YES.OPERATION (+)
ORDER BY TOD.SQL_ID, TOD.ID;



4. 어제와 상이한 실행계획의 실행계획 보기

SELECT SQL_ID, ID, CHILD_NUMBER, LPAD(' ', DEPTH*5)|| OPERATION, OPTIONS,
OBJECT_OWNER||'.'||OBJECT_NAME OBJECT_NAME, OPTIMIZER,
(SELECT COLUMN_NAME
FROM DBA_TAB_COLUMNS
WHERE COLUMN_ID = A.SEARCH_COLUMNS
AND OWNER = A.OBJECT_OWNER
AND TABLE_NAME = A.OBJECT_NAME) cn,
COST,BYTES,ACCESS_PREDICATES,FILTER_PREDICATES
FROM YOON.TOP100_PLAN a
WHERE SQL_ID = '4h78kdyjv5f9m'
ORDER BY ID;



실행계획이 어제의 것과 다른 경우는 대부분 아래의 사유와 같다.

① SQL이 수정되어 신규 실행계획이 만들어진 경우
② 테이블 또는 인덱스의 수정으로 실행계획이 새로 만들어진 경우
③ SQL에서 참조하는 Object의 통계정보 갱신

자주 수행되는 Top100 SQL이 아닌 경우라면 더 많은 사유가 존재하겠지만, 자주 수행되는 SQL이 대상이 되므로 대부분 위의 3 경우에 해당될 것이다.

길게 설명하던 단무지는 갑자기 머나먼 대리에게 질문을 던진다.



단무지: 위의 경우 중 상세하게 실행계획을 점검해야 할 경우가 언제일까머나먼: 음~~~ 2개는 확실히 알겠는데요, 세번째는 통계정보가 무엇인지 몰라 답을 못하겠습니다.
첫 번째 것은 SQL이 신규로 만들어 졌기 때문에 최적화 되어 있는지 봐야 할 것 같고요.
두 번째 것도 인덱스가 수정된 경우라면 다시 최적화를 봐야 할 것 같습니다.단무지: 위의 2가지는 정확해. 반드시 실행계획을 점검해서 최적화 되어 있는지 점검해야 할 거야.
그리고 세 번째도 마찬가지야. 통계정보란 옵티마이저가 실행계획을 만들 때 참조하는 정보야.
과거의 오라클 서버에서는 RBO(Rule Base Optimizer)를 사용했으며, 오라클 8i 버전부터
CBO(Cost Base Optimizer) 기능이 출시 되었으며, 그 이후로는 대부분 CBO를 사용하는 추세지
. CBO를 사용할 경우 옵티마이저는 테이블, 인덱스, 칼럼에 대한 통계정보를 읽어 실행계획을
작성하게 된단 말이야. 그런데 말이야 테이블, 인덱스, 칼럼에 대한 통계정보가 최신 정보가 아니면
옵티마이저는 실행계획을 잘못 만들 수 밖에 없어. 이런 경우지. 실제 테이블은 1억 건이 있다 가정해 보자고.
이때 읽으려는 조건절 칼럼에 인덱스가 존재해. 그럼 Full Scan을 하는게 빠른가 아니면 인덱스를 읽는게 빠른가머나먼: 내 당연히 인덱스를 읽는게 빠르겠죠단무지: 그런데 말야, 통계정보에는 해당 테이블의 레코드가 5건만 있다고 되어 있는거야
그러면 옵티마이저가 Full Scan을 유도할까 인덱스 Scan을 유도할까머나먼: 아~~~ 글쎄요. 옵티마이저가 실행계획을 만들 때 실제 데이터를 모두 읽어 건수를
카운트한 후 실행계획을 만들자면 시간이 너무 오래 걸릴 것이고요.
그러면 잘못된 통계정보를 읽어 실행계획을 만들겠군요. 그렇다면 Full Scan을 유도할 것 같습니다.단무지: 빙고. 그러면 DBA는 이런 경우를 해결해 주기 위해 무엇을 해야 할까머나먼: 통계정보를 주기적으로 Update해 줘야 합니다.단무지: 빙고. 그런데 말야, 통계정보를 DBA가 갱신해 주고 나면, DBMS는 통계정보가
갱신된 테이블 또는 인덱스를 참조하는 SQL에 대한 실행계획을 새로 만들게 되지.
Oracle Shared Pool에 있는 더 자세히 이야기 하자면 Library Cache에 실행계획이
Caching되어 있더라도, 해당 실행계획을 지우고 SQL이 새로 실행될 때 다시 실행계획을
만들어 수행하게 되는데. 문제는 이 때 옵티마이저가 잘못된 실행계획을 만들 경우가 존재해.
그걸 DBA가 일일점검에서 찾아내고, 새롭게 다시 튜닝해 줘야 한다는 거야.
특히나 해당 SQL이 자주 사용되는 SQL 이라면 시스템 부하 및 사용자 응답속도 저하 등으로 장애가 발생할 수 있거든.머나먼: 아~~~ 팀장님. 정말 이제 머리속에 안개가 사라지는 것 같습니다. 감사합니다.단무지: 아 이사람아. 아직 갈 길이 멀어. 하하 오늘은 여기까지만 해 보자고.머나먼: 네. 알겠습니다. 실행계획 관련해서 더 공부해 보겠습니다.



날벼락 맞은 단무지

단무지는 퇴근길에 운전을 하고 있었다. 금요일 저녁이긴 하였으나, 회사에서 8시가 넘어 출발하였기에 길은 그렇게 막히지 않았다. 오늘 퇴근 후 영화나 한편 다운받고 본인이 가장 사랑하는 맥주와 함께 감상해야겠다고 생각하였다. 단무지는 교차로를 지나기 직전 이었다. 신호가 곧 끊기지 않을까 생각하며 신호를 주시하며 엑셀을 천천히 밟고 있었다.

자기 앞 차가 속도를 줄인다. 이 상황에서 빨리 교차로를 통과 해야 하는데 말이다. 앞차는 점점 속도를 더 줄인다. 어 이건 뭐지 이 신호에 충분히 나갈 수 있는데, 앞차의 더딘 움직임이 단무지의 가슴을 답답하게 만드는 것만 같았다. 단무지는 뒤차가 없다는 것을 확인하고 1차로로 차선을 변경하였다. 그리고 곧 앞차를 추월하기 직전이었다. 음. 역시 여자 운전자였군. 그리고 아직 파란 신호등이 있는 것을 확인하고 엑셀 위에 올려있는 오른 발에 힘을 강하게 주었다. 차는 교차로로 진입하였다.

순간 신호등은 노란색으로 변경되었다. 교차로에 진입한 후 노란색 신호등이 변경되었을 경우 최대한 빠르게 교차로를 빠져 나가야 한다는 상식을 단무지는 너무도 잘 알고 있었다. 단무지는 앞차의 방해를 이겨냈다는 묘한 쾌감과 함께 순간의 승리감에 도취되어 있었다. "오 역시 난 베스트 드라이버야. 하하… 오늘은 무슨 영화를 다운 받을까" 라는 생각이 드는 순간 추월하려 했던 우측의 차량이 갑자기 급 좌회전을 하는 것이었다.

그 차량은 약 1.5M 가량 앞서 가고 있었기에 급 좌회전 하며, 단무지 차량과 충돌하려는 순간이었다. 단무지는 충돌을 피하기 위해 좌측으로 핸들을 충분히 꺾었다. 하지만 우측 차량의 방향 전환이 너무도 순식간이었으며, 또한 핸들을 너무 많이 좌측으로 변경하였기에 단무지 차량과 충돌할 듯 보였다.

우측의 차가 단무지에게 점점 더 가까이 다가온다. 단무지도 핸들을 한번 더 감았다. 순발력에 있어 타의 추종을 불허하는 단무지였지만, 옆 차와의 충돌은 막지 못했다. 단무지는 좌회전을 하여 차를 인도로 붙였다. 그리고 긴 한숨을 쉬었다. "새 차를 뽑은 지 이제 6개월도 되지 않았는데 이게 무슨 상황이란 말인가 쩝! 그렇다고 뭐 사람이 다친 것도 아니니 큰 사고는 아니네"라는 생각과 함께 차에서 내려 천천히 뒤에 주차한 사고 차량으로 다가갔다. 여성 운전자는 새파랗게 질려 말도 하지 못하고 운전석에서 어찌 할 바를 몰라 했다.

단무지는 왠지 여자가 안스럽다는 생각이 들었다. 단무지는 웃으며 괜찮다는 제스처를 취하며 유리창을 내리라는 시늉을 했다. "괜찮아요. 어디 다친 데는 없어요" 라고 단무지는 부드럽게 이야기 했다.



여성 운전자: 네. 괜찮은 것 같아요. 그런데 어쩌죠단무지: 혹시 다쳤을 수도 있으니 내려서 걸어봐요.여성 운전자는 단무지의 말대로 차량에서 내려 움직여 보더니 이네 괜찮다고 했으나 울기 직전이었다.여성 운전자: 어떻게 해요 차가 많이 찌그러진 것 같아요.단무지: 사람 안 다쳤으면 큰 사고는 아니에요. 차는 접촉사고 이니 보험처리 하면 괜찮아요
. 혹시 연락할 사람 있어요. 남편 분이나, 아니면...여성 운전자: 저 아줌마 아니에요. 그리고 가족들 다 해외여행 갔는데, 이를 어째드디어 여성운전자는 울기 시작했다. 당황스러운 것은 단무지가 더 심했다.
사고를 유발한 운전자가 울어버리니 이걸 어찌한단 말인가단무지: 괜찮아요. 그럼 보험 들었죠 보험에 처리하면 돼요. 큰 사고 아니고, 현재 차량도
인도로 주차했으니 별일 없어요. 우선 진정하시고요. 괜찮아요, 괜찮아. 혹시 차에 마실 물 같은 거 있어요여성운전자: 네. 제 차에~~~단무지는 뒤 차에서 패트병의 물을 꺼내 와 건네 주었다. 단무지: 물 먼저 마시세요. 여성운전자는 물을 좀 마시더니 이내 안정을 찾은 것 같았다. 단무지: 조금 안정이 되신 것 같으니 제 말씀 좀 들어보세요. 접촉 사고이니 큰 돈 나오지 않을 거고요.
보험에서 처리하면 돼요. 또한 저는 좌회전 차로에서 직진을 했고요. 댁은 직진 차로에서 좌회전해서
사고가 났으니 이건 50:50이예요. 그냥 보험 처리하면 되니까 안심하세요.
이제 서로 연락처 교환하고요. 집에 가서 보험에 신고하세요. 지금 차량 손상된 정도가
서로 비슷한 것 같으니, 각자 자기 차 자기가 고치기로 해요.
만약 보험에 신고하고 문의 하신 후 생각이 바뀌시면 저에게 연락 주세요. 괜찮죠여성운전자: 네~~ 일단 집에 가서 보험에 신고할 게요.단무지: 네. 그럼 제가 명함을 드리겠습니다. 그리고 저한테도 명함 있으면 하나만 주세요.여성 운전자: 단무지 푸~~훗. 아 죄송해요. 제 명함 여기 있어요.단무지: 이제 웃으시는 것 보니 진정이 되셨네요. 그럼 보험접수하고 내일 연락 드릴게요.여성 운전자: 다~~~단무지 팀장님, 저~~~ 저~~~ 운전을 못하겠어요.단무지: (참나~ 사고 유발한 사람 진정 시켰더니 나더러 어쩌라고) 네 여성 운전자: 정말 죄송한 것은 알고 있는데요. 지금 가족도 해외 여행가고 없고요.
집은 여기서 너무 멀어 차를 놓고 갈 수도 없어요. 그런데 운전을 못하겠어요.단무지: 나 원 참! 사고를 유발하셨고요. 제가 진정까지 시켜 드렸는데 저더러 뭘 어쩌란 말입니다.
물에 빠진 사람 건져 줬더니 보따리 내놓으라 한다더니. 지금 한지아 씨가 그런 꼴 아닙니까
제 차는 출고 된 지 6개월 밖에 안 된 차라고요.드디어 참고 있던 단무지가 폭발했다. 허나 여성운전자 한지아는 단무지의 돌변에 놀랐는지 갑자기
울어버리는 것이 아닌가 거기다 조금 전 사고에 간신히 진정시켜 놓았던 것도 도로묵이 되어 버린 상황 같았다."그럼 어떻게 해요. 난 운전을 못하겠는데… 차는 놓고 갈 수도 없는데. 여기가 어딘지도 모르겠고…."
그리고는 주저앉아 흐느끼고 있었다.
"(아~~~놔~~~ 이거 참) 네~~네~~ 알았어요, 알았어. 제가 집까지 모셔다 드리겠습니다. 댁이 어디세요"
단무지가 이야기 했다. "정~~~말~~~요"
한지아는 정말 면목이 없다는 투로 죽어가는 말투로 질문 아닌 질문을 했다.
단무지: 자, 가십시다. 제가 님 차로 댁까지 모셔다 드릴게요.
제 차는 여기다 잠시 주차해 놓으면 될 듯 합니다. 댁이 어디세요한지아: 잠실이요.단무지: 허~~~걱. 여기가 문래동인데 잠실이라고요 ... (체념한 듯) 자~~ 갑시다, 가요.한지아: 정말 고마워요.



고목에서도 꽃은 피고

금요일 저녁인지라 문래동에서 잠실까지는 약 2시간 가량 걸렸다. 한지아는 33살 미혼이었으며, 오늘 휴가를 냈다고 했다. 멀리 해외 출장 가 있던 친구가 돌아오는 날이었기에 친구들과 함께 하루를 보냈고, 이제 집으로 돌아가는 길이라 했다. 한지아는 손해보험사 IT 부서 대리였으며, Java 개발자라 했다. 그리고 단무지가 데이터아키텍처라고 이야기했더니 굉장히 부러워하는 눈치였다. 그리고 한지아 집에 주차를 하고 근처 커피숍에서 커피를 한잔 하고 있는 중이다.



한지아: 정말 죄송하고, 너무 고마워서 뭐라 드릴 말씀이 없어요. 사실 사고도 제가 유발한 것 알고 있어요.
길을 잘 몰라서 좌회전 해야 하는지 직진 해야 하는지 몰라 망설이다 갑자기 방향을 바꿔서 사고가 난 거예요.
그런데 단무지 씨는 사고도 50:50이라고 얘기해 주셨고요.
저를 진정시켜 주시고, 또 운전까지 해서 저를 바래다 주셨어요. 정말 고마워요. 좋으신 분 같아요.단무지: 하하하… 그렇네요. 상황이 좀 어이 없긴 하지만 나쁘지는 않네요. 하하한지아: 그래서 말인데요. 솔로라 하셨죠단무지: 네. 모태솔로는 아니지만, 그렇다고 돌싱도 아닙니다. 하하한지아: 제가 오늘의 고마운 것을 보답해 드릴 겸 해서 앞으로 10번 정도 밥을 사 드리면 안될까요단무지: 안됩니다!!! 절대 그럴 수 없습니다.한지아: (얼굴이 확 달아오른다. 양손으로 볼을 감싸며) 아~~ 네. 알겠습니다. 그럼 오늘 너무 감사했습니다.단무지: 술과 함께 산다면 모를까 밥만으로는 부족합니다.한지아: (얼굴에 화색이 돈다) 아~~ 네. 네, 물론이죠. 술도 함께 사야죠. 고맙습니다.
(허~~~걱. 고맙다니 아~~~ 개 쪽팔림!!!)단무지: 저야 영광입니다. 한지아 씨 같은 미인이 제게 밥과 술을 사준다면
아주 영광 그 자체 입니다. 하지만 한 가지 조건이 있습니다.한지아: (또 다시 쪽팔릴까 긴장된다) 네 그게 뭔데요단무지: 저는 36살, 지아 씨는 33살. 그러니까 다음 번 만날 때부터 지아 씨가 저를 오빠라 불러야 한다는 겁니다.한지아: (참눼~~ 친절하지만 정말 엉뚱하고 재미있는 사람이네) 사실 저도 그러려고 했어요. (쑥스러움)단무지: 그럼 다음부터가 아닌 오늘부터 술 한잔 사시죠 어때요
지금부터 오빠라 불러 보시고요.한지아: 하하~~ 네. 좋아요. 한잔 하러 가시죠. 지금은 쑥스러우니 술 한잔 들어가면
그때부터 오빠라 불러 드릴께요.단무지: 아~~~싸



고목에도 꽃이 핀다 했던가 36살의 청춘() 단무지에게도 봄이 오고 있었다. (다음 회에 계속) .



출처 : 한국데이터진흥원

제공 : 데이터 전문가 지식포털 DBguide.net