Oacle commt 와 rollback
8699 단어 oracle 학습
redo 벡터 는 redo 로그 파일 에 기록 되 어 있 습 니 다. Oacle 에서 로그 파일 을 사용 하 는 목적 은 미디어 오류 일 때 데이터 베 이 스 를 복원 할 수 있 습 니 다.Oacle 에는 온라인 로그 파일 과 압축 파일 로그 파일 두 가지 로그 파일 이 있 습 니 다.데이터베이스 마다 최소한 두 개의 로그 파일 이 있 습 니 다. 로그 파일 이 가득 찼 을 때 Oacle 은 다음 로그 파일 로 전환 하여 계속 씁 니 다. 이 때 로그 가 다시 가득 찼 을 때 Oacle 에서 압축 파일 로 그 를 사용 하지 않 으 면 Oacle 은 원래 의 일 지 를 덮어 쓰 고 1 번 로그 파일 을 다시 씁 니 다.Oacle 에서 압축 파일 로 그 를 사용 하면 Oacle 은 먼저 1 번 로 그 를 압축 파일 로그 에 기록 한 다음 로 그 를 기록 합 니 다.다음은 Oacle 공식 문서 의 설명 입 니 다. 여기 서 번역 하지 않 겠 습 니 다.
Redo entries record data that you can use to reconstruct all changes made to the database, including the undo segments. Therefore, the redo log also protects rollback data. When you recover the database using redo data, the database reads the change vectors in the redo records and applies the changes to the relevant blocks.
Redo records are buffered in a circular fashion in the redo log buffer of the SGA and are written to one of the redo log files by the Log Writer (LGWR) database background process. Whenever a transaction is committed, LGWR writes the transaction redo records from the redo log buffer of the SGA to a redo log file, and assigns a system change number (SCN) to identify the redo records for each committed transaction. Only when all redo records associated with a given transaction are safely on disk in the online logs is the user process notified that the transaction has been committed.
Redo records can also be written to a redo log file before the corresponding transaction is committed. If the redo log buffer fills, or another transaction commits, LGWR flushes all of the redo log entries in the redo log buffer to a redo log file, even though some redo records may not be committed. If necessary, the database can roll back these changes.
commt 에 관 한 일 들:
트 랜 잭 션 의 크기 가 얼마 든 간 에 commt 는 매우 빠 른 동작 입 니 다.때때로 우 리 는 매우 큰 일이 commt 에 있 을 때 매우 느 릴 것 이 라 고 생각한다.많은 개발 자 들 은 commt 의 작은 사무 가 큰 사 무 를 제출 하 는 것 보다 더 적은 시스템 자원 을 차지 할 것 이 라 고 생각 하지만 실제로 이런 방법 은 시스템 자원 의 소 모 를 증가 시 키 는 것 이다.적당 할 때 사 무 를 제출 합 니 다 (예 를 들 어 업무 가 모두 완료 되 었 습 니 다). 성능 을 향상 시 킬 뿐만 아니 라 공유 자원 의 경쟁 도 줄 일 수 있 습 니 다 (로그 파일, 많은 내부 latch 등).다음은 관련 된 예 를 보 겠 습 니 다.
SQL> create table t (x int);
。
SQL> set serveroutput on
SQL> DECLARE
2 l_start number default dbms_utility.get_time;
3 BEGIN
4 for i in 1..10000
5 loop
6 INSERT INTO t VALUES(i);
7 end loop;
8 COMMIT;
9 dbms_output.put_line( dbms_utility.get_time-l_start || ' hsecs' );
10 END;
11 /
32 hsecs
SQL> DECLARE
2 l_start number default dbms_utility.get_time;
3 BEGIN
4 for i in 1..10000
5 loop
6 INSERT INTO t VALUES(i);
7 COMMIT;
8 end loop;
9 dbms_output.put_line( dbms_utility.get_time-l_start || ' hsecs' );
10 END;
11 /
67 hsecs
PL/SQL 。
우 리 는 끊임없이 업 무 를 제출 하 는 것 을 볼 수 있 습 니 다. 업무 가 끝 난 후에 제출 하 는 것 보다 시간 이 많이 걸 리 기 때문에 빈번 한 제출 을 사용 하지 않 아 도 시스템 자원 의 경쟁 을 줄 일 수 있 습 니 다.
그런데 왜 commt 는 매우 빠 릅 니까? commt 전에 Oacle 은 99% 의 일 을 완 성 했 고 commt 는 해 야 할 일이 매우 적 기 때 문 입 니 다.다음은 Oacle 이 commt 전에 완 성 된 것 입 니 다.
우리 가 commt 명령 을 내 렸 을 때, Oacle 은 다음 과 같은 일 을 했다.
그래서 위 를 통 해 알 수 있 듯 이 commt 는 해 야 할 일이 많 지 않다.그 중 가장 긴 동작 은 LGWR 을 실행 하여 로 그 를 디스크 에 긁 는 것 이다.그러나 LGWR 이 차지 하 는 시간 도 매우 제한 되 어 있 습 니 다. 사실 제출 하기 전에 로 그 를 다시 만 드 는 대부분의 사람들 이 디스크 에 반복 적 으로 긁 혔 습 니 다. 그러면 제출 업무 가 redo 를 디스크 에 긁 어서 많은 시간 을 소모 하 는 것 을 피 할 수 있 습 니 다.redo 가 다음 조건 을 만족 시 킬 때 Oacle 은 redo 를 디스크 에 표시 합 니 다.
우 리 는 예 를 들 어 commt 가 매우 부 드 러 운 조작 임 을 증명 합 니 다.
SQL> create table t as select * from all_objects;
。
SQL> insert into t select * from t;
74429 。
SQL> insert into t select * from t;
148858 。
SQL> commit;
CREATE OR REPLACE PROCEDURE DO_COMMIT(P_ROWS IN NUMBER) AS
L_START NUMBER;
L_AFTER_REDO NUMBER;
L_BEFORE_REDO NUMBER;
BEGIN
SELECT V$MYSTAT.VALUE
INTO L_BEFORE_REDO
FROM V$MYSTAT, V$STATNAME
WHERE V$MYSTAT.STATISTIC# = V$STATNAME.STATISTIC#
AND V$STATNAME.NAME = 'redo size';
L_START := DBMS_UTILITY.GET_TIME;
INSERT INTO T
SELECT * FROM T WHERE ROWNUM < P_ROWS;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rows created');
DBMS_OUTPUT.PUT_LINE('Time to INSERT: ' || TO_CHAR(ROUND((DBMS_UTILITY.GET_TIME - L_START) / 100,5),'999.99') || ' seconds');
L_START := DBMS_UTILITY.GET_TIME;
COMMIT;
DBMS_OUTPUT.PUT_LINE('Time to COMMIT: ' || TO_CHAR(ROUND((DBMS_UTILITY.GET_TIME - L_START) / 100,5),'999.99') || ' seconds');
SELECT V$MYSTAT.VALUE
INTO L_AFTER_REDO
FROM V$MYSTAT, V$STATNAME
WHERE V$MYSTAT.STATISTIC# = V$STATNAME.STATISTIC#
AND V$STATNAME.NAME = 'redo size';
DBMS_OUTPUT.PUT_LINE('Generated ' ||TO_CHAR(L_AFTER_REDO - L_BEFORE_REDO,'999,999,999,999') || ' bytes of redo');
DBMS_OUTPUT.NEW_LINE;
END;
지금 우 리 는 상술 한 과정 을 호출 합 니 다.
SQL> BEGIN
2 FOR I IN 1 .. 5 LOOP
3 DO_COMMIT(POWER(10, I));
4 END LOOP;
5 END
6 ;
7 /
9 rows created
Time to INSERT: 3.45 seconds
Time to COMMIT: .00 seconds
Generated 2,484 bytes of redo
99 rows created
Time to INSERT: .03 seconds
Time to COMMIT: .00 seconds
Generated 9,356 bytes of redo
999 rows created
Time to INSERT: .24 seconds
Time to COMMIT: .00 seconds
Generated 103,336 bytes of redo
9999 rows created
Time to INSERT: 1.15 seconds
Time to COMMIT: .00 seconds
Generated 1,052,000 bytes of redo
99999 rows created
Time to INSERT: 6.31 seconds
Time to COMMIT: .00 seconds
Generated 11,500,372 bytes of redo
PL/SQL 。
SQL> show parameter log_buffer;
NAME TYPE VALUE
------------------------------------ ----------- ---------------
log_buffer integer 8593408
이 를 통 해 알 수 있 듯 이 트 랜 잭 션 이 생 성 된 redo 가 아무리 크 더 라 도 commt 는 사용 하 는 시간 이 짧 습 니 다. redo 가 cache 의 3 분 의 1 에 이 르 렀 을 때 lgwr 는 배경 에서 redo 를 디스크 에 칠 하기 때문에 제출 할 때 나머지 redo 가 많 지 않 기 때문에 redo 가 commt 에 미 치 는 영향 은 매우 적 습 니 다.
rollback 에 관 한 것들:
위의 이 사례 에 대해 만약 에 우리 가 commt 를 rollback 으로 바 꾸 면 어떻게 될 까?
9 rows created
Time to INSERT: .00 seconds
Time to ROLLBACK: .00 seconds
Generated 1,384 bytes of redo
99 rows created
Time to INSERT: .00 seconds
Time to ROLLBACK: .00 seconds
Generated 9,768 bytes of redo
999 rows created
Time to INSERT: .03 seconds
Time to ROLLBACK: .00 seconds
Generated 108,052 bytes of redo
9999 rows created
Time to INSERT: .09 seconds
Time to ROLLBACK: .02 seconds
Generated 1,106,744 bytes of redo
99999 rows created
Time to INSERT: .87 seconds
Time to ROLLBACK: .03 seconds
Generated 12,208,564 bytes of redo
PL/SQL 。
따라서 업무 의 크기 가 rollback 에 미 치 는 영향 이 비교적 크다 는 것 을 알 수 있 습 니 다. 이 유 는 Oacle 이 rollback 복원 전의 모든 작업 을 완성 하여 데이터 베 이 스 를 일치 하 는 상태 로 복원 해 야 하기 때 문 입 니 다. 。rollback 이후 Oacle 은 다음 과 같은 작업 을 수행 해 야 합 니 다.
rollback 은 데이터베이스 자원 을 소모 하 는 일 임 을 알 수 있 기 때문에 Oacle 에 서 는 일반적으로 비교적 큰 업무 에서 rollback 을 사용 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
oracle 저장 프로세스 및 사용자 정의 함수 (저장 함수) 초학1. 저장 프로세스와 저장 함수의 주요 차이 저장 함수는return을 통해 함수 값을 되돌릴 수 있다.저장 함수는 SQL 문장 내부에서 호출할 수 있다.저장 함수는 저장 과정에 비해 많은 제한이 있다.저장 프로세스는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.