'centos'에 해당하는 글 12건

ORACLE dump import

Daily/Prog 2021. 7. 22. 00:14

 

초보 오라클러가 오라클 데이터를 덤프받아 import 하며 간만에 크게 삽질한 과정을 적어본다. (난 도대체 언제까지 초보일껀가?) impdp 과정에서 오류나는 tablespace 열심히 만들고, 그 외에 유독 눈에 띄는 오류들이 있었다.

 

ora-12899: value too large for column actual x maximum n

 

아니 똑같은 스키마에 덤프 떠서 고대로 넣는데 먼 소린고... 

 

무시하다가 나중에 데이터를 확인했는데 같은 테이블에서도 어떤 컬럼은 한글이 깨지고 어떤 컬럼은 안깨지고... Mysql 에서도 테이블 별로 인코딩 설정은 가능하지만, 컬럼 별로 깨지고 안깨진다? 오라클 초보자로서는 당최 이해할 수가 없었는데 검색을 조금 해보니 알 것 같았다. KO16MSWIN949 의 2바이트짜리 한글들이 AL32UTF8 의 3바이트 한글로 넘어오면서 컬럼값이 넘친 것이니 인코딩 문제는 맞다. 아니 오라클 깔면 기본으로 UTF8 쓰게 되어 있는데 굳이 바꿔 가지고 이렇게들 피곤하게 할까잉...

 

오라클에서 인코딩 관련 설정 2개 / 언어 관련 설정 2개를 찾았다.

 

SELECT name, value$
FROM sys.props$
WHERE name IN ('NLS_LANGUAGE','NLS_TERRITORY','NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');

or

SELECT * 
FROM NLS_DATABASE_PARAMETERS 
WHERE PARAMETER IN ('NLS_LANGUAGE','NLS_TERRITORY','NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');

--NLS_LANGUAGE AMERICAN
--NLS_TERRITORY AMERICA
--NLS_CHARACTERSET AL32UTF8
--NLS_NCHAR_CHARACTERSET AL16UTF16

 

NLS_CHARACTERSET : char / varchar 데이터타입에서 사용하는 문자셋

NLS_VCHAR_CHARACTERSET  : nchar / nvarchar 데이터타입에서 사용하는 문자셋

 

 

역시 덤프 받아온 운영DB 와 NLS_CHARACTERSET 이 달랐고, varchar 의 한글만 문제가 발생한 것이다. KO16MSWIN949 로 인코딩 변경이 필요했다.

 

 

SQL> update props$ set value$='KO16MSWIN949' where name='NLS_CHARACTERSET';
SQL> commit;
SQL> shutdown immediate;
SQL> startup;

 

인터넷에서 대충 검색 해보고 뙇! 역시 천재라고 잠시 생각했지만, update 하면서 인코딩 값에 오타가 들어갔었는지 습관적으로 커밋은 했는데 startup 에 실패했다. 그 일순간의 오타로 오라클을 재설치까지 했다.ㅋㅋ nomount 하고 어쩌구 저쩌구 하면 가능하다고는 하는데, 난 모르겠고 빨리 재설치를 빨리 하는 것이 더 이득인 상황. 어짜피 이미 깨진 한글 다시 넣으려면 테이블들 다 확인해서 drop 을 하던 truncate 를 하던 해야 할 상황이었는데, 재설치가 빠르지... 라는 타협을 하고서는 ./deinstall ㅋㅋ 역시 뭔 프로그램이던 삭제는 참 빨라. $ORACLE_HOME 이랑 oradata 디렉토리도 비워주고 재설치 고고.

 

이번엔 미리 NLS_CHARACTERSET 인코딩 설정하고, profile 에 NLS_LANG 도 맞춰주고... impdp 뙇!

 

ORA-39006: internal error
ORA-39065: unexpected master process exception in DISPATCH
ORA-00600: internal error code, arguments: [kokle_lob2lob13:input mismatch], [1], [], [], [], [], [], []
ORA-39097: Data Pump job encountered unexpected error -600

 

아씨... 이럼 완전 나가린데...

 

한참 삽질 끝에 구글신이 도와주긴 했는데 이해는 안간다. NLS_CHARACTERSET 랑 DB internal 캐릭터셋이 따로 노는겨? 왜 둘다 바꿔줘야 하는겨? ㅡ.ㅡ 테스트 해보니 아래 방법이 NLS_CHARACTERSET 까지 확실하게 바뀌니, 아래 방법을 추천하는 걸로...

 

SQL> shutdown immediate;
SQL> startup mount;
SQL> alter system enable restricted session;
SQL> alter system set job_queue_processes=0;
SQL> alter database open;
SQL> alter database character set internal_use KO16MSWIN949;
SQL> shutdown immediate;
SQL> startup;

 

alter database character set internal_use <- 요기가 포인트!

 

아무튼 긴~ 삽질끝에 덤프질 해결~


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

우와... 난 처음 글을 쓰는 거라고 생각했는데, 약 15년 전에 tomcat5 를 가지고 연동했던 글이 있네. 그 동안 아파치는 10년이 지나도록 apache3 도 내지 않고 있고...ㅋ

 

이렇게 사용하는 이유?는 성능을 위해서 일 수도 있겠고, 리소스 중복 줄이기나, 아파치의 특정 기능을 반드시 사용해야 하거나... 하겠지만, WAS 에서 인스턴스를 1개 정도만 사용한다면 글쎄... jmeter 등으로 테스트 해보고 결정하라. 인스턴스가 여러 개이고 동일한 정적 리소스를 사용한다면, 또 그 양이 방대하다면 리소스 중복을 줄일 수 있다는 이유로 apache 를 사용해 볼 만하다. 아니면 .htaccess? 아니면 php 랑 같이 쓴다던가. 아무튼... 이런저런 이유로 이 둘을 연동해야 한다면 해 봐야지.

 

테스트 환경 : CentOS 7 / Apache 2.4 / Tomcat 8.5 (instance1~3)
테스트 목표 : http://serverIP 80포트로 각 인스턴스에 AJP 통신 확인.(로드밸런싱 용도 아님)

 

 

1. Tomcat server.xml 설정 

 

(Apache / Tomcat 이 설치되어 있다고 가정)

$ vi /app/tomcat/instance1/conf/server.xml
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector protocol="AJP/1.3"
           address="::1"
           port="8009"
           secretRequired="false"
           redirectPort="8443" />

 

server.xml 에 AJP 관련 요소를 수정해야 한다. AJP(Apache JServ Protocol)은 웹서버와 WAS 간에 통신이 가능한 프로토콜이다. 우선 주석을 해제하고 인스턴스 별로 ajp port 와 https redirectPort 를 지정한다. secretRequired="false" 를 지정하지 않으면 아래의 에러를 만나게 된다.

 

Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.

 

 

2. Tomcat Connectors (mod_jk) 설치

의존 라이브러리 설치

 

# yum install gcc gcc-c++ httpd-devel


Download : https://tomcat.apache.org/download-connectors.cgi

 

$ cd /usr/local/src
$ wget https://mirror.navercorp.com/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz
$ tar zxvf tomcat-connectors-1.2.48-src.tar.gz
$ cd tomcat-connectors-1.2.48-src/native/
$ ./configure --with-apxs=/usr/bin/apxs
$ make
$ make install


서버의 apxs 경로 확인 후 올바르게 입력

 

 

3. mod_jk 설정

 

apache 버전마다 설정은 조금씩 다르니 httpd.conf 파일 참고.

 

$ vi /etc/httpd/conf.modules.d/00-jk.conf
LoadModule jk_module modules/mod_jk.so

 

$ vi /etc/httpd/conf.d/mod_jk.conf
<IfModule jk_module>
  JkWorkersFile conf.d/workers.properties
  JkLogFile logs/mod_jk.log
  JkLogLevel debug
  JkShmFile run/mod_jk.shm
  JkMountFile conf.d/uriworkermap.properties
</IfModule>

 

 

4. workers.properties 추가

3개의 Tomcat 인스턴스가 있다고 가정하고 각 인스턴스의 이름과 포트 설정.

 

$ vi /etc/httpd/conf.d/workers.properties
worker.list=tomcat1, tomcat2, tomcat3

worker.tomcat1.type=ajp13
worker.tomcat1.port=8109
worker.tomcat1.host=localhost

worker.tomcat2.type=ajp13
worker.tomcat2.port=8209
worker.tomcat2.host=localhost

worker.tomcat3.type=ajp13
worker.tomcat3.port=8309
worker.tomcat3.host=localhost



5. uriworkermap.properties

 

uri 에 매칭되는 workers.properties 의 worker 인스턴스로 ajp 통신. 해당하지 않는 uri 는 apache 디렉토리에서 매칭.

/=tomcat1
/instance2/*=tomcat2
/instance3/*=tomcat3



6. 톰캣 웹사이트 고양이 복사

 

$ mkdir -p /app/tomcat/instance2/webapps/ROOT/instance2
$ mkdir -p /app/tomcat/instance3/webapps/ROOT/instance3
$ cp /app/tomcat/instance1/webapps/ROOT/*.* /app/tomcat/instance2/webapps/ROOT/instance2
$ cp /app/tomcat/instance1/webapps/ROOT/*.* /app/tomcat/instance2/webapps/ROOT/instance3

 

 

7. SELinux 에 AJP 포트 추가

 

SELinux 정책에 의해 AJP 연결이 추가로 필요할 경우, 해당 IP 를 추가한다.
(/etc/selinux/config 파일에 SELINUX 설정을 변경하는 것은 추천하지 않는다.)

 

# semanage port -a -t http_port_t -p tcp 8109
# semanage port -a -t http_port_t -p tcp 8209
# semanage port -a -t http_port_t -p tcp 8309
# semanage port -l | grep http_port_t
http_port_t        tcp      8309, 8209, 8109, 80, 81, 443, 488, 8008, 8009, 8443, 9000

 

semanage 명령어가 없을 경우, policycoreutils-python 설치

 

# yum install policycoreutils-python

 

 

8. Web Server / WAS 재구동 후 연동 확인

 

http://serverIP
http://serverIP/instance2/
http://serverIP/instance3/

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

Tomcat 에서 인스턴스를 여러개 만들어 서비스에는 성공하였지만, 각 인스턴스간에 세션을 공유해야 할 상황이라면 몇가지 설정을 추가해야 한다.

 

테스트 환경 : CentOS 7 / Tomcat 8.5
테스트 목표 : 구성된 인스턴스 간에 이동을 하더라도 session 유지

 

 

1. 현재 인스턴스 세션 확인

 

톰캣의 기본 고양이 화면 파일을 수정하여 세션ID 를 노출시켰다.

 

$ vi /app/tomcat/instance1/webapps/ROOT/index.jsp
<!-- 세션 사용하도록 항목 삭제나 변경. (기본값 session="true") -->
<%@ page session="false" %>

<!-- body 태그 안에 추가 -->
<%=session.getId()%>


http://serverIP:port1
http://serverIP:port2
http://serverIP:port3

 

EF5B9FCA054DBCEC5E3201DBA42C927A 처럼 보여지는 세션ID 는 세 인스턴스 간에 모든 다른 값을 출력할 것이다.

 

 

2. server.xml 파일 수정

server.xml 파일에 클러스터 설정의 주석을 해제한다.

상세 설정은 tomcat 웹사이트 참고 : https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html 

 

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

 


3. 방화벽 port 추가

<Membership className="org.apache.catalina.tribes.membership.McastService"
            address="228.0.0.4"
            port="45564"
            frequency="500"
            dropTime="3000"/>


클러스터 멤버를 구성하는데 필요한 Multicast 기본 포트(45564)를 추가한다.
멀티캐스트(multicast)는 한 번의 송신으로 메시지나 정보를 여러 컴퓨터에 동시에 전송하는 역할을 한다.

 

# firewall-cmd --permanent --zone=public --add-port=45564/tcp
# firewall-cmd --permanent --zone=public --add-port=45564/udp
# firewall-cmd --reload

 

 

4. web.xml 파일 수정

각 인스턴스의 webapps/ROOT/WEB-INF/web.xml 파일 아래에 distribuable 요소를 추가하면, 해당 컨텍스트에 대한 클러스터링이 진행되며 세션 공유가 가능해 진다.

<web-app ...>
  <distributable/>
</web-app>



5. Apache / Tomcat 재부팅

http://serverIP:port1
http://serverIP:port2
http://serverIP:port3

재부팅 하면 포트간에 이동하여도 동일한 세션ID 가 유지됨을 확인할 수 있다.

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

부제: Tomcat multiple instances 자동 실행

 

작성해 놓은 스크립트를 부팅시 실행시키려면 rc.local 파일을 이용하면 된다. 하지만 rc.local 의 기본값은 부팅시 실행되지 않는다. rc.local 파일이 부팅시 실행되도록 먼저 설정하고, 원래 부팅시 실행하려던 스크립트들을 rc.lcoal 파일에 추가하도록 한다.

 

 

1. rc.local 파일 실행 권한 설정

 

 

# chmod +x /etc/rc.d/rc.local

 

 

2. runlevel3 환경이 셋업될 때 rc.local 이 실행되도록 스크립트 추가

 

# vi /usr/lib/systemd/system/rc-local.service

[Install]
WantedBy=multi-user.target

 

 

3. 부팅시 서비스 자동 실행 설정

 

# systemctl enable rc-local.service

 

 

4. rc.local 파일로 실행할 스크립트 추가

 

su - tomcat /app/tomcat/instance1/start.sh
su - tomcat /app/tomcat/instance2/start.sh
su - tomcat /app/tomcat/instance3/start.sh

 

 

5. 재부팅 후 자동 실행된 데몬들 확인

 

# shutdown -r now

 

$ ps -ef | grep tomcat

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

Tomcat 에서 여러 인스턴스를 관리하는 방법이 있다. CATALINA_HOME 디렉토리에서 필요한 부분만 복제하고 약간의 설정을 수정하여 인스턴스들을 구성할 수 있다. server.xml 파일 하나에 여러 호스트 정보를 등록하여 관리할 수도 있지만 이 경우 Tomcat 을 재구동하면 모든 서비스들이 재구동되는 단점이 있으므로 그다지 추천하지는 않는다.

 

[CATALINA_HOME]

  • Tomcat Engine 디렉토리 : bin, lib
  • Tomcat Instance 디렉토리 : conf(설정), logs(로그), webapps(소스), work(jsp구동), temp(임시)

 

위 내용들 중  Instance 디렉토리를 아래의 절차를 거쳐 별도로 구성해 주면 된다.(Tomcat 설치 생략)

 

  1. 필요한 만큼의 Tomcat Instance 디렉토리를 생성한다.
  2. CATALINA_HOME 으로부터 필요 디렉토리를 복제한다.(conf, webapps)
  3. server.xml 에서 port 등 환경을 변경한다.
  4. 인스턴스 실행/중지 스크립트를 만들고 실행한다.
  5. 방화벽에서 해당 port 를 추가한다.

 

테스트 환경 : CentOS 7 / Tomcat 8.5
테스트 목표 : 서버 ip 에 특정 포트들에 연결되는 여러 인스턴스 구동

 

 

1. Instance 디렉토리 생성

 

# mkdir -p /app/tomcat
# chown -R tomcat:tomcat /app/tomcat
# su - tomcat
$ cd /app/tomcat
$ mkdir -p instance1/logs

 

 

2. CATALINA_HOME 에서 디렉토리 복제

 

$ cp -a /etc/tomcat8/conf instance1
$ cp -a /etc/tomcat8/webapps instance1

 

 

3. server.xml 설정 변경

 

$ vi instance1/conf/server.xml

$ vi instance1/conf/server.xml

<Server port="8005" shutdown="SHUTDOWN">

  <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

 

여기에 shutdown port 와 http 서비스 port / https port 를 바꿔준다. 인스턴스가 3개 라면 8005/8105/8205, 8080/8180/8280, 8443/8444/8445 처럼 포트가 겹치지 않고 기억하기 쉽도록 구성하면 된다.

 

 

4. 구동 스크립트 생성

 

$ vi instance1/startup.sh

#!/bin/sh
export CATALINA_HOME=/etc/tomcat8
export CATALINA_BASE=/app/tomcat/instance1
$CATALINA_HOME/bin/startup.sh

 

$ vi instance1/startup.sh

#!/bin/sh
export CATALINA_HOME=/etc/tomcat8
export CATALINA_BASE=/app/tomcat/instance1
$CATALINA_HOME/bin/shutdown.sh

 

$ chmod u+x startup.sh
$ chmod u+x shutdown.sh

 

이렇게 설정하면 Tomcat 설치 디렉토리에서는 구동 스크립트만 빌려 각각의 인스턴스를 구동할 수 있게 된다. 구성된 instance1 디렉토리를 필요한 만큼 복제한다.

 

$ cp -a instance1 instance2
$ cp -a instance1 instance3

 

복제 후에는 이미 진행했던 3,4 번 단계의 각 인스턴스 설정(server.xml, startup.sh, shutdown.sh)을 변경해 준다.

 

 

5. 방화벽 해당 port 추가

 

# firewall-cmd --permanent --zone=public --add-port=8080/tcp
# firewall-cmd --permanent --zone=public --add-port=8180/tcp
# firewall-cmd --permanent --zone=public --add-port=8280/tcp
# firewall-cmd --permanent --zone=public --add-port=8443-8445/tcp
# firewall-cmd --reload

 

 

6. 각 인스턴스 구동 후 확인

 

$ /app/tomcat/instance1/startup.sh
$ /app/tomcat/instance2/startup.sh
$ /app/tomcat/instance3/startup.sh

 

http://serverIP:instance1port
http://serverIP:instance2port
http://serverIP:instance3port


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,