2017년 5월 31일 수요일

MySQL table로부터 DDL 추출하기





Database의 DB table이 생성되어 있을 때 이들 table 생성시 사용했던 DDL(Data Definition Language)를 보고 싶을 경우가 있다.
한마디로 이미 생성되어 있는 DB table들의 DDL을 뽑아내는 방법에 대한 것이다.

명령어 구문은(MySQL에 접속한 상태에서)

mysql> show create table 테이블명;

mysql> show create table kkk;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                             |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| kkk   | CREATE TABLE `kkk` (
  `bdid` bigint(11) unsigned NOT NULL,
  `name` varchar(80) NOT NULL,
  PRIMARY KEY (`bdid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

kkk라는 테이블을 생성한 DDL 구문이다.

여기서 ENGINE의 종류는 InnoDB이다. MySQL의 경우 2가지 엔진 타입이 있는 InnoDB와 MyISAM이 있다.
InnoDB의 경우는 빈번한 쓰기, 수정, 삭제가 발생할 경우 유리하고
MyISAM은 InnoDB에 비해 상대적으로 성능이 높은 편인데 주로 읽기 위주의 처리에 높은 성능을 발휘한다.
반면에 MyISAM은 빈번한 쓰기, 수정, 삭제가 발생하는 경우라면 오히려 InnoDB보다 성능이 못하다고 한다.
정답은 상황에 맞게...

여기서 또 한가 주목할 부분은 DEFAULT CHARSET=latin1을 되어 있다.
이럴 경우 한글을 insert할 때 에러가 발생한다.
이 문제에 대한 해법은 다음 링크 참조.

default charset과 한글 입력 문제 바로가기

2017년 5월 26일 금요일

apache 포트 변경 및 웹 루트 변경하기





apache 포트 변경 및 웹 루트 변경하기

(1) CentOS

CentOS의 경우 apache 포트 번호 변경은 
/etc/httpd/conf/httpd.conf 파일을 열어서

Listen 80

과 같이 되어 있는 번호를 원하는 포트 번호로 변경하면 된다.
변경 후 apache를 재구동해 준다.

# service httpd restart

웹 루트 디렉토리 변경
/etc/httpd/conf/httpd.conf 파일을 열어서

DocumentRoot "/var/www/html"

과 같이 되어 있는 부분을 원하는 경로로 변경해 주면 된다. 다음과 같이..

DocumentRoot "/var/www/myhome"

변경 후 apache를 재구동해 준다.

# service httpd restart


(2) Ubuntu

우분투의 경우 apache 포트 번호 변경은

/etc/apache2/ports.conf 파일에서 

Listen 80

으로 되어 있는 부분을 원하는 포트 번호로 변경하면 된다.
변경 후 apache를 재구동해 준다.

# service apache2 restart

웹 루트 디렉토리 변경은
/etc/apache2/sites-available/000-default.conf 파일을 열면

DocumentRoot /var/www/html

과 같이 되어 있을 것이다. 디폴트 웹 루트 디렉토리이다. 이 디렉토리에 index.html과 같은 웹 페이지를 작성해 두면 http://xxx.xxx.xxx.x/index.html로 접근하는 경로이다.
그런데 /var/www/html을 /var/www/myhome으로 변경하고자 한다면
DocumentRoot /var/www/myhome으로 변경한 후 apache를 재 구동해 주면 된다.

# serivce apache2 restart

2017년 5월 17일 수요일

mysqlimport명령어를 이용하여 로컬의 텍스트 파일이나 dump파일을 MySQL db의 table에 값 저장하기





mysql의 table을 생성할 때 로컬의 특정 파일이 담고 있는 내용을 table의 값으로 저장해야하는 경우가 있다.
이때 로컬의 특정 파일은 dump 파일 일수도 있고, 일반적인 txt 파일 일수도 있다.

test.txt에 ,로 구분되어 다음과 같은 내용이 담겨 있다고 하면

홍길동,남,010-1234-4567,YES
장길동,여,011-0123-1111,NO
...

이 내용을 mysql의 특정 table의 내용으로 저장하는 작업을 할수도 있다.


혹은 로컬의 특정 파일의 내용이 다음과 같이 |로 필드의 값이 구분되어 있다고 할 경우

12      |       74109    |
30      |       29        |
36      |       184914  |
37      |       42        |
46      |       39        |
67      |       32033   |
76      |       155892  |
77      |       74311   |
79      |       74313   |
80      |       155892 |
90      |       34102   |
91      |       34103   |
.....

이럴 경우 mysqlimport 명령어를 이용하면 된다.

mysqlimport -uroot -p --local --fields-terminated-by="|" yyy  merged.dmp

여기서 -uroot는 mysql 사용자 계정의 id가 root라는 뜻이고 -p옵션은 mysql 사용자 계정의 비번을 입력하겠다는 것이다.
이 경우는 비번을 입력하지 않으면 위의 명령어를 실행할 때 비번을 묻게 된다.

--local 옵션을 주지 않으면 로컬 파일인 merged.dmp를 읽지 못하고 다음과 같은 에러를 발생 시킨다.

mysqlimport: Error: 13, Can't get stat of '/var/lib/mysql/yyy/merged.dmp' (Errcode: 2 - No such file or directory), when using table: merged

이 에러는 DB 명으로 입력한 yyy를 디렉토리 경로로 인식하는 문제다.

그 다음 옵션인 --fields-terminated-by="|"는 table저장할 데이터가 들어 있는 merged.dmp의 내용이 위에서 보는바와 같이 |를 기준으로 필드의 값이 구분되어 있다.
따라서 필드 구분자를 지정해 줘야 한다. 만일 ,로 구분되어 있다면 --fields-terminated-by=","와 같이 하면된다.

그다음 옵션인 yyy는 Database 이름이다. yyy라는 데이터베이스 안에 merged라는 table에 merged.dmp가 가지고 있는 내용을 table의 각 레코드와 필드에 값을 저장하게 된다.
이때 만일 다음과 같은 에러가 발생할 것이다.

mysqlimport: Error: 1290, The MySQL server is running with the --secure-file-priv option so it cannot execute this statement, when using table: merged

이 에러는 보안 상의 이유로 특정 디렉토리에 있는 파일에 대해서만 위의 명령어를 실행할수 있도록 설정되어 있다는 뜻이고 그 특정 디렉토리가 어느 곳인지를 알려면

mysql -u사용자id -p사용자비번

으로 들어가서

mysql>show variables like 'secure%';

를 실행하면

+------------------+--------------------------+
| Variable_name    | Value             |
+------------------+--------------------------+
| secure_auth      | ON                  |
| secure_file_priv  | /aaa/bbb/ccc/     |
+------------------+---------------------------+

와 같은 정보가 나올 것이다. 이것은 /aaa/bbb/ccc/라는 디렉토리에서만 mysqlimport로 특정 파일의 내용을 mysql db의 table에 값을 저장할수 있다는 뜻이다.

만일 secure-file-priv 자체를 off 시키고 싶다면
우분투의 경우 /etc/mysql/mysql.cnf 파일 안의 맨 끝에
secure-file-priv=""를 한줄 추가한 후

# service mysql restart

를 실행해서 mysql을 재실행해 주면 mysql.cnf의 설정대로 적용이 되어 secure-file-priv를 off하게 된다.

보안을 위해 이 작업 후에는 역시 mysql.cnf의
secure-file-priv="/aaa/bbb/ccc/"로 변경후 역시 mysql을 restart시키는 것이 신상에 좋을 것이다.

혹은 mysqlimport와 동일한 기능을 다음과 같이도 가능하다.
mysql에 접속해서(mysql -u사용자id -p)

mysql> LOAD DATA INFILE '/var/lib/mysql-files/merged.dmp' INTO TABLE merged FIELDS TERMINATED BY '\t|\t' LINES TERMINATED BY '\t|\n' (old_tax_id, new_tax_id);

여기서 /var/lib/mysql-files/merged.dmp는 mysql db의 table에 저장할 데이터가 들어 있는 로컬의 (텍스트)파일,

FIELDS TERMINATED BY '\t|\t'는 /var/lib/mysql-files/merged.dmp 파일의 필드 구분자가 '\t|\t'라는 뜻이고

LINES TERMINATED BY '\t|\n'는 /var/lib/mysql-files/merged.dmp 파일의 row(레코드) 구분자가 '\t|\n'라는 뜻이고

(old_tax_id, new_tax_id)는 /var/lib/mysql-files/merged.dmp 파일의 내용을 읽어서 저장할 merged라는 table의 필드명이다.

대용량 데이터를 처리해본 결과 mysqlimport에 비해서 LOAD DATA INFILE의 방식이 훨씬 안정적으로 동작했다.