지금까지 미국산 알티베이스를 주로 써왔는데 알티베이스의 경우 iloader 툴이 fmt파일을 없는 경우 formout 옵션을 통해 만들 수가 있다.

그렇게 써오던 중 오라클은 sqlldr에서 동일한 기능이 없다는 것을 알게 되었음.

작업할 테이블이 한두개면야 만들어서 쓰겠는데...이번에 작업할 테이블 개수가 대략 수백개에 달했다.

분명 이런거 자동으로 해주는 툴이 있거나 쉘로 짜서 올려놓은 분이 있을거라 생각했는데 검색에 실패함...ㅜ

그래서 직접 짜보는 sqlldr용 컨트롤 파일 작성기!

먼저 테이블명과 컬럼을 수집할 대상이 있다면 좋겠지만 난 없지만 다행이도 전체 테이블을 대상으로 함. 그렇기에 질의를 통해 이를 해결함.

#!/bin/sh echo "set pagesize 10000;" > login.sql echo "set linesize 1024;" >> login.sql echo "set heading off;" >> login.sql echo "set feedback off;" >> login.sql function scan_tbl() { sqlplus -S scott/tiger << EOF select table_name from user_tables order by table_name; --select table_name, owner from all_tables where owner = 'SCOTT' order by table_name; quit; EOF } function scan_col() { sqlplus -S scott/tiger << EOF --select wm_concat(column_name) from user_tab_columns where table_name ='$1' order by COLUMN_ID; select listagg(column_name, ',') within group(order by column_id) from user_tab_columns where table_name ='$1'; quit; EOF } for TBL_NAME in `scan_tbl` do #echo "TABLE_NAME=[${TBL_NAME}]" echo "load data" > ${TBL_NAME}.ctl echo "infile ${TBL_NAME}.dat" >> ${TBL_NAME}.ctl echo "into table ${TBL_NAME}" >> ${TBL_NAME}.ctl echo "fields terminated by '^'" >> ${TBL_NAME}.ctl echo "optionally enclosed by '\"'" >> ${TBL_NAME}.ctl echo "TRAILING NULLCOLS" >> ${TBL_NAME}.ctl echo "(" >> ${TBL_NAME}.ctl echo `scan_col ${TBL_NAME}` >> ${TBL_NAME}.ctl echo ")" >> ${TBL_NAME}.ctl done

어렵지 않은 코드이니 직관적으로 이해하기 쉬운 수준이다.

단점은 오라클 11g이상에서만 동작한다. 이유는 LISTAGG 함수 때문...11g이하에선 WM_CONCAT을 사용해야 하는데 컬럼 순서 오더링이 보장되지 않는다...WM_CONCAT에 대해 잘 아시는 분이라면 해결하실 듯...

추가로 처음에 테이블 리스트를 조회하는데 한번 그리고 테이블 당 한번씩 컬럼 정보를 조회하기 위해서 데이터베이스에 연결을 한다. 이부분에서 지연이 발생한다. 컬럼 정보를 한방에 받아오고 나눠서 쓰거나 분석해서 쓰면 훨씬 빨라지리라 예상한다.

제약으로는 이미 받아져 있는 데이터파일을 올릴 경우 모든 컬럼이 있어야 하고, 컬럼 순서가 동일해야 한다는 정도이다.

그 외에는 딱히 생각나는게 없네...

보통 리눅스에서 프로그램을 설치하거나 업데이트 할 때 yum(나는 보통 '윰'이라 읽었는데, 외국에선 '염'에 가깝게 읽는다더란...)이란 프로그램을 사용했는데...리눅스를 관리할 일이 없다보니 이 툴도 잘 사용하는 편이 아니었다.

이번에 FC22를 설치하고 보니 yum이 dnf로 대체 되었다고 한다.
X환경에서 프로그램 하나 설치하려고 하면 왜이리 힘든지...이제 늙은건지 이리 해보고 저리 해봐도 잘 모르겠다.
gui는 포기하고 쉘환경에서 dnf를 사용해서 설치하기로 했다.

먼저 dnf -y update 통해 설치되어 있는 것들을 최신으로 업데이트 한다.(아마 맞을거다...)
그리고 나서 dnf -y install vim-enhanced 명령으로 vim을 설치한다.

관련 정보는 아래 링크에서 얻었다.

http://www.liquidweb.com/kb/how-to-install-vim-visual-editor-improved-on-fedora-22/

기존에 쓰던 리눅스는 runlevel을 변경하기 위해서 /etc/inittab 파일을 수정해왔다.

id:3:initdefault:

하지만 이번에 설치한 Fedora Core 22에서는 해당 파일에서 runlevel을 변경하는 항목을 찾을 수 없었다.

대신 다른 방법을 사용하라고 알려주신다.

# inittab is no longer used.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target

root 유저로 아래와 같이 명령을 내리니 변경이 되었다.

systemctl set-default multi-user.target

이후 확인해 보면 아래와 같이 변경 된 것을 확인할 수 있다.

변경 전
# ls -al /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 36 10월 14 17:33 /etc/systemd/system/default.target -> /lib/systemd/system/graphical.target

변경 후
# ls -al /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 41 10월 15 13:22 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

회사 svn이 워낙 중요한 데이터가 있다보니 백업의 중요도가 상당하다...
그래서 매일 백업을 해 특정 저장 공간에 보관하려고 하는데 쓰려고 간단하게 쉘을 하나 작성하였다.
대단한건 아니고 svn 저장소를 통째로 압축하여 전달하는 역할이다. 이 쉘 스크립트는 이전 회사에서 부터 써오던 쉘스크립트를 내가 맘데로 변형 발전시켜온 것인데...토대가 되는 쉘 스크립트의 저작권은 아마도 전 회사에 귀속되어있을테니 이거 가지고 '너 고소!' 하면 할말은 없을지도....
설마 그정도로 쓰래기 짓을 하겠냐 하는 분도 있겠지만 지금 하는 행태로 봐선 쓰래기들이 쓰래기짓하고 있음.

#!/bin/sh
# 변수 등록
_DATE=`date '+%Y%m%d'`
_LOG_TIME=`date '+[%Y/%m/%d %H:%M:%S]'`
_EX_DAY=2
_BACKUP_DIR=$HOME/BACKUP
_LOG_DIR=$_BACKUP_DIR
_BACKUP_FILE=svn_backup
_LOGFILE=$_LOG_DIR/svn_backup.log


_LOGGING()
{
    echo "[`date '+%Y/%m/%d %H:%M:%S'`] $*"  >> $_LOGFILE
}

if [ ! -d $_BACKUP_DIR -a ! -x $_BACKUP_DIR ]
then
    echo "mkdir $_BACKUP_DIR"
    mkdir $_BACKUP_DIR
    if [ $? -ne 0 ]
    then
        echo "Error : mkdir $_BACKUP_DIR" >&2
        exit 1;
    fi
fi

if [ ! -d $_LOG_DIR -a ! -x $_LOG_DIR ]
then
    echo "mkdir $_LOG_DIR" 
    mkdir $_LOG_DIR
    if [ $? -ne 0 ]
    then
        echo "Error : mkdir $_LOG_DIR" >&2
        exit 1;
    fi
fi

# 기간이 만료된 백업 삭제
find $_BACKUP_DIR -type f -name "${_BACKUP_FILE}_*" -mtime +$_EX_DAY -exec rm -f {} \;

# 백업 시작
_LOGGING "SVN BACKUP START!"

killall svnserve >> $_LOGFILE 2>&1
if [ $? -eq 0 ]
then
    _LOGGING "SVN SERVICE STOP SUCCESS!"
else
    _LOGGING "WARNING! SVN SERVICE NOT RUNNING."
    #exit 1;
fi

ps -ef | grep -v grep | grep "svnserve -d" >> $_LOGFILE 2>&1
if [ ! $? -eq 1 ]
then
    _LOGGING "WARNING! DETECT SVNSERVE PROCESS."
    #exit 1;
fi

#tar -cf - $HOME/svnrepo | gzip -c - > ${_BACKUP_DIR}/${_BACKUP_FILE}_${_DATE}.tar.gz
if [ $? -eq 0 ]
then
    _LOGGING "SVN BACKUP SUCCESS!"
else
    _LOGGING "WARNING! SOME PROBLEM IN BACKUP JOB."
    exit 1;
fi

_LOGGING "SEND TO REPOSITORY!"
scp ${_BACKUP_DIR}/${_BACKUP_FILE}_${_DATE}.tar.gz  svn@dev2:~/BACKUP/.
if [ $? -eq 0 ]
then
    _LOGGING "SEND SUCCESS!"
else
    _LOGGING "WARNING! FAIL TO SEND BACKUP."
    #exit 1;
fi

svnserve -d -r /home/svn/svnrepo
if [ $? -eq 0 ]
then
    _LOGGING "SVN SERVICE START SUCCESS!"
else
    _LOGGING "WARNING! FAIL TO START SVN SERVICE."
    #exit 1;
fi
_LOGGING "SVN BACKUP END!"

저장소 장비에서는 특정 기간이 만료된 백업을 제거하는 쉘을 수행해야 한다.

_EX_DAY=7
_BACKUP_DIR=$HOME/BACKUP
_BACKUP_FILE=svn_backup

# 일주일이 지난 백업 삭제
find $_BACKUP_DIR -type f -name "${_BACKUP_FILE}_*" -mtime +$_EX_DAY -exec rm -f {} \;

이제 crontab에 등록해보자. crontab에 최빈시에 백업이 수행되도록 등록만 하면 된다. 사내 장비는 아직 특별한 것이 없으므로 임의로 새벽 1시에 수행되게 설정하였다.

0 1 * * * ~/BACKUP/svn_backup.sh

대개의 경우 내부망이라면 telnet과 ftp를 이용하겠지만 보안상의 이유로 혹은 기타의 이유로 내부망인데도 불구하고 ssh와 sftp를 써야하는 경우가 있다.(대외망은 아마도 대부분 telnet과 ftp를 사용하지 못할 거라 생각한다.)
이전에 ftp를 이용한 자동화에는 .netrc를 이용해서 자동화를 했는데(물론 .netrc를 사용한다는 것은 내 계정정보를 그냥 공개한다고 보면 된다.) sftp를 써야 하기 때문에 이런 기존의 자동화 방법을 적용할 수 없었다.
ssh, sftp 그리고 scp 등의 secure 툴(이 3가지 외에는 생각나는게 딱히 없다.)은 rsa를 이용해서 보안 로그인을 허용한다.
위의 .netrc를 이용하는 것보다는 훨씬 보안이 뛰어나다(라고 알고있다...;;).

먼저 제반사항으로는 당연히 secure 접속이 가능한 장비가 준비되어야 한다. ssh 설치 방법 등은 이 글에서 다루지 않는다.

sshd의 설정파일(/etc/ssh/sshd_config)에서 아래 부분을 수정한다. 기본적으로는 막혀있는 듯하다.
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

다음으로 접속하는데 쓸 rsa 키를 만들어보자.

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fhan/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/fhan/.ssh/id_rsa.
Your public key has been saved in /home/fhan/.ssh/id_rsa.pub.

어디에 저장할지와 추가적인 보안키를 입력 받는데 필요없으면 입력하지 않아도 된다.
이제 $HOME/.ssh/id_rsa.pub 파일이 생겼다. 이 파일을 상대방의 장비에 authorized_keys란 이름으로 넣어주면 준비가 끝난다.
$ scp ~/.ssh/id_rsa.pub fhan@dev:~/.ssh/authorized_keys
이렇게 한 뒤에 scp를 다시 수행하면 패스워드를 물어보지 않는다. 혹 패스워드를 물어본다면 .ssh경로나 authorized_keys 파일의 권한을 700, 600으로 조정해보면 되기도한다.