카테고리 보관물: Linux

mysql(mariadb 5.5)에 있는 데이터를 oracle(oracle 12c)로 migration

mysql에 있는 데이터를 oracle로 migration하기 위해서는 이미 출시되어 있는 툴을 사용하는 것이 가장 빠르고 효율적이다.

그러나, 선천적으로 이러한 툴 또는 유틸리티에 거부감이 있거나 트라이얼 버전의 설치가 번거롭거나 두려움이 느껴지는 경우 직접 데이터를 옮기는 작업을 선택한다.

직접 데이터를 옮기는 방법은 1. phyton이나 php 등으로 프로그램을 직접 짜서 mysql에서 읽어서 oracle로 insert 하는 방법과 2. mysqldump로 데이터를 다운로드 받아 oracle에서 insert를 하는 방법이 있겠다.

1. phyton, php 등으로 직접 프로그램을 짜는 방법

자기가 잘 아는 방법으로 그냥 프로그램을 짜서 돌린다.

이 때 주의할 점이 있는데 DDL, 즉 oracle의 tablespace나 table, view, index, primary key 정의 등은 mysql과 차이가 있기 때문에 미리 별도의 스크립트로 다 만들어 두어야 한다. 그렇지 않으면 프로그램으로 tablespace, table, index 등등을 만들어주는 프로그램을 직접 다 작성해야 한다.

데이터의 insert 시에도 한글 변환문제, 자릿수 문제, NULL 문제 등을 생각하고 처리해야한다. mysql에서는 ”을 NULL로 인식하지 않지만 oracle에서는 NULL로 인식한다.

2. mysqldump를 사용하는 방법

mysqldump -p -u userid database tablename > table1.sql  등의 방법을 사용한다.

이 때 mysqldump로 dump된 내용은

INSERT INTO `tablename` VALUES (value1, value2, value3, .. ), (value1, value2, value3, ... ), (value1, value2, value3, ... ), ...

와 같이 되어 있다.

이를 변환하여

INSERT INTO `tablename` VALUES (value1, value2, value3, ... ) ;
INSERT INTO `tablename` VALUES (value1, value2, value3,... );
...

와 같은 형식으로 변환하는 것은 귀찮은 작업이므로 다음의 옵션을 준다.

mysqldump --skip-opt --quick -p -u userid database tablename > table1.sql .

skip-opt 옵션 ( –skip-opt )는 –add-drop-table, –add-locks, –create-options, –disable-keys, –extended-insert, –lock-tables, –quick, –set-charset 등의 옵션을 취소시키는 옵션으로 그 중 extended-insert 옵션을 특히 disable 시킴으로 써 INSERT 문장이 개별 문장(한줄씩)으로 생성되도록 하고 drop-table 문장과 create table 문장을 포함시키지 않도록 한다. (실제로는 계속 create table 문장이 포함된다)

그리고 –quick 옵션은 버퍼를 하지 않고 바로 disk에 쓰게 함으로써 대용량 테이블의 경우 메모리 오버플로우가 발생하는 것을 막아준다.

그렇게 생성된 table1.sql을 oracle sqlplus에서 @ 명령으로 실행시켜 주면 테이블 명에 `table_name`과 같은 ` 문자가 포함되어 있어서 에러가 발생한다.

그래서

sed -i 's/`//g' table1.sql

명령으로 `문자를 다 제거해 준 다음 sqlplus에서 @로 실행시켜 준다.

 

sqlplus로 oracle에 데이터를 입력할 때 & 문자는 oracle의 예약어로 변수를 선언하는 예약어이다.

만약 데이터 내에 & 문자가 포함되어 있다면 (예를 들어 ‘School & Campus 와 같이 ) insert를 하다가 갑자기 변수값을 입력을 받기 위한 프롬프트 상태가 되어 버린다.

이런 상태를 방지하기 위해서는 table1.sql 파일 첫 머리에

SET DEFINE OFF; 
SET AUTOCOMMIT 1000;

를 추가해 주어야 한다.

SET AUTOCOMMIT 1000;은 1000 line 마다 commit을 해 주도록 한다. 만약 AUTOCOMMIT이 안되면 모든 INSERT 문은 rollback 가능한 상태로 undo tablespace에 저장되고 속도가 점점 느려진다.

한글 문제

데이터 이전시 한글 문제는 여러모로 골치를 썩히는 일이다. 특히 mysql을 패키지로 설치하고 그냥 쓰는 경우 table의 문자셋을 latin1으로 그냥 둔 경우 default-char-set을 latin1으로 지정해야 한글이 정상적으로 추출되고 oracle 한글 입력도 다양한 파라미터( LANG, NLS_LANG, NLS_CHARACTER 등등)를 설정해야 하므로 테스트를 충분히 해 보고 migration해야 할 것이다.

 

 

 

웹 주소에서 php 확장자 안보이게 하기

웹 서버를 설치하고 개발, 운용하는 경우 주소가 http://www.hello.com/world.php?param=1 과 같은 형태로 보여지게되면 뭔가 지저분해 보이기도 하고 약간은 신경을 덜 쓴 듯한 느낌이 든다.

이 때 주소를 http://www.hello.com/world?param=1 또는 http://www.hello.com/world 와 같이 깔끔하게 쓰기 위해서는 Linux, apache, php (LAPM) 환경에서 다음과 같은 작업을 한다.

1. httpd.conf 파일 수정
: Document root director가 될 디렉토리(다음의 예에서는 “myweb_directory” 또는 룰을 적용할 디렉토리에 대한 옵션을 지정한다. 만약 이미 지정되어 있으면 다음의 내용이 있는지 확인한다.

<Directory "/var/www/myweb_directory">
 Options -Indexes MultiViews FollowSymLinks
 AllowOverride All

-Indexes 옵션은 디렉토리의 파일 list를 보여주지 않는 옵션이므로 보안상 적용한다.

다음 httpd 를 다시 시작한다

service httpd restart

이제 http://www.hello.com/world와 같이 써도 인식이 된다. 각 화면에 속한 소스들에서 사이트 내의 link를 “/dir/index.php” 와 같이 작성된 부분을 “/dir/index”로 수정한다.

2. php.ini 파일 수정
/etc/php.ini 파일에서 다음과 같이 수정한다.

expose_php = Off

php.ini를 수정하는 이유는 세션아이디와 같은 부분에서 임시파일 또는 패킷을 캡쳐해서 확인하는 경우 PHP를 사용하는 것을 알 수 있다. 이러한 부분을 숨겨준다고 하니 추가로 꼭 지정한다.

apache의 rewrite rule을 이용하는 부분은 조금 더 복잡하나 다양한 방법으로 주소를 숨길 수 있다.

 

 

ftp passive모드와 포트번호

ftp의 passive모드에 대한 이해와 포트에 대한 오해가 많아 프로젝트에서 개발한 ftp 라이브러리가 회사 서버에 접속하지 못하는 문제를 네트웍관리자, 프로그래머도 해결하지 못하는 경우가 발생하여 ftp에 대해 잠시 분석을 해봤다.
ftp에 대한 기본적인 이해는 이미 알고 있었으나 passive모드에 대한 깨알같은 이해를 이번기회에 확실하게 정리를 하였다.

ftp란
ftp는 당연히 file transfer protocol의 약자로 파일 전송을 위한 기본적인 tcp/ip 프로토콜이다. 초기에 많은 오해가 있었는 부분이 “ftp는 udp 전송을 한다”라는 오해였는데 최근에는 더이상 udp와 tcp를 혼돈하는 경우는 없다.
ftp는 두개의 session을 사용하는데 기본적으로 명령어를 서로 주고 받기 위한 control session과 데이터를 송수신하기 위한 data session이 그것이다.

control session
control session은 흔히 알려진 대로 client쪽에서 server쪽으로 접속 요청을 하고 id와 password를 입력하여 명령을 내릴 준비단계가 된 session이다. 포트는 21번 포트를 사용하며 sftp 등을 사용할 때는 20번 포트 또는 다른 포트로 변경을 하여 사용한다. 그러나 ftp의 공식 포트번호는 21번 포트이다.
일단 접속을 하면 GET, CWD, RETR, LIST 등의 명령을 보내는 통로가 되며 server에서는 이에 대한 응답을 보낸다.

data session
data session은 서버에서 데이터를 보내기 위한 session으로 기본적으로 20번 포트를 사용한다. 20번 포트는 server측의 포트로 server에서 client로 접속하기 위한 기본 포트이다. 이 때 개념적인 server, client와 물리적인 server, client 때문에 많은 혼동이 생길 수 있는데 그 개념은 접어두고 일단 control을 위한 session과 data를 위한 session은 분리되어 있다는 것을 명심해야 한다.

acive모드와 passive모드
Active Mode는 data session을 맺을 때 server(client가 접속한 server)측에서 20번 포트로 client가 지정한 port로 접속을 요청한다 ( server port : 20, client port : client가 통보해주는 랜덤).
그리고 client측에서 control session을 통해 LIST, RETR 등의 명령을 내리면 그 결과를 data session으로 전송해 준다.
Passive Mode는 data session을 server에서 접속하는 것이 아니라 passive mode로 진입하겠다고 client가 통보하면 server에서 접속 가능한 data port 번호를 알려준다. 이 때 이 port 번호로 client가 다시 접속 시도를 해서 접속이 되면 이 data session을 통해 데이터를 받게 된다.

다음의 그림을 보면 명확하게 이해가 될 것이다.
ftp
(그림출처 : taeho’s life logger )

이 때 firewall의 정책이 각각의 ftp server 운영 정책에 따라 달라지는데 active mode의 경우 data session 20번 port의 outbound target을 ANY(*.*.*.*;*)로 open 해 주어야 하고 passive mode의 경우 server의 1024번 이상 포트 inbound ANY(*.*.*.*;*)를 열어주어야 한다.

passive mode port 번호 추출
passive mode로 진입하기 위해 서버에 명령을 전송하면 서버에서는

227 Entering Passive Mode ( 111,222,333,444,123,456)

와 같은 메시지가 전송되어 온다. 이 때 111,222,333,444는 서버의 주소이므로 현재 접속한 서버와 동일할 것이다. 문제는 뒤의 123, 456 위치에 있는 숫자인데 이 숫자가 서버에서 대기하고 있는 data session용 포트번호이다.
ftp를 구현하여 데이터 수신 프로그램을 작성하는 경우 client에서 이 포트번호를 추출하기 위해서는 다음과 같은 코딩을 하여 추출할 수 있다.

        char ip1[10], ip2[10], ip3[10], ip4[10];
        int  port1, port2;
...
중략
...
        if ( atoi(szBuffer) == 227 ) { /* passive mode ok */    
            sscanf(szBuffer, "%[^','],%[^','],%[^','],%[^','],%d,%d", ip1, ip2, ip3, ip4, &port1, &port2);
            nRetCode = port1 * 256 + port2;
        }

server의 port번호는 123 * 256 + 456 이다.

 

[ubuntu] Tomcat7 port를 80으로 설정

ubuntu에 tomcat7을 설치 ( apt-get install tomcat7)을 한 다음 포트번호를
80으로 바꿔 웹서버와 서블릿 서버를 tomcat7 하나로 사용하려고 했으나 ubuntu는 역시 어려웠다.

CentOS에서처럼
/etc/tomcat7/server.xml파일의 Listen port(8080)를 80으로 바꾸고
/etc/default/tomcat7파일의 AUTHBIND=yes를 지정하고

service tomcat7 restart

를 하면 역시

SEVERE: Failed to initialize end point associated with ProtocolHandler [“http-bio-80”]
java.net.BindException: Permission denied :80
at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:410)
at org.apache.tomcat.util.net.AbstractEnd …

이런 에러가 뜬다. (error log 파일에 log만 남고 프로세스가 죽어버리거나, bind error가 난 상태로 떠 있는다)

이 때 해결책은
1. authbind가 있는지 확인하고 없으면 설치(authbind명령을 내려 에러가 나지 않으면 설치되어 있음)

2. root의 권한으로 /etc/authbind/byport에 80 파일을 만들고 tomcat7에게 권한을 준다.
touch /etc/authbind/byport/80
chmod 500 /etc/authbind/byport/80
chown tomcat7.tomcat7 /etc/authbind/byport/80

3. tomcat의 network을 IPv4가 default가 되게 설정해 준다.
cd [TOMCAT_HOME(주로 /usr/share/tomcat7)]/bin
vi setenv.sh
다음을 입력한다.
CATALINA_OPTS=”-Djava.net.preperIPv4Stack=true”
다음에는 같은 디렉토리에 있는 startup.sh 파일을 수정한다.
가장 아랫쪽에 주로 있는 다음의 줄을
exec “$PRGDIR”/”$EXECUTABLE” start “$@”
다음과 같이 변경한다.
exec authbind -deep “$PRGDIR”/”$EXECUTABLE” start “$@”

그리고 tomcat7을 다시 시작하면 에러가 나지 않는다.
service tomcat7 restart

[ubuntu] DHCP를 static IP로 설정

Ubuntu 설치 이후 interface가 dhcp로 설정되어 있으면 telnet접속이 불편하다.
이 때 /etc/network/interfaces 파일을 수정한다.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).# The loopback network interface

auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

“iface eth0 inet dhcp”를 삭제하거나 주석처리하고 IP를 설정해 준다.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).# The loopback network interface

auto lo
iface lo inet loopback

# The primary network interface
auto eth0
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.0.100
netmask 255.255.255.0
dns-nameservers 168.126.63.1
gateway 192.168.0.1

설정이 끝난 다음 network서비스를 다시 시작한다.
sudo service networking restart