부연 설명이 좀 더 있어야 할 듯...
1. snapshot too old와 undo tablespace full의 발생 우선순위
언두 사용시 더이상 사용할 공간이 없을때 에전 언두 데이터를 덮어써 snapshot too old
메세지를 발생시키는지.. 아니면 undo tablespace full 메세지를 발생시키는지
메세지간의 우선 순위
==> snapshot too old 와 undo tablespace full은 언두 내에서 일어나는 문제 때문에 발생하는 에러 이지만
두 에러는 별개의 문제라는 생각이 드네요.
9i 이후의 버전에서 aum(automatic undo management) 사용을 예로 들면
진행중인 트랜잭션이 모든 undo tablespace를 사용하여 더 이상 사용할 공간이 없을 경우 발생하는 것이며,
(이 경우에는 모든 undo segment의 모든 extent들의 상태는 active 상태임)
snapshot too old는 undo의 circular 동작 방식과 관계가 있습니다,
간단히 말씀드리면 각각의 undo segment는에는 트랜잭션을 관리하는 트랜젝션 테이블 슬롯과
그 undo 정보를 저장하는 undo block(undo recode)으로 볼 수 있는데요,
트랜잭션이 많은 시스템에서는 undo의 circular 방식에 의해(10g의 guarantee 옵션 제외)
active 상태가 아니면 새로운 트랜잭션이 트랜잭션 테이블 슬롯 이든 undo block든 모두 재사용 될 수 있으며
재사용된 테이블 슬롯 이든 undo block을 read consistent를 위해 읽을 필요가 있는 세션은
쿼리를 시작했던 시점의 data를 복원할 수 없으므로 나는 에러이므로
무엇이 우선이다 라고 얘기 할 수 없듯 합니다.
==> 이런 이슈가 나온 이유는,
어느날 내가 ctas 작업을 하고 있었는데 select 하는 테이블은 아무도 사용을 하지 않는 테이블이었거든.
그런데 한 3시간 돌고 나서 snapshot too old가 떨어져 버리는 거야.
ctas는 ddl 이긴 하지만 만약 undo를 사용한다고 하면 undo가 풀나서 못사용한다는 에러야 이해가 가지만,
내가 읽는 데이터는 undo에서 읽어 올 이유가 전혀 없는데 snapshot too old가 떨어진 것이 잘 이해가 안되어서 한 질문..
==> 형이 겪은 내용은 아주 드믄 경우의 예인거 같은데요..
snapshot too old에러가 나는 경우는 위에서 얘기한 것과 같이 두가지 경우인데요.. 그 중 트랜잭션 테이블 슬롯이
재사용되었을 경우에 발생했다고 볼 수 있을거 같습니다.
그 당시 select 하던 테이블이 오래전에 대량의 변경이 발생하였고
당시 아무도 사용하지 않았지만 해당 시간대에 트랜잭션이 많았다면
오라클이 commit하는 방식중 delay block cleanout 방식에 의한 에러 일 가능성이 있을거 같습니다.
2. rollback segment 사용시처럼 특정 작업에 특정 롤백 세그먼트를
사용하도록 하는 히든 패러미터 존재 여부
==> UNDO 테이블스페이스에도 rollback segment를 만들 수는 있으나 그렇게 하지 않는 것이 권고사항이라네요.
다른 하나의 방법은 auto 와 manual로 두 undo tablespace를 만들고 메뉴얼한 작업이 필요한 경우에 한하여
alter system set undo_tablespace=xx;
로 변경하여 지정후 사용할 수 있는 것으로 압니다.
==> 이러한 방법이 있었군.
그런데 alter system set 으로 변경하게 되면 전체적으로 그 undo를 사용하는거 아닌가?
실제 예전 rollback segment 처럼 특정 세션이나 특정 작업이 특정 undo를 사용할 수 있게 만들 수는 없나?
그게 궁금해서 나왔던 얘기였지...
==> 글쎄요.. 같이 사용할 수 있는 방법은 모르겠어요.. ㅜ.ㅜ
전에 듣기로는 어느 사이트는 배치가 끝난 업무시간에는 auto로 사용하다가
저녁 배치 실행시에는 위와 같이 바꿔서 돌리고 끝나면 다시 바꿔서 사용한다고 들은 사이트가 있었던거 같네요...
3. 인덱스리빌드시 사용하는 테이블스페이스
인덱스가 존재하는 테이블스페이스인지, 템프 테이블스페이스인지
==> 모든 정렬은 sort area에서 발생하는 합니다. 고로 템프 테이블 스페이스를 사용하거 같네요.
새로운 이름으로 인덱스를 생성하고 나중에 체인지하고 기존꺼 드랍 하는 방식 이였던거 같은데요.
누가 테스트해 주세요.. 정확히 말씀드리기 힘드네요..
==> 어떻게 테스트 해야 할지 몰라서..ㅋㅋ
인덱스를 리빌드 할때는 기존의 인덱스를 읽어서 생성하고 완료되면 기존 인덱스는 드랍하는 방식이라서
혹시 템프테이블스페이스를 사용하더라도 최소한으로 사용하지 않나 하는 생각이 있어서..
나도 질문 자체가 정확히 기억나지 않는군..
==> 리빌드 하면서 템프 사용량 계속 확인해보니
현재 108M의 인덱스 리빌드 해보니
해당 세션의 템프 사용량 없는 상태에서 최대 105M 까지 증가하다가 인덱스 리빌드 완료 후 바로 사용량 0M.
인덱스의 크기는 리빌드 후에 104M 네요..
4. 인덱스 nologging 사용시 문제
왜 인덱스를 nologging으로 사용하지는 않는지
==> 저희는 인덱스를 nologging으로 운영하다가 최근에 제가 logging으로 바꿨습니다.
인덱스를 nologging으로 사용하는 이유는 다 아시다 시피 redo로그 생성량을 줄일 수 있기때문인데요.
대신 db crash 발생시 복구를 하게 되면 해당하는 테이블의 인덱스를 리빌드 해 줘야 합니다.
그만큼 복구 시간이 길어 지게 되므로 redo로그 발생이 많아지더라도 복구 시간을 최소해 하기
위해 전 바꾸었는데요. 인덱스 없이 운영가능하거나 복구 시 시간에 자유로운 시스템이라면
굳이 logging으로 운영할 필요는 없을거 같네요..
(또하나는 복구시 찾아서 인덱스 리빌드까지 해 줘야 하므로 귀찮니즘이....)
==> 현재 내가 맡고 있는 시스템에서 대량의 데이터를 입력할 때 인덱스가 있으면 너무 오래 걸려서
인덱스를 unusable 한 후 입력하고 나중에 rebuild 를 하는데, 그렇게 하면 훨씬 작업시간이 단축되거든..
이유는, 인덱스가 있으면 데이터를 입력하는 동안 게속 인덱스도 같이 만들기 때문에...
나중에 인덱스 리빌드를 하게 되면 parallel로 할 수도 있고, 또 한번에 몰아서 정렬하고 하니까 훨씬 빠르거든.
동일한 이유로, db crash가 발생하여 리두로그 혹은 아카이브에서 데이터를 복구 할때도 결국엔 insert 작업을
할텐데 인덱스가 있으면 더 많이 늦어질꺼잖아.
테이블이 깨지면 일단 테이블의 데이터를 우선 복구한 후 인덱스는 재생성하거나 재 구축하면 더 빠르지 않을까?
굳이 db crash가 난 비상상황에서 인덱스까지 껀껀이 만들어 가면서 복구해야 하는지...
==> redo로그의 경우는 저장되는 정보가 operation code와 물리적인 위치(rowid), 변경된 값 많을 가지고 있어서
마지막 백업 이후의 데이터만 복구하면 되므로 복구시에 빠르게 복구 될거구요..
대량의 데이터 작업하고는 틀리게 인덱스도 로그로 복구되면 해당 위치에 바로 복구 되므로
리빌드보다는 빠른 복구가 가능 합니다.
5. 파티션 테이블에서 append 힌트를 사용해서 insert시에
테이블 전체에 락을 잡는지 아니면 해당 파티션에만 락을 잡는지
==> 일반적으로 생각해 보면 오라클이 append시 어떤 값이 들어 올지 모르므로
테이블 전체에 대해 락을 잡을듯 하네요.
insert into tbl partition (part_name)
select * from tbl2;
위의 구문이 동작하므로 파티션 단위로 락을 잡게 할 수 있으므로 전체를 잡을듯하네요.
이것도 누가 테스트 해주세요...ㅎㅎ
==> 요건 곧 테스트 해 볼 생각임...
그런데 db link 상황에서 insert into tbl partition (part_name) 이런 식의 구문이 먹을까?
==> 불행이도 db link상에서는 할수 없네요.
ora-14100 에러 나네요..