2024/01/03
select * from user_constraints
DEFERRABLE
DEFERRED
create 제약조건
create table emp_sal(
salary number constraint sal_ck check(salary>100) deferrable initially immediate,
bonus number constraint bounus_ck check(bonus>0) deferrable initially deferred
);
select * from user_constraints where table_name = 'EMP_SAL';
insert into emp_sal(salary,bonus) values(90,5); -- 오류 salary : initially immediate
insert into emp_sal(salary,bonus) values(101,-5);
commit; -- 오류 bonus : initially deferred
---
commit
오류 보고 -
ORA-02091: 트랜잭션이 롤백되었습니다
ORA-02290: 체크 제약조건(HR.BOUNUS_CK)이 위배되었습니다
02091. 00000 - "transaction rolled back"
*Cause: Also see error 2092. If the transaction is aborted at a remote
site then you will only see 2091; if aborted at host then you will
see 2092 and 2091.
*Action: Add rollback segment and retry the transaction.
---
- 현재 세션에서 모든 제약조건을 지연가능하도록 수행 하겠다는 의미 ( 트랜잭션이 끝나면 자동으로 해지 된다. )
- not deferrable 로 설정되어 있을 경우 불가능하다.
set constraints all deferred; 또는 alter session set constraint = deferred; --- Constraints ALL을(를) 성공했습니다.
insert into emp_sal(salary,bonus) values(90,5);
insert into emp_sal(salary,bonus) values(101,-5);
commit; -- 오류
- 현재 세션에서 모든 제약조건을 즉시 수행 하겠다는 의미 ( 트랜잭션이 끝나면 자동으로 해지 된다. )
set constraints all immediate; 또는 alter session set constraint = immediate; --- Constraints ALL을(를) 성공했습니다.
- bounus_ck 제약조건 여부 체크를 commit 시에 체크하도록 설정
set constraints bounus_ck deferred;
drop table emp_sal purge;
create table emp_sal(
salary number constraint sal_ck check(salary>100) not deferrable initially immediate,
bonus number constraint bonus_ck check(bonus>0) not deferrable initially immediate
);
set constraints all deferred;
insert into emp_sal(salary,bonus) values(90,5); -- 오류
insert into emp_sal(salary,bonus) values(101,-5); -- 오류
오류 이유
: not deferrable로 설정되어 있을 경우 set constraints all deferred 설정이 안된다.
● 제약조건이있는 대량의 데이터 이행 할때 시나리오
▶ 1. 테이블생성, 데이터 추가
drop table test purge;
create table test(id number,name char(10), sal number);
insert into test(id,name,sal) values(1,'a',1000);
insert into test(id,name,sal) values(2,'b',100);
insert into test(id,name,sal) values(1,'c',2000);
commit;
alter table test add constraint test_id_pk primary key(id);
--- 오류
alter table test add constraint test_id_pk primary key(id)
오류 보고 -
ORA-02437: (HR.TEST_ID_PK)을 검증할 수 없습니다 - 잘못된 기본 키입니다
02437. 00000 - "cannot validate (%s.%s) - primary key violated"
*Cause: attempted to validate a primary key with duplicate values or null
values.
*Action: remove the duplicates and null values before enabling a primary
key.
---
▶ 2. 제약 조건을 생성하지만, disable
: DISABLED, NOT VALIDATED 세트이다.
사용하지않고, 적용하지 않겠다.
alter table test add constraint test_id_pk primary key(id) disable;
select * from user_constraints where table_name = 'TEST';
▶ 3. 제약조건을 적용시키기전에 적용안된 데이터를 담을 테이블 생성 (스크립트 사용해도 되고, exceptions 구조처럼 테이블을 만들어줘도 된다.)
SQL> @$ORACLE_HOME/rdbms/admin/utlexpt1
Table created.
SQL> desc exceptions
Name Null? Type
----------------------------------------- -------- ----------------------------
ROW_ID ROWID
OWNER VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CONSTRAINT VARCHAR2(30)
SQL> select rowid, name, id,sal from test;
ROWID NAME ID SAL
------------------ ---------- ---------- ----------
AAAVpFAAEAAAAJWAAA a 1 1000
AAAVpFAAEAAAAJWAAB b 2 100
AAAVpFAAEAAAAJWAAC c 1 2000
AAAVpF : data object id (6)
AAE : file id (3)
AAAAJW : block id (6)
AAA : row slot (3)
select rowid from hr.employees;
select *
from hr.employees
where rowid = 'AAAVPhAAFAAAADPAAV';
select * from user_objects where object_name = 'TEST';
select * from user_segments where segment_name = 'TEST';
[sys session]
select * from dba_data_files;
select * from dba_segments where segment_name = 'TEST';
select * from dba_extents where segment_name = 'TEST';
insert into test(id,name,sal) values(5,'j',3000);
commit;
select * from test;
select * from user_constraints where table_name = 'TEST';
▶ 4. 제약조건 enable 로 변경하고 exceptions 처리, 확인후 변경
alter table test enable constraint test_id_pk exceptions into exceptions;
select * from exceptions;
alter table test add constraint test_id_pk primary key(id) exceptions into exceptions;
select rowid, t.* from test t
where rowid in (select row_id from exceptions);
update test
set id = 6
where rowid = 'AAAVpFAAEAAAAJWAAC';
▶ 5. exceptions 테이블 데이터 삭제하고, 다시 enable로 변경후 enable인지 확인
truncate table exceptions;
alter table test enable constraint test_id_pk exceptions into exceptions;
또는
alter table test add constraint test_id_pk primary key(id) exceptions into exceptions;
select * from exceptions;
select * from user_constraints where table_name = 'TEST';
: 현재 데이터는 검증하지 않고, 새로운 데이터부터 검증
alter table test add constraint test_sal_ck check(sal>=1000) enable novalidate;
select * from user_constraints where table_name = 'TEST';
insert into test(id,name,sal) values(10,'k',500);
--- 오류
insert into test(id,name,sal) values(10,'k',500)
오류 보고 -
ORA-02290: 체크 제약조건(HR.TEST_SAL_CK)이 위배되었습니다
---
truncate table exceptions;
alter table test enable constraint test_sal_ck exceptions into exceptions;
-- enable = enable validate
select * from exceptions;
select rowid, t.* from test t
where rowid in (select row_id from exceptions);
update test
set sal = 1100
where rowid = 'AAAVpFAAEAAAAJWAAB';
truncate table exceptions;
alter table test enable constraint test_sal_ck exceptions into exceptions;
select * from user_constraints where table_name = 'TEST';
: DML 불허
alter table test disable validate constraint test_sal_ck;
disable novalidate (기본값)
: 제약조건을 생성은 하지만 제약조건에 대한 체크는 하지 않겠습니다. 즉 새롭게 들어오는 데이터 기존 데이터에 대해서 제약조건 검증하지 않겠습니다.
, 데이터 이관작업할때 disable novalidate 변경후 이관한 다음 enable로 변경
disable validate
: 제약조건을 생성하지만 새로운 데이터에 대해서 DML은 불허한다.
enable validate (기본값)
: 제약조건을 생성하면서 새로운 데이터 기존 데이터 다 검증한다.
enable novalidate
: 제약조건을 생성하면서 새로운 데이터만 검증한다. 기존 데이터에 대해서는 검증하지 않는다.
하지만 primary key와 unique 제약조건은 enable novalidate 성격을 수행하더라도 기존 데이터도 검증한다.
따라서 제약조건 걸 상황이 오면 enable novalidate 로 변경후 나중에 enable validate 변경후 exceptions를 업무팀에 준다.
: sqldeveloper에서 csv파일로 export 하는것처럼 만들어주기.
[oracle@oracle ~]$ vi emp_sal.sql
set pagesize 0 # : 한페이지로 지정할 라인 수, 0으로 설정하면 컬럼은 출력하지 않습니다.
set linesize 200 # : 한라인에 표시할 글자의 수
set echo off # : 실행하는 SQL문을 출력하지 않습니다.
set termout off # : SQL문으로 실행한 결과를 표시하지 않습니다.
set trimspool on # : 라인뒤 공백을 제거
set feedback off # : SQL문의 실행한 결과 건수를 표시하지 않습니다.
spool emp_sal.csv # : SQL문의 실행결과를 spool file로 생성한다.
-- 이 부분만 변경해주면 된다. csv파일처럼 쉼표를 넣어준다.
select employee_id||','||last_name||','||first_name||','||salary||','||department_id as emp_info
from hr.employees;
spool off # : SQL문의 실행결과를 spool file로 생성을 멈추겠다.
[oracle@oracle spool]$ pwd
/home/oracle/spool
[oracle@oracle spool]$ sqlplus hr/hr
SQL> ! pwd
/home/oracle/spool -- sqlplus한 디렉토리가 바로 현재 위치가된다.
SQL> @emp_sal.sql
: 외부 파일에서 오라클 데이터베이스의 테이블로 data를 load(insert) 하는 프로그램
drop table emp_sal purge;
create table emp_sal
as
select employee_id,last_name,first_name,salary,department_id
from hr.employees
where 1=2;
select * from emp_sal;
[oracle@oracle spool]$ vi emp_sal.ctl
UNRECOVERABLE LOAD DATA # : 리두정보를 담지않는다
INFILE emp_sal.csv
INSERT INTO TABLE hr.emp_sal
FIELDS TERMINATED BY ','
(employee_id,last_name,first_name,salary,department_id)
[oracle@oracle spool]$ sqlldr hr/hr control=emp_sal.ctl direct=true
SQL*Loader: Release 11.2.0.4.0 - Production on Sun Dec 24 02:42:06 2023
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Load completed - logical record count 107.
drop table test purge;
create table hr.test(id number constraint test_id_pk primary key,
name varchar2(30), phone varchar2(20));
[oracle@oracle spool]$ vi insa.ctl
UNRECOVERABLE LOAD DATA
INFILE *
INSERT INTO TABLE hr.test
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
# begindata 의 "" 없애주고 넣어준다.
(ID, NAME, PHONE)
BEGINDATA
1,"JAMES","010-1000-0001"
2,"ORACLE","010-1122-2222"
3,"KIM","010-9999-2222"
[oracle@oracle spool]$ sqlldr hr/hr control=insa.ctl direct=true
SQL*Loader: Release 11.2.0.4.0 - Production on Sun Dec 24 02:58:19 2023
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Load completed - logical record count 3.
UNRECOVERABLE LOAD DATA
INFILE *
# INSERT/REPLACE/TRUNCATE/APPEND
INTO TABLE hr.test
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(ID, NAME, PHONE)
BEGINDATA
1,"JAMES","010-1000-0001"
2,"ORACLE","010-1122-2222"
3,"KIM","010-9999-2222"
- APPEND
: 새로운 데이터를 기존 테이블에 제약조건 상관 없이 추가를 한다. 따라서 제약조건이 망가지는 것을 주의를 해줘야한다.
alter table test disable constraint test_id_pk;
truncate table exceptions;
alter table test enable constraint test_id_pk exceptions into exceptions;
select rowid, t.* from test t
where rowid in (select row_id from exceptions);
delete from test
where rowid in (
'AAAVpgAAEAAAAJUAAA',
'AAAVpgAAEAAAAJUAAB',
'AAAVpgAAEAAAAJUAAC'
);
truncate table exceptions;
alter table test enable constraint test_id_pk exceptions into exceptions;
SELECT * FROM user_indexes WHERE table_name = 'TEST';
2023/01/04
- TRAILING NULLCOLS: 널 값도 포함해서 생성
UNRECOVERABLE LOAD DATA INFILE emp_sal.csv TRUNCATE INTO TABLE hr.emp_sal FIELDS TERMINATED BY ',' TRAILING NULLCOLS (employee_id, last_name, first_name, salary, department_id)
[oracle@oracle spool]$ vi insa.ctl
LOAD DATA
INFILE insa.dat
INSERT
INTO TABLE hr.test
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(ID, NAME, PHONE)
[oracle@oracle spool]$ vi insa.dat
1,"JAMES","010-1000-0001"
2,"ORACLE","010-1122-2222"
3,"KIM","010-9999-2222"
3,"SCOTT","010-2229-2222"
: 로우 단위로 데이터베이스로 적재하는 방법입니다.
데이터 파일의 각 로우를 읽어서 로우를 삽입(insert)합니다.
인덱스 및 제약 조건이 존재하면 그에 따라 검사하고 갱신합니다.
sqlldr hr/hr control=insa.ctl
: 대량의 데이터를 효율적으로 로드하는 방법으로, 데이터를 버퍼 캐시를 거치지 않고 직접 데이터 파일에서 데이터베이스로 로드합니다.
데이터 파일의 내용을 일시적으로 테이블의 임시 세그먼트에 저장하고, 이후에 대량의 블록을 한 번에 데이터베이스에 적재합니다.
sqlldr hr/hr control=insa.ctl direct=true
- 기존의 index scan이 table full scan 으로 바뀐다.
select * from hr.test where id=1;
- INSERT가 안된다.
insert into hr.test(id,name,phone) values(4,'PARK','010-9991-1111'); --- 오류 insert into hr.test(id,name,phone) values(4,'PARK','010-9991-1111') 오류 보고 - ORA-01502: 인덱스 'HR.TEST_ID_PK'또는 인덱스 분할영역은 사용할 수 없은 상태입니다
- delete가 안된다.
delete from hr.test where name='SCOTT'; --- 오류 delete from hr.test where name='SCOTT' 오류 보고 - ORA-01502: 인덱스 'HR.TEST_ID_PK'또는 인덱스 분할영역은 사용할 수 없은 상태입니다
- update가 안된다.
update hr.test set id = 4 where name ='SCOTT'; -- 오류 update hr.test set id = 4 where name ='SCOTT' 오류 보고 - ORA-01502: 인덱스 'HR.TEST_ID_PK'또는 인덱스 분할영역은 사용할 수 없은 상태입니다
- 제약조건 disable로 변경
alter table hr.test disable constraint test_id_pk; select * from dba_constraints where owner ='HR' and table_name = 'TEST'; select * from dba_indexes where owner ='HR' and table_name = 'TEST';
- exceptions 테이블 만들기 (스크립트 사용)
SQL> @$ORACLE_HOME/rdbms/admin/utlexpt1 Table created.
- enable로 변경, exceptions 테이블에 로드
truncate table sys.exceptions; alter table hr.test enable constraint test_id_pk exceptions into sys.exceptions; -- 주의 : sys 세션에서 실행하여도 exceptions 소유자를 쓰지 않으면 hr의 exceptions 테이블로 로드해진다.
- rowid 확인
select rowid, t.* from hr.test t where rowid in (select row_id from exceptions);
- 문제되는것 변경 (업무팀에 전달)
update hr.test set id = 4 where rowid ='AAAVpzAAEAAAAJTAAD'; commit;
- enable로 변경
truncate table sys.exceptions; alter table hr.test enable constraint test_id_pk exceptions into sys.exceptions;
- 확인
select * from dba_constraints where owner ='HR' and table_name = 'TEST'; select * from dba_indexes where owner ='HR' and table_name = 'TEST'; select * from dba_ind_columns where index_owner = 'HR' and table_name = 'TEST';
[문제1]
hr.employees 테이블에서 2005년 이전에 입사한 사원들의
employee_id, last_name, salary, hire_date 데이터를 추출해서
emp_before_2005.csv 파일로 저장해주세요
emp_before_2005.dat 파일에 있는 데이터를 SQL LOADER를 이용해서
hr.emp_before_2005 테이블에 로드해주세요
create table hr.emp_before_2005(
employee_id number,
last_name varchar2(30),
salary number,
hire_date date);
[oracle@oracle spool]$ vi emp_before_2005.sql
set pagesize 0
set linesize 200
set echo off
set termout off
set trimspool on
set feedback off
spool emp_before_2005.csv
select employee_id||','||last_name||','||salary||','||hire_date
from hr.employees
where hire_date < to_date('2005/01/01','yyyy/mm/dd');
spool off
주의 만약 to_char(hire_date,'yyyy/mm/dd')
이면 파일에 로드가 안된다 따라서 컨트롤파일을 (hire_date date 'yyyy/mm/dd') 형식으로 만든다.
SQL> ! pwd
/home/oracle/spool
SQL> @emp_before_2005.sql
[oracle@oracle spool]$ vi emp_before_2005.ctl
UNRECOVERABLE LOAD DATA
INFILE emp_before_2005.csv
TRUNCATE
INTO TABLE hr.emp_before_2005
FIELDS TERMINATED BY ','
TRAILING NULLCOLS
(employee_id, last_name, salary, hire_date)
[oracle@oracle spool]$ sqlldr hr/hr control=emp_before_2005.ctl direct=true
SQL> select * from hr.emp_before_2005;
UNRECOVERABLE LOAD DATA
INFILE emp_new.csv
TRUNCATE
INTO TABLE emp_new
FIELDS TERMINATED BY ','
(employee_id sequence(max,1), last_name, salary, hire_date date 'yyyy/mm/dd')
sequence(max,1) : 1부터 끝까지
sequence(max,1) : 100부터 시작 1씩증가
- Client - Server 환경 (2-Tier)
: client - server 네트워크는 client process (user process) 가 server process에서 서비스를 요청하는 구조입니다.
client 환경에서 구성하는 network 정보
server 환경에서 구성하는 network 정보
- Client - middleware(application tier) - server 환경 (3-Tier)
middleware 환경에서 구성하는 network 정보
server 환경에서 구성하는 network 정보
: db server 는 listener 를 통해 client application 에서 초기 연결을 수신한다.
기본적으로 listener 정보
- listener name
: LISTENER- PORT
: 1521- PROTOCOL
: TCP/IP- SID
: Oracle 데이터베이스의 SID, 예를 들면 ORCL- HOST NAME
: HOST 이름
[oracle@oracle spool]$ cd $ORACLE_HOME/network/admin
[oracle@oracle admin]$ pwd
/u01/app/oracle/product/11.2.0.4/db_1/network/admin
[oracle@oracle admin]$ ls
listener.ora samples shrept.lst tnsnames.ora
[oracle@oracle admin]$ cat listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
[oracle@oracle admin]$ ps -ef | grep pmon
oracle 6240 1 0 Dec23 ? 00:00:11 ora_pmon_ora11g
oracle 27711 24731 0 09:42 pts/1 00:00:00 grep --color=auto pmon
[oracle@oracle admin]$ lsnrctl stop
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 24-DEC-2023 09:44:09
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521)))
The command completed successfully
- pmon process 가 listener 한테 instance (services) 정보를 등록한다.
- pmon
: 데이터베이스 인스턴스의 상태를 모니터링하고 관리하는 역할을 수행합니다.
dynamic 서비스 등록
: 동적 서비스 등록은 오라클 인스턴스를 구성하는 프로세스중 pmon 프로세스가 listener에게 인스턴스 서비스 등록을 한다.
- 기본적으로 pmon process는 TCP/IP의 기본 로컬 주소인 포트 1521 에서 listener 에게 서비스 등록을 한다.
LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) )
SQL> show parameter service_names
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string ora11g
SQL> show parameter db_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string ora11g
SQL> show parameter db_domain
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain string
- lsnrctl stop
[oracle@oracle admin]$ lsnrctl stop
- 리스너 포트 수정
[oracle@oracle admin]$ cd $ORACLE_HOME/network/admin
[oracle@oracle admin]$ pwd
/u01/app/oracle/product/11.2.0.4/db_1/network/admin
[oracle@oracle admin]$ ls
listener.ora samples shrept.lst tnsnames.ora
[oracle@oracle admin]$ vi listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
- lsnrctl start
[oracle@oracle admin]$ lsnrctl start
- lsnrctl 정보 확인
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
[oracle@oracle admin]$ cat listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
- 포트번호 변경 ( 주의:마지막 괄호확인)
SQL> alter system set local_listener = '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522)))';
System altered.
- 확인
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string (DESCRIPTION = (ADDRESS = (PRO
TOCOL = TCP)(HOST = oracle)(PO
RT = 1522)))
- lsnrctl stop
[oracle@oracle admin]$ lsnrctl stop
- 리스너 포트 수정
[oracle@oracle admin]$ cd $ORACLE_HOME/network/admin
[oracle@oracle admin]$ pwd
/u01/app/oracle/product/11.2.0.4/db_1/network/admin
[oracle@oracle admin]$ ls
listener.ora samples shrept.lst tnsnames.ora
[oracle@oracle admin]$ vi listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
- vi tnsames.ora 에 마지막줄 추가
[oracle@oracle admin]$ vi tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
ORA11G =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ora11g)
)
)
LISTENER = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522))
- lsnrctl start
[oracle@oracle admin]$ lsnrctl start
- lsnrctl 정보 확인
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
[oracle@oracle admin]$ cat listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
- 포트번호 변경 ( 주의:마지막 괄호확인)
SQL> alter system set local_listener = 'LISTENER';
System altered.
- 확인
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string LISTENER
[oracle@oracle admin]$ sqlplus / as sysdba
SQL> alter system set local_listener = '';
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
[oracle@oracle admin]$ lsnrctl stop
[oracle@oracle admin]$ lsnrctl start
: etc/host 에 등록했으므로 IP주소, HOST이름은 같다
[oracle@oracle admin]$ vi listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
[oracle@oracle admin]$ lsnrctl stop
[oracle@oracle admin]$ lsnrctl start
SQL> alter system register;
2023/01/05
: listener.ora 메뉴얼하게 서비스 등록해준다.
- listener.ora 파일은 어디있나?
: $ORACLE_HOME/network/admin
[oracle@oracle admin]$ vi listener.ora
SID_LIST_L01 =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = ora11g)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/db_1)
(SID_NAME = ora11g)
)
L01 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1522)))
ADR_BASE_LISTENER = /u01/app/oracle
[oracle@oracle admin]$ lsnrctl start L01
[oracle@oracle admin]$ lsnrctl status L01
[oracle@oracle admin]$ lsnrctl stop L01
[oracle@oracle admin]$ lsnrctl status
[oracle@oracle admin]$ lsnrctl stop
- 간단한 연결 (Easy connect)
- 기본적으로 활성화
- 클라이언트 측 구성이 필요 없다.
- TCP/IP 만 지원
- 로컬 이름 지정
- 클라이언트 측 이름 분석(names resolution) 필요
- 모든 oracle net 프로토콜 지원
- $ORACLE_HOME/network/admin/tnsnames.ora
C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN\tnsnames.ora
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-6FUPLFQ)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
ora11g =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1522))
(CONNECT_DATA =
(SERVICE_NAME = ora11g)
)
)
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
)
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
: 데이터베이스 링크는 다른 데이터베이스의 객체에 액세스할 수 있도록 하는 데이터베이스 객체입니다.
● 1. client XE DB에 tnsnames.ora 내용 추가
$ORACLE_HOME/network/admin/tnsnames.ora
ora11g =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1522))
(CONNECT_DATA =
(SERVICE_NAME = ora11g)
)
)
● 2. XE db에서 remote ora11g로 접속
C:\Users\itwill>sqlplus hr/hr@ora11g
SQL> conn hr/hr@ora11g
C:\Users\itwill>sqlplus hr/hr
● 3. xe에 있는 hr유저에서 시스템 권한 확인
C:\Users\itwill>sqlplus hr/hr
SQL> select * from session_privs;
PRIVILEGE
--------------------------------------------------------------------------------
...
CREATE DATABASE LINK
...
● 4. xe에 있는 hr 에 데이터베이스 링크를 생성
CREATE DATABASE LINK ora11g_hr
CONNECT TO hr identified by hr
USING 'ora11g'; -- tns정보
SELECT * FROM user_db_links;
SELECT * FROM departments@ora11g_hr;
CREATE DATABASE LINK ora11g_insa01
CONNECT TO insa01 identified by oracle
USING 'ora11g'; -- tns정보
SELECT * FROM user_db_links;
SELECT * FROM dept@ora11g_insa01;
select e.employee_id, e.last_name, d.department_name
from employees e, dept@ora11g_insa01 d
where e.department_id = d.department_id
and e.job_id = 'AD_VP';
- DB LINK 생성
CREATE DATABASE LINK ora11g_insa01 CONNECT TO insa01 identified by oracle USING 'ora11g'; -- tns정보
- DB LINK 삭제
DROP DATABASE LINK ora11g_insa01;
● 5. XE dba 로 접속해서 PUBLIC DATABASE LINK 생성
> sqlplus / as sysdba
CREATE PUBLIC DATABASE LINK ora11g_insa01
CONNECT TO insa01 identified by oracle
USING 'ora11g';
SELECT * FROM dba_db_links;
● 6. XE hr로 접속
SELECT * FROM all_db_links;
select e.employee_id, e.last_name, d.department_name
from employees e, dept@ora11g_insa01 d
where e.department_id = d.department_id
and e.job_id = 'AD_VP';
● 7. XE dba로 접속해서 public synonym 생성
CREATE PUBLIC SYNONYM ora11g_dept FOR dept@ora11g_insa01;
SELECT * FROM dba_synonyms WHERE synonym_name = 'ORA11G_DEPT';
● 8. XE hr로 접속해서 synonym 확인
SELECT * FROM all_synonyms WHERE synonym_name = 'ORA11G_DEPT';
select e.employee_id, e.last_name, d.department_name
from employees e, ora11g_dept d
where e.department_id = d.department_id
and e.job_id = 'AD_VP';
● 9. XE dba로 접속해서
DROP PUBLIC SYNONYM ora11g_dept;
DROP PUBLIC DATABASE LINK ora11g_insa01;
dedicated server 환경에서는 server process 안에 PGA안에 UGA가 있다.
PGA (Program Global Area)
shared server 환경에서는 server process 안에 PGA에는 stack space (바인드 변수 생성) 영역만 있고 UGA는 SGA 영역에 저장된다.
PGA (Program Global Area)
※ shared server 환경에서 수행하지 말아야 할 작업, 무조건 dedicated server 환경에서 수행해야하는 작업
- 데이터베이스 관리
- 백업 및 복구 작업
- 대량로드 작업
- 일반적인 dba 작업
- dispatcher 구성
alter system set dispatchers = "(protocol=tcp)(dispatcher=2)";
alter system set max_dispatchers = 10;
SQL> show parameter dispatchers
NAME TYPE VALUE
--------------- ------- ----------------------------
dispatchers string (protocol=tcp)(dispatcher=2)
max_dispatchers integer 10
- shared server process 구성
alter system set shared_servers=2;
alter system set max_shared_servers=10;
SQL> show parameter shared_servers
NAME TYPE VALUE
------------------ ------- -----
max_shared_servers integer 10
shared_servers integer 2
- 윈도우 환경의 tns 파일에 추가
ora11g_d =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ora11g)
)
)
ora11g_s =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = ora11g)
)
)
근데, 스태틱 리스너에서 dispatcher가 안떠서 default 리스너를 이용해서 dispatcher를 띄웠다.
◆ 왜? 스태틱 리스너에서는 안될까?..
[oracle@oracle admin]$ cat listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
SID_LIST_L01 =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = ora11g)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/db_1)
(SID_NAME = ora11g)
)
)
L01 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.104)(PORT = 1522)))
ADR_BASE_LISTENER = /u01/app/oracle