'ORA-1555 snap shot too old' 에러는 개발자들을 당혹케 만드는 오라클 에러 중 하나이다.
해당 에러에 대한 oerr 유틸의 메세지는 아래와 같다.
[oracle@asmtest ~]$ oerr ora 1555 01555, 00000, "snapshot too old: rollback segment number %s with name \"%s\" too small" // *Cause: rollback records needed by a reader for consistent read are // overwritten by other writers // *Action: If in Automatic Undo Management mode, increase undo_retention // setting. Otherwise, use larger rollback segments
한 사용자가 A 쿼리를 날렸는데 해당 데이터 블록이 (내가 읽으려고 하는 시점 이전에 다른 사용자에 의해 ) 변경이 되어, 롤백 세그먼트에서 해당 블록의 변경전 데이터를 찾으려고 하는데 이미 다른사용자가 해당 롤백 레코드를 덮어 써버려서 이전 데이터를 찾을수 없어서 발생하는 에러.
이를 그림으로 표현하자면 아래와 같다.
개발자들이 이 현상을 이해하려면 아래 두가지에 대한 이해가 필요하다.
- 읽기 일관성
- 언두(롤백) segment 의 매커니즘
1. 읽기 일관성 ( Read consistency)
여기서는 읽기 일관성을 최대한 간단하게 설명해보겠다. (자세한건 검색으로..)
읽기 일관성이란 쿼리의 리턴 데이터들의 시점이 일관성이 있어야 한다는 것이다.
즉, 위의 그림에서 쿼리 A 가 아무리 오래 걸려도 이들 결과 값은 같은 시점의 데이터여야 한다는 것이다.
마치 쿼리 A 가 시작했을때, 해당 DB 의 그 시점의 스냅샷을 뜬것처럼 데이터를 리턴해야 한다는 것이다.
위 그림의 예를 들면 table 이 존재하고, pk 가 aa 인 1 row 가 있다고 가정하자.
조회쿼리 Query A 가 08:00 시에 실행되었다고 치면, 그 당시에 col A 의 값은 1 이었다.
그런데 다른 쿼리 Query B 가 해당 row 를 08:10 에 col A 를 2로 업데이트 했다.
또다시 Query C 가 해당 row 를 08:15 에 col A 를 3 으로 업데이트 했다.
그러면 08:00 에 시작한 Query A 가 08:16 분에 해당 row 를 읽으려고 하면 어떤 값을 return 해야하는가?
현재 데이터블록의 해당 row 값은 3 이지만, 읽기 일관성의 관점에서는 Query A 의 시작시점 값인 1 을 리턴해야한다.
이를위해서 오라클은 과거시점의 데이터를 읽기일관성을 위해 DB의 공간에 저장할 필요가 있는데
이곳이 언두(롤백) 세그먼트 이다.
2. 언두세그먼트 의 매커니즘
언두세그먼트는 디비 전체 (정확히는 instance별) 에서 공유하는 resource 이다.
설정된 공간을 계속해서 덮어쓰는 구조이다. 언두 공간이 부족하면 추가를 할수 있지만 아무런 기준없이 추가를 계속할수는 없고 관리자의 입장에서 사이트의 특성을 고려해서 전략적으로 선택해야한다.
- undo retention
언두 사이즈도 중요하지만 언두데이터를 얼마의 시간동안 유지 할것인가도 중요하다.
유지시간을 너무 짧게 잡으면 금방 다른 데이터로 덮어씌여져 SNAPSHOT TOO OLD 가 발생할 수 있다.
반면 필요 이상으로 길게 잡으면 언두블록을 할당받아야할 세션들에 병목이 발생할수 있다.
식당으로 치면 회전률이 안나오는 격이니 주인 입장에서는 골치가 아프다.
3. 에러에 대한 조치
- ORA-1555 가 발생한 쿼리가 너무 오래동안 수행되었다면 쿼리성능 개선을 고려해본다.
- UNDO RETENTION 이 너무 짧다면 좀 더 길게 변경 해준다.
- UNDO RETENTION 이 적정한데도 에러가 났다면 UNDO DATAFILE 을 추가해준다.
alias grid_env='export ORACLE_HOME=$GRID_HOME;export ORACLE_SID=+ASM;export PATH=$GRID_HOME/bin:$PATH' alias db_env='export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/db_1;export ORACLE_SID=orcl' alias ss='sqlplus / as sysdba' alias oh='cd $ORACLE_HOME' alias gh='cd $GRID_HOME' ===== oracle bash profile =====
This will configure the on-boot properties of the Oracle ASM library driver. The following questions will determine whether the driver is loaded on boot and what permissions it will have. The current values will be shown in brackets ('[]'). Hitting <ENTER> without typing an answer will keep that current value. Ctrl-C will abort.
Default user to own the driver interface []: oracle Default group to own the driver interface []: asmadmin Start Oracle ASM library driver on boot (y/n) [n]: y Scan for Oracle ASM disks on boot (y/n) [y]: y Writing Oracle ASM library driver configuration: done [root@asmtest oracle]#
[root@asmtest oracle]# oracleasm init Creating /dev/oracleasm mount point: /dev/oracleasm Loading module "oracleasm": oracleasm Configuring "oracleasm" to use device physical block size Mounting ASMlib driver filesystem: /dev/oracleasm [root@asmtest oracle]# oracleasm status Checking if ASM is loaded: yes Checking if /dev/oracleasm is mounted: yes [root@asmtest oracle]# oracleasm configure ORACLEASM_ENABLED=true ORACLEASM_UID=oracle ORACLEASM_GID=asmadmin ORACLEASM_SCANBOOT=true ORACLEASM_SCANORDER="" ORACLEASM_SCANEXCLUDE="" ORACLEASM_SCAN_DIRECTORIES="" ORACLEASM_USE_LOGICAL_BLOCK_SIZE="false" [root@asmtest oracle]#
- FDISK
디스크 추가 전
[root@asmtest dev]# ls /dev/sd* /dev/sda /dev/sda1 /dev/sda2
ASM 에서 사용할 디스크그룹을 아래와 같이 추가하자
- crs1,2,3 : asm 파일용, 대충 각 1G - data : database 용, 최소 20G - reco : recovery 영역, 대충 5G
VM관리자에서 설정 클릭
* 디스크는 online 상에선 추가가 안되고 vm 이 down 된 상태에서 가능하다. 처음부터 준비하면 좋다.
오라클 엔진을 설치하고 나서 dbca 로 간단하게 데이터베이스를 생성할수도 있지만 CREATE DATABASE 구문으로 DB 를 생성할수도 있다.
1. CREATE DB
export ORACLE_SID=ORCL; export DB_NAME=ORCL;
--shutdown immediate; sqlplus / as sysdba startup mount exclusive restrict drop database;
-- pfile 은 사전에 준비되어있어야 한다. startup nomount pfile='initORCL.ora'
CREATE DATABASE ORCL user sys identified by oracle user system identified by oracle CONTROLFILE REUSE LOGFILE GROUP 1 ('+DATA') SIZE 10M REUSE, GROUP 2 ('+DATA') SIZE 10M REUSE DATAFILE '+DATA' SIZE 10G AUTOEXTEND ON MAXSIZE 30G DEFAULT TABLESPACE USERS DATAFILE '+DATA' SIZE 10G AUTOEXTEND ON MAXSIZE 30G DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE '+DATA' SIZE 10G AUTOEXTEND ON MAXSIZE 30G UNDO TABLESPACE UNDOTBS DATAFILE '+DATA' SIZE 10G AUTOEXTEND ON MAXSIZE 30G CHARACTER SET AL32UTF8 ;
alter database mount; alter database open;
2. DICTIONARY, 후속작업
수동으로 디비를 생성하고 open 했지만 깡통 디비이기에 할수 있는게 없다. 후속으로 아래 스크립트를 실행하자.
conn sys/oracle as sysdba SQL>@?/rdbms/admin/catalog.sql -- Creates the data dictionary and public synonyms for many of its views, and grants PUBLIC access to the synonyms; also calls the scripts CATAUDIT.SQL, CATESP.SQL, and CATLDR.SQL
SQL>@?/rdbms/admin/catproc.sql -- Runs all scripts required for or used with PL/SQL: CATPRC.SQL, CATRSNAP.SQL, CATRPC.SQL, STANDARD.SQL, DBMSSTDX.SQL, PIPDL.SQL, PIDIAN.SQL, DIUTIL.SQL, PISTUB.SQL, DBMSSNAP.SQL, DBMSLOCK.SQL, DBMSPIPE.SQL, DBMSALRT.SQL, SBMSOTPT.SQL, DBMSDESC.SQL
희생자들을 비난하지말자. 나도 20대였다면 이태원은 꼭 가보고 싶었을거고 그자리에 있었을 수도 있다. 만약 자신은 공감할수 없어서 도저히 명복을 빌어줄수없다면 최소한 침묵을 지키자. 친구, 가족을 잃은자들의 슬픔을 애도기간만이라도 생각해주었으면 한다.
행정력의 부재 아쉽다.
전조는 있었다. 앞서 8시즈음 똑같이 골목의 정체가 발생했다. 기사에 따르면 한 여성의 통솔로 진입을 멈추고 사람들이 조금씩 빠져나왔다고 한다. 그때는 이른시간이라 취한이도 적고 통솔이 되는 분위기였을듯. 그러나 사건이 발생한 10시 경 에는 취한이 도 생기고 군중속에 이상한 분위기가 퍼지면서 이성적통제가 안되었을것이다. 밀라고 한사람도 비난은 받아야겟지만 실제로 그 현장에 있지 않았다면 정확하게 알수없기에 뭐라못하겠다.
결국 그 근처에 통제인원이 있었다면 이상한 심리가 퍼져나가는것을 막을수 있지 않았을까..
경찰력을 무한대로 지원 할수없다면 혼잡도를 cctv등으로 실시간 분석해서 특정 밀집도 이상이면 골목 진입막고 나가는것만 허용하는 것을 했다면 적은인원으로도 통제가 가능했을것이다. 이태원에 핫한 골목이 수십개 있는것도 아니고 딱 한군데 그곳 뿐이라 왜 이런생각을 하지 못했을까..
할로윈하면 이태원이라는 공식이 성립한지 꽤 되었다. 누구나 할로윈하면 "이태원에 가서 분위기를 즐겨야지" 하는 생각을 하게된다. 그러나 이태원의 핫한 골목은 다른 인기 상업지와 다르게 좁은 골목에 형성되었다. 사실 인기 상업지로 성장하기에 한계가 있는 지역인데 수용가능인원보다 휠씬많은 사람이 방문한것이다.
쇼핑몰의 이야기를 한번해보자면.. 사람들은 쇼핑을 특정 기간, 시간에 몰려서 한다. 크리스마스나 연말이나 저녁등. 그러나 쇼핑몰 측은 피크타임을 기준으로 서버를 가지고 있어야 한다. 그렇지 않으면 가장 매출을 많이 올릴수있는 시간에 시스템 장애로 대목을 놓치게 될테니까..
이태원의 참사는 대목인걸 알고있었지만 그에맞는 대응책의 부재로 일어난 사건이라고 생각한다. 그로인한 피해는 앞날이 창창한 젊은이들의 생명이고 다시 되돌릴수 없기에 너무도 가슴이 아프다.