그누보드 5의 이메일 기능 사용하기

Posted by taeho Tae-Ho
2016.01.20 13:00 Web/DB/Dev

게시판을 모아둔 웹사이트를 구축할 때 많이 사용되는 무료게시판 중에 그누보드(GNUBOARD)라는 게시판 솔루션이 있습니다. 저도 애용하는 게시판 소스 중 하나인데요. 이 그누보드는 메일발송 기능까지 포함고 있습니다. 내부적으로는 PHPMailer라는 메일발송 라이브러리를 연동하여 제공하는 기능이죠.


그누보드의 이메일 사용 설정


이 그누보드의 메일발송기능은 다음과 같이 그누보드의 관리자 페이지에서 설정할 수 있습니다.




위 설정화면에서 처럼 회원가입한 사람이 있으면 등급설정을 위해 관리자에게 회원가입 신청이 있음을 알려주는 설정을 비롯해 글쓴이에게 댓글이 작성되었음을 알려주는 등 다양한 용도로 메일 발송기능을 사용할 수 있습니다.


하지만 위 화면에서 메일 발송 기능을 사용하도록 설정한다고 하여 바로 메일이 발송되는 것은 아닙니다.


그누보드의 소스파일 중 일부를 수정해주어야 합니다. 보다 쉽게하기 위해 환경설정을 통해 설정이 되도록 그누보드의 기능을 개선하면 좋겠지만 몇몇 이유로 인해 그렇게까지 기능을 제공하지는 않습니다. 때문에 IT를 전공하고 약간의 이메일서버의 개념과 동작원리를 이해해야만 수정할 수 있습니다.


그누보드의 SMTP(Mail Server) 설정

앞에서 설명한 그누보드의 메일 보내기 기능 사용 설정은 그누보드가 "어느 메일서버에 어떤 계정으로 접속하여 메일을 보낼지"를 알려주어야 제대로 동작합니다.


여기에서 사용되는 메일 서버는 다음이나 네이버 혹은 구글 등 SMTP 기능을 제공하는 다양한 메일서버를 사용할 수 있습니다. (SMTP에 대한 설명은 생략합니다.)


또한 SMTP 설정 시 SSL 설정과 Plain Text 방식 중 하나를 사용할 수 있는데 이 포스트에서는 다음이나 구글, 네이버 등에서 요구하는 SSL(암호화통신프로토콜)을 사용하는 메일 설정과 SSL을 요구하지 않는 Plain Text 방식을 사용할 때의 설정을 모두 설명합니다.


그누보드의 메일서버 주소와 계정 설정은 lib 디렉토리의 mailer.lib.php 파일에서 하게됩니다.

mailer.lib.php 파일에서 mailer() 함수를 찾아 다음과 같이 수정해줍니다. 그누보드라 하더라도 버전에 따라 약간씩 소스가 달라 위치가 다를 수 있습니다.


먼저 plain text 방식의 메일발송을 지원하지 않고 ssl을 요구하는 메일서버에서 설정방식입니다. 다음, 구글등이 해당됩니다. 포트번호도 다르다는 점에 주의해주세요.


function mailer($fname, $fmail, $to, $subject, $content, $type=0, $file="", $cc="", $bcc="") 

{

    global $config;

    global $g5;


    // 메일발송 사용을 하지 않는다면turn;

    if (!$config['cf_email_use']) return;


    if ($type != 1)

        $content = nl2br($content);


    $mail = new PHPMailer(); // defaults to using php "mail()" 

    if (defined('G5_SMTP') && G5_SMTP) {

// Modified By taeho. 2015.12.31, 메일을 보낼 때 메일서버에 접속하기 위한 설정입니다.

        $mail->IsSMTP();

        $mail->SMTPAuth  = true;                  // enable SMTP authentication

        $mail->SMTPSecure = "ssl";                // sets the prefix to the servier

        $mail->Host      = "smtp.daum.net";      // sets GMAIL as the SMTP server

        $mail->Port      = 465;                  // set the SMTP port for the GMAIL server

        $mail->Username  = "다음아이다@hanmail.net";  // MAIL username

        $mail->Password  = "비밀번호";            // MAIL password

        // End. By taeho. 20151231           


    }


    $mail->From = 'noreturn@hanmail.net';   // 사용자에게 보여줄 보내는이 메일주소

    $mail->FromName = 'taeho BBS';  // 사용자에게 보여줄 보내는 사람의 이름 등

    $mail->Subject = $subject;

    $mail->AltBody = ""; // optional, comment out and test

    $mail->MsgHTML($content);

    $mail->AddAddress($to);

        $mail->AddAddress($to);

    if ($cc)

        $mail->AddCC($cc);

    if ($bcc)

        $mail->AddBCC($bcc);

    //print_r2($file); exit;

    if ($file != "") {

        foreach ($file as $f) {

            $mail->AddAttachment($f['path'], $f['name']);

        }

    }

    return $mail->Send();


다음은 plain text를 지원하는 표준 메일서버의 설정입니다.

function mailer($fname, $fmail, $to, $subject, $content, $type=0, $file="", $cc="", $bcc="")

{

    global $config;

    global $g5;


    // 메일발송 사용을 하지 않는다면

    if (!$config['cf_email_use']) return;


    if ($type != 1)

        $content = nl2br($content);


    $mail = new PHPMailer(); // defaults to using php "mail()"

    if (defined('G5_SMTP') && G5_SMTP) {

        $mail->IsSMTP(); // telling the class to use SMTP

        $mail->Host = 'mail.company.kr'; // SMTP server

        $mail->SMTPAuth = true;

        $mail->Username = 'taeho@company.kr';

        $mail->Password = '비밀번호';

    }

    $mail->From = 'noreturn@company.kr';

    $mail->FromName = 'Library Server';

    $mail->Subject = $subject;

    $mail->AltBody = ""; // optional, comment out and test

    $mail->MsgHTML($content);

    $mail->AddAddress($to);

    if ($cc)

        $mail->AddCC($cc);

    if ($bcc)

        $mail->AddBCC($bcc);

    //print_r2($file); exit;

    if ($file != "") {

        foreach ($file as $f) {

            $mail->AddAttachment($f['path'], $f['name']);

        }

    }

    return $mail->Send();

}


표준 SMTP 메일서버의 경우 Port 번호를 명시하지 않아도 됩니다. 포트번호가 명시되지 않으면 표준 SMTP 포트번호인 25번이 자동으로 설정됩니다.


주의사항

프로그래밍을 할 때 절대 삼가해야할 점은 소스코드에 ID와 Password를 하드코딩하지 말아야 한다는 점입니다. 하지만 무료 소스이다보니 위의 사례들 처럼 비밀번호를 소스코드에 그대로 노출시키게 되는 경우가 있습니다. 만약 이 서버에 접속 권한이 있는 개발자나 운영자가 이 비밀번호를 유출시킨다면 큰 피해로 이어질 수 있기 때문에 매우 주의해야 합니다.


RedCastle과 같은 파일접근통제 솔루션을 이용해 개발자나 운영자가 telnet, ssh, ftp 등의 접속을 통해 이 소스파일을 읽지 못하도록 조치한다면 최소한의 보안은 가능하지만 그 이외의 경우... 이 파일에 대한 접근을 통제하기는 매우 어렵다는 점을 항상 유의해야 합니다.


신고
이 댓글을 비밀 댓글로
  1. 무료보드에 참 기능이 많아서 저도 과거에 이용해본 경험이 있습니다 메일도 쉽게 연계가 가능하군요^^
    • 그누보드엔 참 많은 기능이 있습니다. 그중에서 특별히 활용하는게.. 메일기능과 여분필드 정도네요.. ^^ 개발능력이 부족하거든요.. ^^

CentOS 6.6 Final에 PostgreSQL 9.3 설치하기

Posted by taeho Tae-Ho
2015.11.16 13:03 Web/DB/Dev

CentOS와 RedHat은 기본적으로 MySQL과 PostgreSQL 같은 RDBMS의 온라인 설치를 지원한다. CentOS와 RedHat이 설치된 서버가 인터넷에 연결되어 있다면 바로 yum 명령을 이용하여 MySQL이나 PostgreSQL을 설치할 수 있다.


그런데 CentOS 6.6 Final DVD를 이용해 CentOS를 설치하고 yum을 이용해 postgreSQL을 설치하게 되면 기본적으로 8.x 버전의 postgreSQL이 설치된다. 하지만 최신은 아니더라도 비교적 최근의 버전을 설치할 일이 생겨버렸다.


그래서 구글링을 해본 결과 다음과 같은 방법으로 상위버전의 postgreSQL의 설치가 가능했다.


CentOS 6.6 Final에 PostgreSQL 9.3 설치하기

먼저 리눅스의 버전확인. 커널버전 2.6.32-504가 6.6 Final 이다. 그리고 64bit 커널이다.

[root@localhost lib]# uname -a

Linux localhost.localdomain 2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

다음과 같이 postgresql 사이트에서 yum의 리포지토리를 업그레이드하는 rpm을 다운받아 설치한다.


[root@localhost lib]# rpm -Uvh http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-redhat93-9.3-1.noarch.rpm

http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-redhat93-9.3-1.noarch.rpm(을)를 복구합니다

경고: /var/tmp/rpm-tmp.jMiE5n: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY

준비 중...               ########################################### [100%]

   1:pgdg-redhat93          ########################################### [100%]

[root@localhost lib]# 


정상적으로 완료되었다면 yum을 이용해 postgreSQL 패키지를 다운 받는다.

[root@localhost lib]# 

[root@localhost lib]# yum install postgresql93-server postgresql93

Loaded plugins: fastestmirror

Setting up Install Process

Loading mirror speeds from cached hostfile

 * base: centos.mirror.cdnetworks.com

 * extras: centos.mirror.cdnetworks.com

 * updates: centos.mirror.cdnetworks.com

pgdg93                                                                                     | 3.7 kB     00:00     

pgdg93/primary_db                                                                          | 126 kB     00:00     

Resolving Dependencies

--> Running transaction check

---> Package postgresql93.x86_64 0:9.3.10-1PGDG.rhel6 will be installed

--> Processing Dependency: postgresql93-libs = 9.3.10-1PGDG.rhel6 for package: postgresql93-9.3.10-1PGDG.rhel6.x86_64

--> Processing Dependency: libpq.so.5()(64bit) for package: postgresql93-9.3.10-1PGDG.rhel6.x86_64

---> Package postgresql93-server.x86_64 0:9.3.10-1PGDG.rhel6 will be installed

--> Running transaction check

---> Package postgresql93-libs.x86_64 0:9.3.10-1PGDG.rhel6 will be installed

--> Finished Dependency Resolution


Dependencies Resolved


===================================================================================

 Package                          Arch                Version                          Repository           Size

===================================================================================

Installing:

 postgresql93                     x86_64              9.3.10-1PGDG.rhel6                pgdg93              1.0 M

 postgresql93-server              x86_64              9.3.10-1PGDG.rhel6                pgdg93              4.1 M

Installing for dependencies:

 postgresql93-libs                x86_64              9.3.10-1PGDG.rhel6                pgdg93              193 k


Transaction Summary

====================================================================================

Install       3 Package(s)


Total download size: 5.3 M

Installed size: 21 M

Is this ok [y/N]: y

Downloading Packages:

(1/3): postgresql93-9.3.10-1PGDG.rhel6.x86_64.rpm                                          | 1.0 MB     00:03     

(2/3): postgresql93-libs-9.3.10-1PGDG.rhel6.x86_64.rpm                                     | 193 kB     00:00     

(3/3): postgresql93-server-9.3.10-1PGDG.rhel6.x86_64.rpm                                   | 4.1 MB     00:07     

-----------------------------------------------------------------------------------

Total                                                                             451 kB/s | 5.3 MB     00:12     

Running rpm_check_debug

Running Transaction Test

Transaction Test Succeeded

Running Transaction

Warning: RPMDB altered outside of yum.

** Found 1 pre-existing rpmdb problem(s), 'yum check' output follows:

redcastle-4.0.3-1.x86_64 has missing requires of /usr/lib/librclog.so()(64bit)

  Installing : postgresql93-libs-9.3.10-1PGDG.rhel6.x86_64                                                    1/3 

  Installing : postgresql93-9.3.10-1PGDG.rhel6.x86_64                                                         2/3 

  Installing : postgresql93-server-9.3.10-1PGDG.rhel6.x86_64                                                  3/3 

  Verifying  : postgresql93-9.3.10-1PGDG.rhel6.x86_64                                                         1/3 

  Verifying  : postgresql93-server-9.3.10-1PGDG.rhel6.x86_64                                                  2/3 

  Verifying  : postgresql93-libs-9.3.10-1PGDG.rhel6.x86_64                                                    3/3 


Installed:

  postgresql93.x86_64 0:9.3.10-1PGDG.rhel6             postgresql93-server.x86_64 0:9.3.10-1PGDG.rhel6            


Dependency Installed:

  postgresql93-libs.x86_64 0:9.3.10-1PGDG.rhel6                                                                   


Complete!

[root@localhost lib]#

디펜던시까지 알아서 체크하고 libs도 자동으로 다운받아 설치해준다.


설치된 패키지 확인. (postfix는 아니다.)

[root@localhost lib]# rpm -qa | grep post

postfix-2.6.6-6.el6_5.x86_64

postgresql93-9.3.10-1PGDG.rhel6.x86_64

postgresql93-libs-9.3.10-1PGDG.rhel6.x86_64

postgresql93-server-9.3.10-1PGDG.rhel6.x86_64

[root@localhost lib]# 


postgreSQL의 데이터베이스를 초기화한다. 초기 데이터베이스와 시스템카다로그가 생성된다.

[root@localhost lib]# 

[root@localhost lib]# /etc/init.d/postgresql-9.3 initdb

데이타베이스를 초기함:                                     [  OK  ]

[root@localhost lib]# 


이제 완료다. PostgreSQL을 구동한다.

[root@localhost bin]# /etc/init.d/postgresql-9.3 start

postgresql-9.3 서비스를 시작하고 있습니다:                 [  OK  ]

[root@localhost bin]# 


설치되고 구동된 PostgreSQL의 상태와 버전을 체크한다.

여기까지 정상이라면 OK..!!

신고
이 댓글을 비밀 댓글로

워드프레스 회원가입 이메일 인증 설정하기

Posted by taeho Tae-Ho
2015.09.21 16:00 Web/DB/Dev

워드프레스(Wordpress)는 대표적인 설치형 블로그 솔루션이다. 하지만 워드프레스는 블로그는 물론 게시판이나 홈페이지로 까지 변형이 가능할 만큼 유연한 구조를 갖고 있으며 실제로 다양한 플러그인과 테마를 통해 매우 다양한 형태의 홈페이지를 만들 수 있도록 해준다. 게다가 워드프레스는 회원가입을 받을 수 있도록 해주는 플러그인도 지원된다. 그리고 오늘 설명할 회원가입에 대한 이메일 인증 설정은 블로그를 운영하면서 친한 이웃이나 정보를 공유하기 위한 소수의 멤버들을 모아 회원제로 운영할 때 이메일 주소를 확인할 수 있는 이메일 플러그인도 지원한다.


워드프레스 회원 가입 양식

워드프레스는 설치형 블로그 툴이면서도 기본적으로 아래와 같이 회원가입을 할 수 있는 기능을 지원한다.



[사용자명]에 사용할 ID를 입력하고(이메일주소를 ID로 쓸 수도 있다) 

아래 창에 [이메일] 주소를 입력한 뒤 "등록하기" 버튼을 클릭하면 입력한 이메일 주소로 인증메일이 보내지고 인증 메일에 포함된 URL을 클릭하면 비밀번호를 설정하는 방식으로 운영될 수 있다.


하지만 이메일 인증 플러그인을 설치하고 SMTP를 설정해주지 않으면 가입 인증용 이메일이 보내지지 않는다.


워드프레스 이메일 플러그인 설치 및 활성화

워드프레스의 설정 화면에 들어가면 [플러그인] 메뉴가 보인다. [플러그인 추가하기]를 선택하여  키워드 검색란에 "wp-mail-smtp"를 입력하여 검색하면 아래와 같이 Mail 플러그인이 표시된다. [설치]를 클릭하여 설치한다.



wp-mail-smtp 설정

wp-mail-smtp 플러그인을 설치한 뒤 [설치된 플러그인] 메뉴에 가 보면 아래화면 처럼 WP-Mail-SMTP 플러그인이 설치된 플러그인 목록에 보인다. [활성화]를 클릭하여 활성화 하면 [비활성화]로 바뀐다.  화면에 표시된 것 처럼 [비활성화] 메뉴가 보이면 활성화 된 것이다.



그리고 [Settings] 를 클릭하여 회원 가입 인증 메일을 보낼 때 사용할 SMTP 메일 서버 설정창을 실행시킨다.



위의 각 입력항목을 설명하면...


[From Mail] 메일을 보내는데 사용할 보내는 사람 메일주소를 입력한다. 

[From Name] 보내는 사람의 이름이다. 실명이 아니어도 무관하며 일반적으로 사이트에서 사용할 관리자의 닉네임 정도를 입력하면 된다.

[Mailer] 메일을 보낼 메일 클라이언트 프로그램 선택 정도 되는 메뉴다. 어떤 항목이 될지는 SMTP 서버 특성에 따라 다르다. 내 경우 다음메일로 테스트를 해봤는데 아래의 php mail() function을 선택해야 메일이 정상적으로 보내졌다.

[Return Path] 회신 메일 관련 설정인데...그냥 체크해주었다.

[SMTP Host] 보내는 메일 서버 주소다. 이 주소는 각 메일 포털이나 메일서버의 SMTP 주소를 입력하면 된다. 다음 메일(한메일)의 경우 화면에 보이는 값이다. (smtp.daum.net)

[SMTP Port] 보내는 메일 서버의 포트번호다. 이 번호도 메일 포털이나 메일서버의 설정에 따라 맞춰줘야 한다. 위 화면의 포트번호는 다음 메일서버의 포트다.

[Encryption] 암호화 여부다. 마찬가지로 메일서버 설정에 따라줘야 한다.

[Authentication] 메일 발송 시 인증여부다. 메일을 보낼 때 인증이 없으면 해당 서버는 스팸메일 발송지로 악용될 가능성 100%다. 그래서 대부분의 메일 포탈이나 메일서버는 메일 발송 시 보내는 사용자에 대한 인증을 필수적으로 요구한다. 당연히 Yes를 선택해야 할 것이다.

[Username] / [Password] 보내는 메일서버의 인증 ID와 비밀번호다. 위의 경우 다음 메일을 사용하는 사용자의 ID와 비밀번호를  입력한다. 다음 메일 ID 입력시는 ID만 넣고 @hanmail.net 과 같은 도메인 주소는 넣지 않는다.


모두 입력했다면 [변경 사항 저장]을 클릭하여 설정을 저장한 뒤 [send test]나 실제 계정을 등록해 인증메일이 발송되는지 확인한다.


회원 가입 테스트

아래와 같이 워드프레스 회원 가입 양식을 실행하여 사용자 명과 이메일 주소를 입력 한 뒤 [등록하기]를 클릭한다.

그러면 입력한 메일 주소로 회원 가입 인증 메일이 보내진다.



구글 메일에 들어가 수신된 가입 인증 메일을 확인한 것이다. 아래 화면처럼 URL이 발송되어 온다. 인증 URL을 클릭한다.


인증 URL을 방문해보면 아래와 같이 비밀번호를 설정하는 화면이 표시된다. [새 비밀번호]에 도저히 외울 엄두가 안나는 비밀번호를 추천하는데... 모두 지우고 본인이 사용할 비밀번호를 입력하면 된다. 그리고 [비밀번호 초기화]를 클릭하면 회원 가입과 인증 그리고 비밀번호 설정이 완료된다.



비밀번호 설정 후 가입 완료된 화면이다.



이제 가입된 회원은 기본적으로 [구독자] 권한으로 가입된다. 관리자가 워드프레스 사용자 관리 기능을 이용해 글쓰기 등의 권한을 별도로 부여해주면 된다.

신고
이 댓글을 비밀 댓글로

postgreSQL의 Tablespace 에 대한 이해

Posted by taeho Tae-Ho
2015.07.23 11:44 Web/DB/Dev

시스템엔지니어 일을 하면서 종종 DB를 접하게 된다. IT바닥에 뛰어 든 초기에 개발과 DB를 접하고 특히나 Ingres라는 RDBMS를 제법 깊게 공부했던지라 DB와 SQL에 대해서는 일반적인 엔지니어들 보다 이해도가 높다. 덕분에 이런 저런 시스템SW와 보안솔루션들이 DB를 사용할 때 빠르게 구조를 이해하고 감사로그나 수집된 데이터에 대해 직접 DB에 접속하여 SQL을 통해 분석하고 레포팅할 수 있다.


DB와 DBMS

프로세스와 프로세서를 정확하게 개념적으로 구별하지 못하는 엔지니어가 많듯... db와 dbms를 구별하지 못하는 엔지니어도 많은게 현실이다. DB는 DBMS에 의해 저장된 데이터 객체 중 가장 큰 객체를 의미한다. DBMS는 사용자 프로세스와 DB 사이에서 인터페이스 역할을 수행하는 프로세스와 메모리의 집합체다. 


DB(Database)에는 다양한 데이터 객체들이 존재한다. 그리고 DB는 아래의 객체들이 저장되어 있는 파일의 집합체다. (때론 파일이 아닌 Raw Device 인 경우도 있다.) 


이 포스트에서는 학문적인 관점에서의 추상적인 객체 개념이 아닌 실제 상용으로 사용되는 DB의 물리적인 객체에 대해 설명하므로 참고하길 바란다.


1. 시스템카달로그 (System Catalog)


DB의 기본적인 설정 값들이 저장되어 있는 시스템카다로그(테이블의 일종)에는 DB의 경로와 DB사용자 정보와 접근권한 그리고 데이터가 저장되는 테이블에 대한 속성과 인덱스에 대한 정보 등 DBMS가 데이터를 저장하고 조회하고 관리하는데 필요한 핵심적인 데이터가 저장된다. 


2. 테이블(Table)


실제 데이터가 저장되는 객체가 테이블이다. 테이블은 컬럼(Column)과 행(row)로 이루어져 있는 표와 같다고 생각하면 된다. DBMS는 SQL(Standard Query Language)이라는 언어로 사용자 프로세스와 대화하며 테이블 이름과 컬럼 이름을 기준으로 DB에서 데이터를 조회하고 삽입하고 수정하고 삭제한다.


3. 인덱스(Index)


테이블에는 사용자프로세스에서 입력하는 순서대로 행(로우)가 순차적으로 증가한다. 엑셀과 같은 표문서에서 데이터를 저장하면서 행이 증가하는 것과 같다. 따라서 검색시에 특정 행을 찾기 위해서는 첫번째 행부터 표 전체를 검색해야 한다. 당연히 검색 속도가 느릴 수 밖에 없다. 이러한 검색 속도 문제를 해결하기 위해 검색 조건에 많이 사용되는 컬럼, 즉 사람이라면 주민번호, 전화번호, 이름 등의 컬럼을 내림차순, 올림차순에 따라 정리해 놓은 검색을 위한 표가 바로 인덱스다. 

인덱스가 많을 수록 좋을 것 같지만 데이터가 추가(insert) 될 때 인덱스도 함께 생성하고 경우에 따라서는 정리도 해주어야 하기 때문에 인덱스의 생성은 신중해야 한다. 테이블 생성 시 Primary Key를 지정하는 경우가 많은데 이또한 인덱스의 일종이다.


4. 뷰(View)


뷰는 실제로 데이터가 저장되지 않는 논리적인 테이블이다. 두개의 테이블에 모두 존재하는 데이터를 별도의 테이블로 만들고 싶을 때 View를 생성하면 된다. View는 SQL의 select 문을 이용해 정의되어 시스템카다로그에 저장된다. 뷰도 논리적으로는 테이블이기 때문에 테이블의 이름과 뷰의 이름이 중복될 수 없다.


4. 프로시저(Procedure)


트리거 혹은 DBMS 자체에서 지원하는 4GL언어 (예를 들면 PL/SQL 혹은 T-SQL) 또는 사용자프로세스에서 호출할 수 있는 일종의 사용자 정의 함수다. DBMS 자체에서 지원하는 4GL 언어 또는 C언어 등의 언어와 SQL이 혼합되어 작성되며 시스템카달로그에 저장된다. 대부분 여러 사용자 프로세스 혹은 트리거에서 많이 사용되는 절차를 프로시저로 정의해 놓고 호출하여 사용한다. DBMS에 의해 관리되기 때문에 미리 컴파일(Pre-Compile)되어 있고 개발언어 독립적이라는 장점이 있다.


5. 트리거(Trigger)


쉽게 이해하기 위해서는 트리거를 일종의 이벤트 라고 생각하면 된다. 즉 "특정 테이블에 특정 값이 입력될 때 어떤 프로시저를 호출해라"와 같이 이벤트와 처리루틴을 정의하는 것을 말한다. 사용자 프로세스에서 모든 처리를 수행할 수 있으나 여러 사용자 프로세스에서 공통으로 처리해야 하는 프로시저 중에서 "이벤트"기반으로 처리해야할 내용들을 트리거로 지정하는 경우가 많다.


DB의 가장 대표적인 객체 5가지의 개념에 대해 살펴보았다.


다음은 DBMS다. DBMS는 Database Management System이다. 우리말로 쓰자면 데이터베이스 관리 시스템이다. 예전에 DBMS 기술지원 일을 할 때는 DB와 DBMS를 엄격히 분리하여야 했지만 보안이나 시스템소프트웨어 관련 일을 하면서 궂이 분리해야할 필요를 느끼지는 못한다. DB와 DBMS가 운영체제보다도 더 전문적인 지식을 필요하다보니 특히나 보안 분야에서 일하는 분들은 이 둘을 구별해야할 필요를 전혀 느끼지 못하고 있다.


DBMS 중에서 가장 많이 쓰이는 Oracle이나 MySQL , MS-SQL 그리고 PostgreSQL은 기본적으로 RDBMS다. 여기서 R은 Relational(관계형)를 의미한다. 즉, 테이블에 저장되는 데이터들이 관계를 맺고 있고 이 관계에 따라 가공되고 표현됨을 의미한다. 이 관계형에 대한 설명은 다음을 참고하면 좋다. (커드의 12가지 규칙)


모든 DBMS는 접속관리자(Connection Manager),SQL 파서(Parser), 쿼리 옵티마이저(Query Optimizer), 트랜잭션 관리자(Transaction Manager), DB관리자(Database Manager)  등으로 불리는 프로세스들로 구성된다. 제품에 따라 개수는 다르지만 하나의 프로세스로 구성되어 동작하지 않고 여러개로 분리되어 각각의 역할을 수행하도록 만들어져 있다.


여기까지는 DB와 DBMS에 대한 기본적인 이해를 위한 내용이었고 이제 본론인 Tablespace로 넘어간다.


PostgreSQL에서의 Tablespace (테이블스페이스)

Tablespace는 일부 DB에서 등장하는 개념이다. 오라클과 PostgreSQL에서만 사용되고 MySQL과 MS-SQL 같은 DBMS에서는 언급조차 되지 않는 개념이다. 


하지만 PostgreSQL에서 DB는 PGDATA라는 환경변수에 지정된 디렉토리를 통째로 DB로 사용한다. 그리고 그 하위에 테이블이 파일로 생성된다. 즉 테이블스페이스를 따로 생성하지 않아도 DB에 사용자 테이블을 만들 수 있다. 기본적으로 DB로 지정된 디렉토리 전체가 하나의 기본 테이블스페이스로 인식되는 것이다. 


PostgreSQL 공식사이트에서는 다음과 같이 테이블스페이스를 정의하고 있다.


포스트그레스-큐엘에서 테이블스페이스는 DB관리자에 의해 데이터베이스의 객체가 저장될 수 있는 파일시스템의 경로로 정의된다. 테이블스페이스가 생성되면 데이터베이스 객체에 객체를 생성할 때 이름에 의해서 테이블스페이스가 참조될 수 있다.


포스트그레스-큐엘이 설치될 때 디스크레이아웃에 따라 관리자가 생성할 수 있는데 두가지 관점에서 매우 유용하다. 첫번째는 DB가 생성된 볼륨 또는 파티션에 여유공간이 부족할 때 테이블스페이스를 다른 파티션이나 디스크에 생성하여 시스템을 재구성할 때까지 DB를 확장할 수 있다. 또 다른 하나는 데이터베이스 객체의 성능 최적화를 위해 사용할 수 있다는 것이다. 예를 들어 매우 사용량이 많으면서 자주 업데이트 되는 인덱스를 위해 고성능 SSD를 장착하고테이블스페이스를 생성하여 인덱스를 SSD에 생성하여 성능을 개선하는데 사용될 수 있다.


만약 물리적으로 다른 경로를 DB에 사용하고자 할 때 테이블스페이스로 지정하여 DB를 확장할 수 있다. 테이블 스페이스는 다음과 같은 DDL 문으로 생성할 수 있으며 해당 테이블스페이스에 태이블을 생성할 수 있다.


CREATE TABLESPACE fastspace LOCATION '/ssd/mydb2/data';


CREATE TABLE emp(empno int, name varchr(12)) TABLESPACE fastspace;


DB에 생성되어 있는 테이블스페이스의 정보를 확인하고 싶을 때는 다음의 SQL 문으로 생성되어 있는 테이블스페이스 정보를 확인할 수 있다.


SELECT * FROM pg_tablespace;



그리고 PostgreSQL의 대화형 질의 도구인 psql 을 사용하면 \db;  명령으로도 확인할 수 있다.



신고
이 댓글을 비밀 댓글로
  1. 좋은글 감사합니다.
  2. 도움이 많이 되었습니다 >_<
  3. 정리가 잘된 좋은글 잘 읽고 갑니다. 감사합니다.

PostgreSQL 설치와 DB 만들기 (CentOS 6.6)

Posted by taeho Tae-Ho
2015.07.22 13:27 Web/DB/Dev

직장생활을 처음 시작하고 처음으로 한 일은 개발이었다. PC에서 Access와 비주얼베이직, 델파이 등을 이용해 혼자 공부하던 SQL을 직장에서 본격적으로 공부하기 시작했다. 그리고 개발에서 엔지니어로 방향을 튼 뒤 처음 접한 것이 바로 Ingres 라는 RDBMS다. 


그리고 이 Ingres의 증손자(?)뻘 되는 PostgreSQL을 오늘 설치하고 테스트 해야할 일이 생겼다. PostgreSQL은 Post Ingres라는 의미도 갖고 있다고 하니 감회가 새롭다. (PostgreSQL은 포스트그레스-큐엘 이라고 읽는다.)


각설하고... 설치 과정과 DB 생성까지를 남긴다. 


1. yum을 이용한 PostgreSQL 설치

postgress는 postgresql의 공식 사이트인 http://www.postgresql.org/에서 소스를 다운받아 직접 컴파일하여 설치할 수도 있지만 일단 테스트니 yum을 이용해 설치했다.


root 계정에서 yum install postgresql-server 명령을 실행해 설치 한다.



당연히 인터넷에 연결되어 있어야 하고 DNS 설정도 제대로 되어 있어야만 리포지토리로 지정된 서버를 찾을 수 있다.


정상적으로 리포지토리를 찾으면 다음과 같이 설치할 패키지를 보여준다. 만약 설치되어 있지 않다면 updates가 아닌 install이라고 표시된다. 현재 8.4.20 버전이 설치될 것임을 보여준다.


Is this ok 에 y 로 응답하면 설치(업데이트)를 시작한다.



2. 계정 확인

mysql과 같은 DB는 일반적으로 root에서 설치하고 실행하는 경우가 많다. 하지만 DB가 root로 구동된다는 것은 보안 관점에서 많은 취약점을 노출시킨다. 그래서 Postgres는 root에서 실행하는 것을 매우....싫어한다.


때문에 앞에서와 같이 postgresql을 설치하면 postgres를 실행할 계정을 만들어 준다. /etc/passwd 파일을 확인해보면 다음과 같이 postgres 계정이 만들어져 있다.



postgresql 을 초기화하고 구동하려면 이 postgres 계정으로 로그인해야 한다. 때문에 postgres 계정의 비밀번호를 설정해주어야 한다. passwd 명령을 통해 비밀번호를 설정하고 ssh 또는 telnet을 재접속한다. 당연히 postgres 계정으로 로그인 해야 한다.


3. 데이터베이스 생성 경로 지정

PostgreSQL을 초기화하고 구동하기 위해서는 몇가지 설정이 필요하다. 그중에서 가장 중요한 것은 데이터베이스를 어디에 생성할 것인가? 이다.


데이터베이스의 생성 경로는 postgresql을 실행하는 계정의 환경변수에 지정하도록 되어 있다. 기본적으로 postgres 계정으로 구동하게 되므로 해당 계정의 환경변수에 설치 시 기본경로가 자동으로 설정되어 있다. postgres 계정의 홈디렉토리는 /var/lib/pgsql 이며 이 디렉토리의 .bash_profile 파일이 프로파일이다.


이 .bash_profile은 다음과 같이 확인할 수 있다.



.bash_profile에는 PGDATA 환경변수를 설정하는 내용이 포함되어 있다. 이 PGDATA라는 환경변수가 바로 postgreSQL의 DB가 생성되는 경로를 갖고 있는 환경변수이며 postgreSQL을 구동할 때 DB경로를 별도로 지정하지 않으면 이 변수의 경로를 DB경로로 지정하여 구동된다.

이 변수는 다음과 같이 env 명령으로 확인할 수 있다. (bash, ksh의 경우)



만약 DB의 경로를 다른 디스크나 디렉토리로 변경하고 싶다면 .bash_profile의 PGDATA 경로를 원하는 경로로 변경해준 뒤 다시 로그인하면 된다.그리고 이 경로의 변경은 반드시 initdb를 실행하기 전에 하는 것이 좋다. 후에 변경하려면... 좀 복잡해질 수 있다.


4. initdb 실행

initdb는 postgreSQL 설치 후 시스템카달로그를 포함하고 있는 postgres 기본 DB를 생성하는 명령어다. 이 기본DB는 postgres 라는 이름으로 생성되며 이 기본 DB 생성 후 psql과 같은 대화형 명령어를 실행한 뒤 CREATE DATABASE 명령을 통해 사용자가 사용할 DB를 생성하게 된다.



5. PostgreSQL 서버 실행

PostgresSQL 서버를 다음과 같이 실행한다. 


1. postgres 계정으로 로그인 (ssh 혹은 telnet)


2. pg_ctl start 명령 실행



3. 구동상태 확인


ps -ef | grep post 명령으로 확인.



보통 -D 옵션과 DB명을 주라고 하는데 PGDATA 환경변수의 경로에 DB가 있다면 궂이 DB명을 표시하지 않아도 된다. 


6. 사용자 DB 생성

db를 생성하기 위해서는 psql 이라는 도구를 실행하고 psql 내에서 CREATE DATABASE 쿼리문을 이용해 생성한다.



psql 명령에도 DB경로를 지정하는 옵션이 있는데 이 옵션은 하나의 서버에 물리적인 여러개의 DB서버를 운용할 때 필요한 옵션이다. 이 이야기는 initdb를 서로 다른 경로에 2번 이상 했을 경우(2개 이상의 인스턴스 운용)에만 운용하면 된다.


-- 끝~~~~ --






신고
이 댓글을 비밀 댓글로
    • 2016.04.06 22:33
    비밀댓글입니다
    • ㅎㅎ 그러게요~~ 딴생각하며 썼나봅니다~
      수정했습니다~

저용량 메모리 환경에서 mysql 튜닝기 (My Book Live 3TB - MySQL 환경)

Posted by taeho Tae-Ho
2015.03.15 15:32 Web/DB/Dev

디지털 IT 기기들이 생활 속 깊이 파고들면서 옛날 같으면 종이 문서와 사진으로 남겨질 수 많은 일상의 흔적들이 디지털 정보로 노트북이나 컴퓨터 혹은 외장하드에 쌓여가고 있다. 하지만 이렇게 남겨진 디지털 정보들은 언제든지 순간의 실수 혹은 저장 기기들의 고장으로 사라져버리기 쉬운 것도 사실이다. 


My Book Live 3TB (이하 MBL)

그래서 구입한 것이 3 Tera Byte 저장 공간을 갖고 있는 NAS 장비인 My Book Live다.



MBL을 구입한 뒤 제일 먼저 한 것은 MySQL DB를 설치한 일이다. 그리고 그누보드를 설치해 게시판까지 쓸 수 있도록 했다. 그런데 문제가 발생했다. 워낙 CPU가 저-사양이니 속도가 느린 것은 이해하겠지만 수시로 메모리 부족으로 웹서버가 Hang 되는 현상이 발생했다.


이 MBL의 CPU와 메모리는 다음과 같은 사양을 갖고 있다.



문제가 되는 것은 Memory다. 그나마 128MB가 아닌 것이 다행일 지경이다.

웹서버인 Apache가 동작을 거부(?)하는 상황에서 CPU와 RAM 상태를 보면 다음과 같다.



Memory 여유분이 12480KByte이고 Swap을 440832KByte(440M)나 사용한다. 램이 256인데 440을 쓰다니.. -.- 어떤 상황인지 통 알 수가 없다. 하지만 256 MByte의 대부분을 Apache와 Mysql이 사용하는 것은 자명하다. 위 화면에는 표시되지 않았지만 mysql이 메모리를 왕창차지하고 일하기를 거부하고 있었다.


그래서 Mysql을 튜닝해보기로 했다.


저용량 메모리 환경에서 MySQL 튜닝 - my.cnf

관계형 DBMS의 하나인 Mysql은 여타 DBMS들과 마찬가지로 많은 메모리를 사용한다. 하지만 MySQL의 전통적인 관계형 DB엔진인 myisam의 경우 튜닝여부에 따라 저용량 메모리(RAM)를 가진 기기에서도 구동이 가능하다. 이는 MyISAM 엔진이 page level locking과 row level locking을 지원하지 않고 Table Level Locking만을 지원하고 Transaction 개념을 지원하지 않기 때문이다. Transaction 개념을 지원하지 않는다는 것은 commit과 rollback 등을 사용할 수 없다는 것을 의미한다. (MyISAM 이후에 지원하는 InnoDB 엔진은 이 개념들을 모두 지원한다.)


하지만...


그런 여러 고급 기술들을 지원하지 않기 때문에 작은 메모리를 가진 NAS 기기에서도 구동이 가능한 장점(?)을 갖게 됩니다.


MySQL을 튜닝하기 위해서는 /etc/mysql/my.cnf 파일의 내용을 이해해야 한다. (위치는 설치 환경에 따라 다를 수 있다.)

하지만... 그 개념들을 하나씩..하나씩 이해하면서 튜닝하기에는 시간도 노력도 투자하기가 쉽지 않다. 그렇다면?? 이미 남들이 만들어 놓은 my.cnf에서 필요한 항목을 따다~~쓰면 된다.


우리나라의 검색엔진인 Naver나 Daum에서는 그런 정보들을 찾기 쉽지 않지만 Google 에서는 그러한 정보를 찾을 수 있었다. 역시..구글..!!


그리하여 찾은 my.cnf의 내용은 다음과 같다. MySQL 파일의 내용 중 아래에서 진하게 표시된 부분만 덮어 쓰면 된다.


[mysqld]

#

# * Basic Settings

#

user            = mysql

pid-file        = /var/run/mysqld/mysqld.pid

socket          = /var/run/mysqld/mysqld.sock

port            = 3306

basedir         = /usr

datadir         = /var/lib/mysql

tmpdir          = /tmp

language        = /usr/share/mysql/english

skip-external-locking

#

# Instead of skip-networking the default is now to listen only on

# localhost which is more compatible and is not less secure.

bind-address            = 127.0.0.1

#

# * Fine Tuning

key_buffer_size         = 16M

max_allowed_packet      = 1M

table_open_cache        = 64

sort_buffer_size        = 512K

net_buffer_length       = 8K

read_buffer_size        = 256K

read_rnd_buffer_size    = 512K

myisam_sort_buffer_size = 8M


#if no other servers are going to be connecting to this server, uncomment the following line

#bind-address            = 127.0.0.1


skip-innodb

default-storage-engine = MyISAM


max-connections = 25


query-cache-size  = 2M

query-cache-limit = 1M


thread-stack      = 256K

thread-cache-size = 2M


slow-query-log

long_query_time   = 5


[mysqldump]

quick

max_allowed_packet = 16M


[mysql]

no-auto-rehash


[myisamchk]

key_buffer_size  = 20M

sort_buffer_size = 20M


일부 내용은 수정되기 전과 동일한 값이 설정되어 있을 수 있다.


이렇게 설정한 뒤 MySQL을 재구동하거나 리부팅하면 된다.


이 값을 설정한 뒤 또 문제가 생기면 일부 값들을 다시 튜닝해보려 했으나... 3일 째 문제 발생 없이 잘 돌고 있다.



Memory는 게시판에 업로드 하거나 하면 90% 이상으로 사용량이 증가하지만 Swap을 사용하지는 않는다. Swap을 사용하기 시작하면 기기의 성능은 급격하게 떨어지기 시작한다.


신고
이 댓글을 비밀 댓글로
  1. mysql 유용하게 이용될때가 많은데 튜닝등에 많은 참고가 될듯 합니다 환절기 건강 유의하시고 좋은 한주 되세요 ^^
    • 무슨 문제인지는 몰라도... 4일만에.. mysql이 다운됐습니다. mysql로그에도... 서버의 message 로그에도 에러가 기록되진 않네요.. 수행되는 sql과 데이터 특성까지 봐야하는 건지..
      256 램에서 그누보드와 일정관리까지 돌리는 건 무리일 듯 싶기도 하네요.
  2. 역시...구글에 공감하며...ㅎㅎ
    오늘은 날씨가 참 좋습니다.
    행복한 봄날 보내세요!
  3. 음. 모니위키같은 위키위키엔진은 어떠신가요. mysql과 같은 dbms를 안쓰는것으로 알고 있습니다. (파일시스템기반)
    아니면 sqllite 를 사용할 수 있는 CMS를 찾아보시는것도 나쁘지 않은 선택으로 보입니다.

그누보드5에 포함된 네이버 스마트에디터 사용법 및 에디터 높이 변경 방법

Posted by taeho Tae-Ho
2015.02.26 11:26 Web/DB/Dev

게시판과 같은 글쓰기 기능이 포함된 웹페이지를 만들 때 가장 간단한 방법은 HTML 태그 중에서 <textarea></textarea>을 사용하는 것이다. 하지만 이 태그는 너무도 단순해서 HTML 코드나 이미지 첨부 또는 폰트 크기나 색상의 변경 등을 처리할 수 없는 단점이 있다. 그래서 사실상 거의 사용되지 않는다고 보는 것이 좋다.

그누보드5(GNUBOARD5) 베타에 포함되어 있는 CKEditor

그 대안으로 사용되는 것이 CKEditor와 같은 javascript로 만들어진 에디터다. 아래 화면은 내가 개발해 사용 중인 프로젝트 및 일정관리 시스템의 일정 등록 화면이다. 수행업무 내역을 입력하는 노란색 상자 내부가 CKEditor다. 게시판으로 함께 사용중인 그누보드5(beta)에 CKEditor가 포함되어 있어서 그 CKEditor를 그대로 사용했다.



위 화면의 소스를 들여다 보면 <textarea></textarea>가 존재하며 <textarea>태그에 id와 name 속성을 지정하고 아래에서 해당 id를 가진 textarea 객체를 javascript로 만든 에디터 객체로 대체(?)하는 형태를 띄고 있다.


<!-- 글쓰기 기능을 가진 페이지의 <header></header>부분에 아래 포함

<!-- 아래는 그누보드 5(beta)의 CKEDITOR를 사용하기 위한 설정 -->

<script src= "/plugin/editor/ckeditor4/ckeditor.js"></script>

<script>

var g5_editor    = "ckeditor4";

var g5_editor_url = "/plugin/editor/ckeditor4";

</script>

<!-- 그누보드5(beta)에 설치된 CKEDITOR를 사용하는 설정 -->


<!-- 실제 글쓰기 부분에서는 아래 처럼 사용 -->

<tr>

<td>내용</td>

<td colspan=3><textarea name="desc" id="desc" class="ckeditor" wrap="VIRTUAL">

수행업무내역을 상세히 입력합니다.

</textarea>

<script language="javascript">

    /* 그누보드5(beta)의 CKEditor 에디터설정을 그대로사용할 때... */

var editor=CKEDITOR.replace('desc'); 

</script>


</td>

</tr>


이런 에디터를 사용하면 본문에 이미지를 첨부하거나 표를 만들어 넣거나 또는 제목 등을 표시하는 것이 가능하다. 간단한 문서편집기 기능을 수행하기 때문이다. 


이 CKEditor는 <textarea></textarea> 태그에 rows 속성과 cols 속성을 주면 크기 설정이 자동으로 되어 편리했다.


그누보드5 정식버전에 포함되어 있는 네이버스마트에디터2.0


하지만 그누보드5 정식버전에는 CKEditor가 아닌 Naver에서 개발하여 무료로 배포하고 있는 SmartEditor 가 포함되어 있다. CKEditor보다 조금 더 무겁긴 하지만 사용자 입장에서 익숙하고 조금 더 스마트하기 때문에 많이 사용되고 있다. 2015년 2월 20일 경 다운로드 받은 그누보드5.0.30에는 2.3 버전이 포함되어 있다.


앞의 프로젝트 일정관리 화면의 CKEditor를 Naver SmartEditor2 버전으로 교체한 화면이다.



CKEditor 보다 조금 더 깔끔한 스타일을 보여준다. 물론 CKEditor의 스킨을 더 스마트한 버전으로 교체하면 동일한 수준으로 사용할 수 있다.


이 네이버 스마트에디터도 <textarea></textarea> 객체를 대체하는 형식으로 만들어져 있기에 소스수준에서의 적용방법은 거의 동일하다. 다만 Naver SmartEditor의 경우 <textarea></textarea> 태그의 cols 속성은 동작하나 rows 속성은 제약이 있다. 스마트에디터의 최소 높이가 소스 내부적으로 고정되어 있어 일정 높이 이하로 높이를 줄일 수 없게 되어 있다.

위 화면의 Naver SmartEditor2의 사용 예제 소스를 보면 다음과 같다.


<!-- CKEditor와 마찬가지로 페이지의 <head></head>에 다음의 내용을 추가

<!-- 아래는 그누보드 5의 SmartEditor2를 사용하기 위한 설정 추가로 설정할 필요없음. -->

<script type="text/javascript" src="/plugin/editor/smarteditor2/js/HuskyEZCreator.js" charset="utf-8"></script>

<script language="javascript">

var g5_editor    = "smarteditor2";

</script>

<!-- 그누보드5에 설치된 SmartEditor2를 사용하는 설정 -->



<!-- 실제 쓰기 기능을 가진 페이지의 textarea 태그 부분에 다음내용 추가 -->

<tr>

<td>내용</td>

<td colspan=3><textarea name="desc" id="desc"  class="smarteditor2" style="width:100%;height:220px; display:none;">

수행업무내역을 상세히 입력합니다.

</textarea>

    <!-- 네이버 스마트에디터2 적용 부분 시작-->

<script src="/plugin/editor/smarteditor2/js/HuskyEZCreator.js"></script>

<script>var g5_editor_url = "/plugin/editor/smarteditor2", oEditors = [];</script>

<script src="/plugin/editor/smarteditor2/config.js"></script>

<script>

function submitContents(elClickedObj) {

oEditors.getById["desc"].exec("UPDATE_CONTENTS_FIELD", []); // 에디터의 내용이 textarea에 적용됩니다.

// 에디터의 내용에 대한 값 검증은 이곳에서 document.getElementById("ir1").value를 이용해서 처리하면 됩니다.

try {

elClickedObj.form.submit();

} catch(e) {}

</script>

    <!-- 네이버 스마트에디터2 적용 부분 끝.-->

</td>

</tr>

<!-- CKeditor와는 달리 다음과 같이 Submit 부분에 onclick 이벤트 추가 -->

<tr>

<td colspan=4><center><input type=submit value="저장하기" onclick="submitContents(this)"><input type="reset" name="reset" value="취소" onClick="window.close();"> </center></td>

</tr>


네이버 스마트에디터 2.0의 에디터 최소 높이 조정

네이버 스마트에디터는 소스 내부적으로 최소 높이가 지정되어 있다.그래서 그 높이를 최소 높이 이하로 줄이려고 <textarea></textarea> 의 rows 속성이나 style의 height를 아무리 줄여도 일정 높이 이상으로는 줄일 수 없다. 만약 이 높이를 줄이려면 에디터의 최소 높이 즉 높이를 지정하지 하지 않을 경우의 기본 높이를 변경해 주어야 한다.


이 스마트에디터의 최소 높이는 SE2BasicCreator.js 파일에 htDimension의 nMinHeight 값으로 지정되어 있다.

var htDimension = {

nMinHeight:220,

nMinWidth:parseInt(elIRField.style.minWidth, 10)||570,

nHeight:elIRField.style.height||elIRField.offsetHeight,

nWidth:elIRField.style.width||elIRField.offsetWidth

};


위와 같이 220으로 변경하면 에디터의 초기 높이 기본값이 변경된다.


만약 에디터의 높이를 더 높이고자 한다면 <textarea></textarea>의 style 에서 height를 220px 보다 크게 주면 된다.


이 네이터 스마트에디터의 높이를 조정하는 방법을 알아내는데...꼬박...하루(8시간 정도)가 걸렸다.

난..웹 개발자의 소양은 갖추지 못한 모양이다. 

웹 개발은 너무 어렵다.


신고
이 댓글을 비밀 댓글로
  1. 직접 개발해서 사용중이신 프로젝트및
    일정 관리 시스템이 멋집니다.^^
    좋은 하루 보내세요!

그누보드5 게시판의 첨부파일 용량 제한과 관련된 PHP 설정

Posted by taeho Tae-Ho
2014.05.22 09:13 Web/DB/Dev

요즘은 게시판 위주의 홈페이지를 만들기가 무척 편해졌다. 제로보드XE나 그누보드(GNUBOARD)를 아파치와 PHP 그리고 Mysql 환경에 설치하면 여러 게시판을 가진 포탈스런(?) 홈페이지를 뚝딱~만들 수 있다.


아래 화면은 그누보드(GNUBOARD5)를 이용해 한나절만에 만든 게시판 위주의 자료실 홈페이지다.



ATOM CPU(D510??으로 기억)달린 2G 메모리의 4년쯤된 컴에 레드햇 6.3을 깔고 (웹서버로) 보니 mysql이 없어서 yum의 리포지토리로 레드햇CD를 등록한 뒤 yum을 이용해 mysql을 설치했다.


yum을 이용해 mysql을 설치하면 의존성을 자동으로 체크하여 의존적인 패키지를 함께 설치해주기 때문에 무척 편리하다. 일일히 의존성 체크해가며 설치하자면 하루도 더 걸릴 듯... -.-


하지만 yum을 사용하여 리눅스 설치 CD의 패키지를 설치하려면 그냥은 안되고 yum에서 설치 cd를 리포지토리로 사용하도록 설정해 주어야 한다. 리눅스 (redhat, centos)의 설치 cd를 yum 리포지토리에 추가하는 방법은 유명하신 스누피님 블로그에서 찾아볼 수 있다. (여기)


아파치, PHP, MYSQL의 설치가 완료되면 게시판을 선택하여 설치한다. (여기서는 설명하지 않는다.)


게시판 소스을 설치하고 나면 게시판을 생성하여야 하는데 일반 글과 작은 이미지 파일 정도를 업로드 하는데는 별 문제가 없지만 제안서나 브로셔 등 사이즈가 10M 이상되고 그런 파일들을 10개 까지 업로드 하려 하면 많은 문제가 발생한다.


아파치는 DOS공격이나 DDOS 공격을 방어하기 위해 하나의 서버사이드스크립트(php, jsp 등)가 한번에 실행될 수 있는 시간을 제한하거나 웹페이지에 접속하고 아무런 후속 요청이 없으면 세션 타임아웃이 발생해 접속이 끊어지도록 되어 있다. 그 외에도 대용량 파일을 게시판에 업로드 할 때 사용되는 세션의 메모리나 시간, 파일 크기 등을 여러 파라미터를 통해 조정을 해줘야 원활하게 자료실 형태의 게시판으로 운영할 수 있다.


먼저 조정해줘야 할 것은 게시판 자체의 파일 업로드 크기 제한이다.

아래 이미지는 그누보드5의 업로드 파일 크기 제한 설정 화면이다.



기본적으로 1M Byte로 되어 있었는데 10M 바이트로 늘린 화면이다. 하나의 게시물에 여러개의 파일이 올라가도 각각 개별적인 파일의 크기만 제한한다. 즉 위처럼 설정되어 있다면 10M 파일을 여러개 업로드 할 수 있다. 이 설정은 게시판~마다 설정해줘야 한다.


하지만 이 설정만 변경해서는 용량이 큰 파일을 업로드할 수는 없다.

다음은 php.ini 파일에서 업로드 파일 관련 설정을 변경해주어야 한다. php.ini는 /etc 디렉토리에 있다.



먼저 file_uploads가 On으로 되어 있어야 하며

upload_max_filesize를 원하는 용량으로 변경해주면 된다. 위의 설정은 한번의 파일 업로드 즉 하나의 php 스크립트가 실행되면서 해당 세션에서 업로드할 수 있는 용량을 의미한다.


만약 아파치서버의 임시디렉토리가 포함된 파일시스템의 용량이 작다면(일반적으로 /tmp) upload_tmp_dir을 설정할 필요도 있다.


다음은 php.ini에서 post 메소드 실행 시 사용할 수 있는 메모리 제한값을 설정해 주어야 한다.



그누보드의 경우(대부분 그럴 것으로 보임) 파일을 업로드 하면 POST 메소드로 전송이 되는데 이때 업로드하는 파일의 크기만큼 POST로 전송되는 메시지가 커진다. 이 설정도 보안과 관련이 있지만 게시판의 기능인 자료실 용도이니 만큼 제한을 작게 할 수는 없다. 아펭서 파일의 업로드크기 제한을 100M로 했으므로 POST 시 사용할 수 있는 메시지의 크기도 100M보다 커야한다. 


위에서는 128M로 설정했다. 왜 100이 아니고 128이냐고 묻는다면 8의 배수 그리고 16의 배수, 32의 배수, 64의 배수로 설정해주는게 습관이 돼서라고 이야기 해주겠다.


그리고 메모리 관련 설정이 또 하나가 있다. (제약이 참 많기도 하다.) 앞에서 POST 메소드에서 사용할 수 있는 메모리를 설정해 주어도 PHP 스크립트 하나에서 사용할 수 있는 메모리 제약이 걸려있기 때문에 post_max_size 보다 아래의 memory_limit 가 작다면 의미가 없다.


아래 처럼 post_max_size인 128M 보다 크거나 같게 설정한다.



이제 업로드 파일의 용량과 업로드 시 사용되는 웹서버 측의 메모리 제약에 대한 설정은 모두 변경하였다.


하지만 이것만 설정해선 또 오류가 발생할 수 있다. 파일을 업로드 하는 것은 하나의 PHP 스크립트 파일이 아파치 대몬에 의해 실행되는 것이다. PHP에선 하나의 스크립트가 실행될 수 있는 최대 시간도 제한이 걸려 있다. 만약 100M의 업로드에 제약이 걸린 시간보다 오랜 시간이 소요된다면 timeout 오류가 발생할 수 있다. 이 문제를 예방하기 위해 하나의 php 스크립트가 실행될 수 있는 최대 실행시간 즉, max_execution_time 을 변경해준다.



60초 이내에 100M 바이트의 파일 업로드가 완료되어야 한다. 만약 시간이 부족하다면 더 늘려주면 된다. 단위는 초다.


이제 아파치 대몬을 재구동하고 파일 업로드를 해보라..

잘 되는가?? ^^



신고
이 댓글을 비밀 댓글로

티스토리(태터툴즈)에서 워드프레스로 블로그 이사하기

Posted by taeho Tae-Ho
2013.09.17 15:56 Web/DB/Dev

블로그를 운영하는 블로거에게 최대의 숨겨진 고민(?)은 블로그가 설치된 서버가 내것이 아니라는 것이다. 블로그를 운영한 시간이 길면 길 수록 블로그에 올려져 있는 포스트들은 자식과 같이 느껴져서 블로그가 없어지는 것을 상상하는 것은 너무도 끔찍한 일이다. 게다가 워낙 많은 포스트 탓에 하나씩 하나씩 다른 블로그로 이사하는 것 조차 불가능한 블로거는 지금 운영하고 있는 블로그 서비스가 문을 닫으면 완전..!! 낙동강 오리알 신세가 될 수 밖에 없다.


하지만 티스토리는 다르다. 티스토리는 소스가 오픈된 오픈소스 블로그이기 때문에 몇몇 다른 블로그로 이사가 가능하다.


예전에 올린 포스트(티스토리 블로그를 설치형 블로그인 태터툴즈(TextCube)로 이사하기) 처럼 별도의 호스팅서비스에 태터툴즈를 설치하고 데이터를 복구하면 똑같은 쌍둥이 블로그를 만들 수 있다. 이것은 티스토리가 오픈소스 블로깅 시스템인 태터툴즈에 기반하였기 때문에 가능한 일이다.


하지만 태터툴즈, 현재 텍스트큐브로 불리는 설치형 블로그는 개발이 중단된 상태다. 텍스트큐브를 개발하던 회사가 구글에 인수되면서 개발이 중단되었기 때문이다. 그래서 티스트로리를 떠난다 해도 개발이 중단된 텍스트큐브의 마지막 버전을 사용해 블로그를 새로 만들기는 조금 찜찜하다.


그래서 찾아본 것이 바로 최근 가장 많은 사용자를 확보하고 있는 워드프레스로의 데이터 이전 방법이다. 워드프레스는 국산 설치형 블로그는 아니지만 전세계적으로 가장 많은 블로거를 확보하고 있는 설치형 블로그로서 텍스트큐브처럼 오픈소스이기 때문에 수 많은 자발적으로 스킨이나 플러그인을 개발하는 개발자들을 확보하고 있다.


자..본론으로 들어가자. 


먼저 티스토리에서 데이터를 백업 받고 워드프레스가 설치된 서버에 FTP를 이용해 업로드 해 두어야 한다.백업은 앞선 포스트에서 설명하였으므로 생략한다. ^^


그리고 워드프레스를 설치해야 한다. 워드프레스 한글판은 이곳에서 다운로드 받아 설치하면 된다. 설치 과정 또한 어렵지 않으며 다른 곳에 설치 방법이 잘 소개되어 있으므로 생략한다~ ^^


1. TTXML 플러그인 다운로드 


워드프레스가 설치되어 있다면 TTXML 이라는 워드프레스의 플러그인을 다운받아야 한다. 

다운로드 주소는 이곳이다. [  http://wordpress.org/plugins/ttxml-importer/installation/  ]


2. TTXML 플러그인 업로드


다운로드 받은 TTXML 플러그인을 워드프레스에 설치하기 위해서는 zip 파일을 압축해제하고 FTP를 이용해 업로드를 해야한다.


먼저 압축을 해제한다. 폴더이름을 살려서 압축을 푼다.


압축을 해제하였으면 FTP접속하여 다음과 같이 워드프레스의 설치 경로아래의 wp-content/plugins 디렉토리에 ttxml-importer 와 같이 폴더 통채로 업로드를 한다.


3. TTXML 모듈 활성화


ttxml 임포터를 plugins 디렉토리에 복사해 넣었으면 워드프레스의 플러그인에 ttxml이 보이게 된다. 이 ttxml을 활성화 시킨다.

위의 화면 처럼 플러그인 설정화면에서 TTXML을 활성화를 클릭하면 비활성화 버튼으로 바뀌어 보인다. 비활성화 라고 표시되어 있다면 활성화 된 것이다.


4. 티스토리 백업 XML 파일 임포트


TTXML 플러그인이 정상적으로 활성화 되면 도구 메뉴 화면에 TTXML이 보인다.    


다음과 같이 서버에 업로드한 티스토리의 백업 XML 파일 위치를 입력한다.

PC에 XML을 저장해두고 업로드하게 되면 캐릭터셋 문제 혹은 XML파일의 전송 중 특수문자 깨짐 현상 등으로 인해 제대로 복구가 안될 수 있다. 가장 좋은 방법은 서버에 FTP를 이용하여 업로드하고 위의 그림처럼 로컬의 경로를 직접 지정해주는 방법이다. 나의 경우 205 MByte 짜리의 XML 백업파일이 정상적으로 복구되는 것을 확인할 수 있었다.


위의 그림에서 "제출" 버튼을 누르면 다음과 같이 복구되는 과정을 속~시원하게 보여준다.


5. 티스토리에서 워드프레스로 블로그 이사 완료.


이렇듯 오픈소스의 개방성과 호환성은 상용툴들의 그것에 비할바가 아니다. 하지만 다음에서 인수한 티스토리의 경우 기술지원이나 서비스의 중단은 쉽게 발생하지는 않을 것이다. 인터넷의 대부분의 컨텐츠가 블로거들에 의해 블로그에서 생산되고 전파된다. 최근 SNS가 커뮤니케이션 수단으로 각광받고 있지만 주요 컨텐츠들은 블로거들에 의해 생산되어 블로그에 저장되는 것이 일반적이다. 따라서 다음이 티스토리를 버릴 가능성은 매우 희박하다고 생각된다. 당연히 티스토리의 서비스도 지속될 것이다.


하지만 혹시 모를 불상사에 대비하거나 독립형 블로그의 유혹이 강해질 때를 대비해서 워드프레스로의 블로그 이사를 테스트해보았고 성공적으로 이사가 가능함을 알게되었다. 이제 열심히 주기적으로 블로그를 백업해두기만 하면 된다.


신고
이 댓글을 비밀 댓글로
  1. 안녕하세요
    궁금한 게 있는데요,

    티스토리에서 블로그 API 와 백업 기능을 12월 16일 부로 없앴는데요,
    해서 워프로 이사하는 데 위와 같은 방식으로 진행하기가 까다로워졌습니다.
    혹시 백업이 가능하던 시절 xml 마크업을 공유받을 수 있을까요

    지금은 게시글 가져오기가 단일포스팅에 한해서만 가능해서 약 100개의 글을 가져온다는 가정하에
    100개의 xml 을 다운받아, 취합해서 위와 같은 방식으로 워프에 import 할 생각인데요

    어떤 마크업으로 취합해서 워프관리자에서 import 할 수 있는지 궁금합니다.
    감사합니다.
    • 아...백업 받아놓은 데이터를 찾아봐야겠네요. URL을 이용해 포스트를 가져오고 해당 XML 마크업으로 변환해 저장한 뒤 워드프레스에서 불러오는 방식으로 이사하시려는 건가요? 프로그래밍도 할 줄 아신다면 좋은 방법이 될지도 모르겠네요.
    • 빠른 답변 감사드립니다.

      네 말씀 하신 방법으로 진행하려는데
      글이 1800개가 넘어서 가능할 지 모르겠네요..
      일단 시도는 해보려구요
      성공하면 포스팅과 댓글로 알려드리겠습니다.
      혹시 백업 데이터가 있으시다면 마크업만 공유부탁드립니다 ^^
    • 이메일 주소 보내주시면...백업받아두었던 파일에서 샘플링해서 보내드릴께요~
      • 2016.12.30 21:06
      비밀댓글입니다

getElementById()가 크롬에서 동작하지 않는 경우 체크할 것

Posted by taeho Tae-Ho
2013.06.02 16:44 Web/DB/Dev

조그마한 웹페이지를 하나 만들어도 Internet Explorer와 Chrome, Firefox 등 여러 브라우저에서 정상적으로 동작하는지를 검토해야하고 게다가 모바일에서까지 잘 동작하는지 체크하고 안되면 수정하는 것은 많은 웹개발자들에게 큰 어려움이다.

어쩌다 한번 웹 소스를 수정하는 나에게도 이건 정말 욕나오는 시추에이션이다.

오늘도 그런 일이 하나 있었다. 그런데 이 경우는 엄밀하게 이야기해서 "나의 실수"였지만 그 실수를 유발하는 것은 다름아닌 Microsoft의 IE였다.

뭔고하니 바로 자바스크립트에서 웹페이지상에 생성된 객체(select box, text box 등)를 조회하여 해당 객체를 리턴해주는 getElementById() 함수의 동작방식이다.

아래와 같은 소스가 있다.

<script language=javascript>

function dateupdate()

{

var target = document.getElementById("order");

iudate=target.value;

opener.location.href="request_issuedate_update.php?rqid=<? echo $rqid; ?>&updatedate=" + iudate + "&olddate=<? echo $udate ?>";

window.close();

}

</script>

<body>

<br>

<table border=1 width=250>

<tr>

<td>이슈 기한/요청일자</td>

</tr>

<tr>

<td><input type=text name=order size="15" maxlength="15" value="<? echo $udate; ?>" readonly>

</td>

</tr>

<tr>

<td><br><input type=button value="변경하기" onClick="dateupdate();"></input></td>

</tr>

</table>

위의 소스는 IE9.0에서 잘 실행된다. 하지만 Chrome 브라우저에서는 에러가 발생한다. 그 이유를 찾는데 두 시간 여가 걸렸다. 이 얼마나 시간낭비인가? 그리고 그 이유는 아주 단순한데 있었다. 이유가 뭔고하니...

getElementById() 함수는 객체의 ID를 기준으로 Document에 있는 객체를 찾는다... 그런데 <input type=text name=order size....> 의 order 입력상자는 name은 갖고 있지만 ID는 갖고 있지 않다. 때문에 크롬에서는 동작하지 않고 getElementByID() 함수가 null 을 리턴한다.

하지만 IE에서는 이상하게도 위의 소스가 에러없이 동작한다. 추측하건데 ID가 지정되지 않았으면 name 키워드로 찾아주는 불필요한 센스(?)를 갖고 있는 것 같다. 

언뜻볼때 ID가 없으면 알아서 객체의 name으로 찾아주는 MS의 친절함 같겠지만 이런 과잉친절은 절대 있어서는 안된다. 왜냐하면 IE는 Java Script가 실행되는 운영체제의 역할을 수행한다. 하지만 Java Script는 IE, Chrome, Firefox 등 다양한 브라우저(가상플랫폼) 위애서 소스의 수정없이도 정상적으로 실행되도록 "엄격한" 규칙의 준수가 필요하기 때문이다.

위의 소스는 다음과 같이 두줄이 수정되어야 IE와 Chrome 두 브라우저에서 동일하게 정상적으로 실행된다.

<script language=javascript>

function dateupdate()

{

var target = document.getElementById("closedate");

iudate=target.value;

opener.location.href="request_issuedate_update.php?rqid=<? echo $rqid; ?>&updatedate=" + iudate + "&olddate=<? echo $udate ?>";

window.close();

}

</script>

</head>

<body>

<br>

<table border=1 width=250>

<tr>

<td>이슈 기한/요청일자</td>

</tr>

<tr>

<td><input type=text name=order id="closedate" size="15" maxlength="15" value="<? echo $udate; ?>" readonly>

</td>

</tr>

<tr>

<td><br><input type=button value="변경하기" onClick="dateupdate();"></input></td>

</tr>

</table>



신고
이 댓글을 비밀 댓글로