본문 바로가기
Oracle/Other

데이터 베이스_ 오라클 [Delete, Truncate, Drop] 데이터 삭제 및 복구

by Super Santj 2019. 7. 5.

데이터를 살제할때 -> drop문 -> drop table 삭제시킬 테이블명 -> DDL문 -> 테이블이 삭제(그 내용도 삭제)

delete 와 truncate의 차이점 및 공통점은 아래와 같다.

    차이점 _

delete from 테이블은 rollback이 된다. 

truncate table 삭제시킬 테이블명은 rollback이 안된다. 해당 구문은 -> DDL 문이기에 롤백이 안된다.

그리고 오라클의 10g 이후부터 flashback 기술 => 항상 복원이 안된다. (휴지통에 임시 저장) -> 휴지통에서 꺼내오기

    공통점 _

일반적인 상황에선 delete from 테이블명; // 해당 구문은 테이블의 모든 데이터를 삭제 하는것이다.

그리고 truncate table 삭제시킬 테이블명; // 해당 구문 또한 테이블의 모든 데이터를 삭제 하는것이다.

    실행 결과 _

SQL> select count(*) from b_emp5;

  COUNT(*)
----------
        14

SQL> delete from b_emp5;

14 행이 삭제되었습니다.

SQL> rollback;

롤백이 완료되었습니다.

아래와 같이 복구가 된다.

SQL> select * from b_emp5;

     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM
---------- ---------- --------- ---------- -------- ---------- ----------
    DEPTNO
----------
      7369 SMITH      CLERK           7902 80/12/17        800
        20

      7499 ALLEN      SALESMAN        7698 81/02/20       1600        300
        30

      7521 WARD       SALESMAN        7698 81/02/22       1250        500
        30


     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM
---------- ---------- --------- ---------- -------- ---------- ----------
    DEPTNO
----------
      7566 JONES      MANAGER         7839 81/04/02       2975
        20

      7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400
        30

      7698 BLAKE      MANAGER         7839 81/05/01       2850
        30


     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM
---------- ---------- --------- ---------- -------- ---------- ----------
    DEPTNO
----------
      7782 CLARK      MANAGER         7839 81/06/09       2450
        10

      7788 SCOTT      ANALYST         7566 87/04/19       3000
        20

      7839 KING       PRESIDENT            81/11/17       5000
        10


     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM
---------- ---------- --------- ---------- -------- ---------- ----------
    DEPTNO
----------
      7844 TURNER     SALESMAN        7698 81/09/08       1500          0
        30

      7876 ADAMS      CLERK           7788 87/05/23       1100
        20

      7900 JAMES      CLERK           7698 81/12/03        950
        30


     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM
---------- ---------- --------- ---------- -------- ---------- ----------
    DEPTNO
----------
      7902 FORD       ANALYST         7566 81/12/03       3000
        20

      7934 MILLER     CLERK           7782 82/01/23       1300
        10


14 개의 행이 선택되었습니다.

우리는 truncate 도 과감하게 실행해보자

SQL> truncate table b_emp5;

테이블이 잘렸습니다.

테이블이 잘렸다고한다... ㅎㄷㄷ 말또한 무섭다. 하지만 우리는 다시 롤백을 진행해본다.

SQL> rollback;

롤백이 완료되었습니다.

롤백이 완료 되었다고는 하지만, 아마 데이터는 다 날라갔을것이다. select 문 + count(*) 를 이용하여 데이터를 조회 하여 보자.

SQL> select count(*) from b_emp5;

  COUNT(*)
----------
         0

모두 날라간것을 확인해 볼수가있다. truncate 는 DDL 문으로 커밋이 완료된상황이고, 이러한 이유로 롤백 적용이 안되는 것을 확인할수가 있다.

그리고 Drop _

우선 emp 테이블에서 테이블을 복제하여 b_emp6 라는 이름으로 테이블을 만들고

테이블이 생성되었습니다.

SQL> drop table b_emp6;

drop 구문을 이용 테이블을 날려보자.

SQL> drop table b_emp6;

테이블이 삭제되었습니다.

그리고 다시 조회 해본다면, 아래와 같은 결과를 볼수가 있는데,,

SQL> select * from b_emp6;
select * from b_emp6
              *
1행에 오류:
ORA-00942: 테이블 또는 뷰가 존재하지 않습니다

우리는 테이블 자체를 삭제 한것이기때문에 말그대로 존재 하지 않은 테이블을 조회한것이다. 그리고 한번 전체적으로 조회를 해보자면,

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
AAAA_QWER                      TABLE
BIN$2ePN4EyAQLqY3KYS0cCY5A==$0 TABLE    <==바로 이것 휴지통으로 들어간것이다.
BONUS                          TABLE
BUSER                          SYNONYM
B_DEPT2                        TABLE
B_EMP2                         TABLE
B_EMP3                         TABLE
B_EMP4                         TABLE
B_EMP5                         TABLE
DEPT                           TABLE
DEPT30                         VIEW

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
EMP                            TABLE
EMP30                          VIEW
EMP_DEPTNO                     TABLE
SALGRADE                       TABLE
TEST1                          TABLE
V_30                           VIEW
V_DALLAS                       VIEW
V_DNAME                        VIEW
V_EMP20                        VIEW
V_EMP_10                       VIEW
V_MAXSAL                       VIEW

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
V_NONE                         TABLE
V_SALE                         VIEW
V_SEARCH                       VIEW
V_SEQUENCE_SEQ                 VIEW
V_SMITH                        VIEW
V_TEST1                        VIEW
ZIPCODE                        TABLE

29 개의 행이 선택되었습니다.

우선 우리는 휴지통을 먼저 desc 문을 이용 조회해보도록 하자.

SQL> desc user_recyclebin;
 이름                                      널?      유형
 ----------------------------------------- -------- ----------------------------
 OBJECT_NAME                               NOT NULL VARCHAR2(30)     ==> 테이블 삭제후 이름
 ORIGINAL_NAME                                      VARCHAR2(32)      ==> 삭제되기 전 이름
 OPERATION                                          VARCHAR2(9)
 TYPE                                               VARCHAR2(25)    ==> 오라클의 객체 종류 즉 테이블
 TS_NAME                                            VARCHAR2(30)
 CREATETIME                                         VARCHAR2(19)
 DROPTIME                                           VARCHAR2(19)   ==> 삭제된 시간
 DROPSCN                                            NUMBER
 PARTITION_NAME                                     VARCHAR2(32)
 CAN_UNDROP                                         VARCHAR2(3)
 CAN_PURGE                                          VARCHAR2(3)
 RELATED                                   NOT NULL NUMBER
 BASE_OBJECT                               NOT NULL NUMBER
 PURGE_OBJECT                              NOT NULL NUMBER
 SPACE                                              NUMBER

그리고 보다 간단한 명령어로 방금 삭제한 테이블을 조회해보고 싶다면, 아래의 구문을 실행하여 결과를 볼수가있다.

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
B_EMP6           BIN$2ePN4EyAQLqY3KYS0cCY5A==$0 TABLE        2019-07-05:09:36:59

휴지통에 우리가 위에서 봤었던 데이터 항목을 확인하였고, 다시 휴지통에서 해당 데이터를 복원 시켜보자면, 아래의 형식에 맞춰 기재를 해야한다.

형식 _

flashback table 복원테이블명(원본테이블명) to before drop

형식에 맞게 작성하게되면 아래와 같은 결과를 얻을수 있다.

SQL> flashback table b_emp6 to before drop;

플래시백이 완료되었습니다.

자 그렇다면.. 휴지통을 거치지 않고 바로 삭제 하는방법은 없을까? 분명히 있다.

flashback 기술이 적용이 안되고, 휴지통을 거치지 않고 바로 삭제하는 구문의 형식은 아래와 같다.

형식 _

drop table 삭제시킬 테이블명 [purge]

실행 결과 _

SQL> drop table b_emp6 purge;

테이블이 삭제되었습니다.

SQL> flashback table b_emp6 to before drop;
flashback table b_emp6 to before drop
*
1행에 오류:
ORA-38305: 객체가 RECYCLE BIN에 없음

완벽하다. 조회까지 해본결과 해당 객체는 휴지통에 존재하지 않는다고 말하고있다.

그리고 우리는 만약 같은 테이블을 여러개 삭제시킨 경우 어떻게 복원을 하는가? 에대한 질문을 할수가있다.

질문의 답을 하자면, 가장 최근에 삭제당한 순서대로 복구가 된다.

테이블을 생성했다, 삭제했다를 시간차를 두고 반복을 먼저 한후,

실행 예제_

SQL> create table t1(a number);

테이블이 생성되었습니다.

SQL> drop table t1;

테이블이 삭제되었습니다.

SQL> create table  t1(a varchar2(10));

테이블이 생성되었습니다.

SQL> drop table t1;

테이블이 삭제되었습니다.

SQL> create table t1(a date);

테이블이 생성되었습니다.

SQL> drop table t1;

테이블이 삭제되었습니다.

SQL> create table t1(a number);

테이블이 생성되었습니다.

SQL> drop table t1;

테이블이 삭제되었습니다.

그리고 휴지통을 조회해 보면, 우리는 시간차 이외에 다른 테이터를 보고 복구 하려는 테이블이 어떤것인지 확인하기가 어렵기때문에 항상 시간차를 중요시 생각하며, 복구 시킬 데이터를 시간 데이터를 보고 선택을 하면 된다.

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1               BIN$AkIt/1dASxaIV32i7pM7Ew==$0 TABLE        2019-07-05:10:12:45
T1               BIN$+1FFYSKVQ3aWfTx0+cu4UQ==$0 TABLE        2019-07-05:10:12:16
T1               BIN$aQf92czhQO6y5we9g/YmsQ==$0 TABLE        2019-07-05:10:11:43
T1               BIN$JKakUtCNStWjlL3ehhSfPA==$0 TABLE        2019-07-05:10:10:40

그리고 우리는 직전의 데이터를 복원해보자면, 아래의 구문을 입력하면 아래와 같은 결과를 볼수가 있다.

SQL> flashback table t1 to before drop;

플래시백이 완료되었습니다.

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1               BIN$+1FFYSKVQ3aWfTx0+cu4UQ==$0 TABLE        2019-07-05:10:12:16
T1               BIN$aQf92czhQO6y5we9g/YmsQ==$0 TABLE        2019-07-05:10:11:43
T1               BIN$JKakUtCNStWjlL3ehhSfPA==$0 TABLE        2019-07-05:10:10:40

가장 마지막에 삭제한 테이블이 복구 됬음을 확인할수가 있다.

하지만 우리가 삭제한 모든 테이블을 다같이 복구를 하게될시 테이블의 이름이 모두 동일하기때문에, 복구할때 동일 테이블 명을 변경 해주는 작업 또한 중요하다. 아래의 형식대로 진행한다면 복원을 할때 이름을 변경 시켜서 복원이 될수있다.

실행 형식 _

flashback table "휴지통의 이상한 문자로 된 테이블 이름을 입력" to before drop rename to 새로운 테이블명;

위와 같이 실행을 하게되면 복원시 이름의 중복 걱정없이 복구 시킬수가있다.

실행 결과 _

SQL> flashback table "BIN$aQf92czhQO6y5we9g/YmsQ==$0" to before drop rename to imsitest;

플래시백이 완료되었습니다.

SQL> select count(*) from imsitest;

  COUNT(*)
----------
         0

테이블 이름이 변경되어 화면에 출력 되었고, 애초에 데이터를 입력하지않아 빈 테이블로 출력이 된것을 확인할 수가 있다.

댓글