MySQL 데이터 변경 감지 (trigger) + 시스템 명령어 사용 (udf)

리눅스/MySQL|2020. 5. 31. 07:35
반응형

아래는 트리거 예제입니다.

테스트 테이블을 생성합니다.

test 테이블에는 데이터를 넣어 놓고,

test2 테이블에는 구조만 같게 해 놓고 데이터는 넣지 않습니다.

그리고 트리거 설정 후 부터는 test 에 insert 되는 데이터를 test2 에도 insert 되게 합니다.



[테스트 준비]

mysql> use test;


mysql> create table test (no int(3) AUTO_INCREMENT PRIMARY KEY, name varchar(20), age int(3));

mysql> insert test (name, age) values ('CDH', '20');

mysql> insert test (name, age) values ('JJE', '21');


mysql> create table test2 (no int(3) AUTO_INCREMENT PRIMARY KEY, name varchar(20), age int(3));



[트리거 생성]

mysql> delimiter $$

create trigger test_trigger

after insert on test for each row

begin

  insert into test2 values(new.no, new.name, new.age);

end

$$

delimiter ;



[설명]

* test_trigger : 트리거 이름

* after insert : insert 되고 나서 실행 (데이터 처리 전에 실행하려면 before 를 사용)

* on test : test 테이블 연결

* for each row : 각 행마다 실행

* begin ~ end : 조건에 맞으면 begin 과 end 사이 구문 실행 (insert, update, delete 감지 가능)

* new : insert 사용시 new, delete 사용시 old, update 사용시 old, new 를 사용할 수 있습니다.

* delimiter 뒤에 오는 문자로 쿼리 마치는 문자를 정의하는 것입니다.

   내용중에 세미콜론(;) 이 들어갈 수 있으니 $$ 로 변경 해놓고, 모든 작업이 완료 후 다시 ; 로 원복 하였습니다.


[참고]

* 트리거 보기

show triggers;


* 트리거 삭제

drop trigger 트리거명;



[테스트]

데이터를 추가로 입력하여 두 개의 테이블에 들어갔는지 확인합니다.


mysql> insert test (name, age) values ('CJW', '3');

mysql> insert test (name, age) values ('CHY', '5');


mysql> select * from test;

mysql> select * from test2;



[원격지 DB 테이블 연결]

mysql> 쉘 상에서는 직접적인 연결을 지원하지 않고,

내부에 원격지 테이블 연결이 가능하므로 연결을 통하여 insert 를 하면 될 것 같습니다.

(참조 : https://icoon22.tistory.com/251)

(단점 : show table testtbl 시 패스워드 노출)


CREATE TABLE testtbl (

 id INT AUTO_INCREMENT PRIMARY KEY,

 col1 VARCHAR(100) DEFAULT NULL,

 col2 VARCHAR(200) DEFAULT NULL

) ENGINE=FEDERATED 

  DEFAULT CHARSET=UTF8

  CONNECTION='mysql://userid:userpw@192.168.10.2:3306/testdb/testtbl;



[MySQL 에서 시스템 명령어 사용]

MySQL 에서 OS 명령어를 실행하려면 UDF 라이브러리가 필요합니다.


1) 리눅스

centos : https://ymj0078.tistory.com/5

ubuntu : https://oranke.tistory.com/273


(아래는 Ubuntu 18.04 에서 진행하였습니다)


# git clone https://github.com/mysqludf/lib_mysqludf_sys.git

# cd lib_mysqludf_sys/


# vi Makefile

LIBDIR=/usr/lib/mysql/plugin


install:

        gcc -Wall -I/usr/include/mysql -I. -fPIC lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so 

* OS 에 따라 /usr/lib/mysql/plugin 또는 /usr/lib64/mysql/plugin 사용

* /usr/include/mysql 디렉토리가 없는 경우

  Ubuntu : apt -y install libmysqld-dev

  CentOS : yum -y install mysql-devel 패키지 추가 설치


# gcc -shared -o lib_mysqludf_sys.so lib_mysqludf_sys.c -I/usr/include/mysql

# cp -arp lib_mysqludf_sys.so /usr/lib/mysql/plugin/


플러그인 추가 (mysql 로그인 후)

DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;

DROP FUNCTION IF EXISTS sys_get;

DROP FUNCTION IF EXISTS sys_set;

DROP FUNCTION IF EXISTS sys_exec;

DROP FUNCTION IF EXISTS sys_eval;


CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';

CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';

CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';

CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';

CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';


확인

select * from mysql.func;


테스트
select sys_exec('touch /tmp/test_mysql');

동작이 되지 않을 경우 쉘에서 아래와 같이 입력합니다.
(참조 : https://oranke.tistory.com/273)

# apparmor_status
결과에 /usr/sbin/mysqld 를 차단하지 않았나 확인해 볼 것
등록되어있는 경우 삭제를 해야 합니다.

# ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
# apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

재확인
sudo apparmor_status

apparmor 와 mysql 재구동
# systemctl restart mysql
# systemctl restart apparmor

그리고 다시 테스트
select sys_exec('touch /tmp/test_mysql');

그렇다면 MySQL trigger 와 udf 를 합친 방법을 사용해 봅시다.

맨 위의 예제에서 begin 과 end 사이에 아래 내용을 넣으면..

begin
    SET @exec_var = sys_exec(CONCAT('touch /tmp/', new.name));
end

exec_var 라는 mysql 변수에 sys_exec 결과를 넣는다는 뜻이지만 실제로 실행이 되어집니다.
CONCAT() 에 있는 'touch /tmp/' 와 콤마(,) 뒤의 new.name (새로운 name 필드값) 은 아래와 같이 이어붙인 명령이 됩니다.

insert into test (name, age) values ('cdh', '22'); 라고 입력시
=> touch /tmp/cdh 라고 시스템 명령을 수행한 것과 같습니다.

한 번 더 해보면.. (CONCAT 내의 띄어쓰기 잘 살펴볼 것)

begin
  SET @exec_var = sys_exec(CONCAT('touch /tmp/', new.name, ' /tmp/', new.age));
end

insert into test (name, age) values ('cdh', '22'); 라고 입력시
=> touch /tmp/cdh /tmp/22 라고 시스템 명령을 수행한 것과 같습니다.
    그래서 /tmp 디렉토리 내에 cdh 와 22 라는 파일이 생성된 것을 볼 수 있습니다.


2) 윈도우


아래 URL 은 64bit 용 dll 파일 입니다.

https://github.com/sqlmapproject/sqlmap/files/1789515/lib_mysqludf_sys_64.zip


lib_mysqludf_sys_64.zip

{mysql 설치디렉토리}\lib\plugin 안에 저장합니다.


디렉토리가 보이지 않을 경우 아래와 같이 플러그인 경로를 확인하고 실제로 존재하지 않을 경우

디렉토리를 수동으로 생성해줍니다.


mysql> select @@plugin_dir;


라이브러리 추가


mysql> use mysql;

mysql> create function sys_exec returns int soname 'lib_mysqludf_sys.so';


확인


mysql> selet * from mysql.func;


시스템 명령어 사용 예 (리눅스와 동일. 단 경로는 슬래시 두개로 사용)


1) 그냥 사용시

mysql> select sys_exec("echo aaa > c://test.txt");


반응형

댓글()

MySQL 5.7 사용자 계정 추가, root 패스워드 갱신

리눅스/MySQL|2020. 2. 3. 10:10
반응형

1. 사용자 계정 생성 및 권한 부여


기존 방법과 달리 MySQL 5.7 버전에서 부터 계정 생성하는 방법이 바뀌었으므로

아래와 같은 명령을 이용하여 계정 생성을 하고 DB 접근 권한을 부여 합니다.


mysql> create database openvas;

mysql> CREATE USER 'openvas'@'localhost' IDENTIFIED BY '12345678' PASSWORD EXPIRE NEVER;

mysql> GRANT ALL PRIVILEGES ON openvas.* TO 'openvas'@'localhost';

mysql> flush privileges;


* MariaDB 10.3.17 에서는 아래와 같이 하면 됩니다.

[mysql]> create user 'openvas'@'localhost' identified by '12345678';

[mysql]> grant all privileges on openvas.* to openvas@'localhost' identified by '12345678' with grant option;

[mysql]> flush privileges;



2. root 패스워드 변경


MySQL 5.7 버전 부터 root 패스워드 변경하는 방법 또한 변경되었습니다.

아래와 같은 쿼리를 이용하여 변경합니다.


mysql> use mysql;

mysql> update user set authentication_string=password('12345678') where user='root'; 

mysql> flush privileges;


이렇게도 안되는 경우 (MySQL 최초 설치시) 아래와 같이 사용해 봅니다.

mysql> alter user 'root'@'localhost' identified with mysql_native_password by '12345678';

mysql> flush privileges;



3. 사용자 정보 간략히 보기


mysql> select host, user, plugin, authentication_string, password_last_changed from user;


반응형

댓글()

특정 필드에 동일 데이터가 있을 경우 update, 없으면 insert

리눅스/MySQL|2019. 12. 27. 08:30
반응형

아래 예저는 users 테이블의 ID 필드에 동일한 값이 있을 경우 update 를, 없는 경우 insert 를 해주는 한 줄 쿼리 문입니다.

 

mysql> CREATE TABLE `users` (
`no` int(10) NOT NULL AUTO_INCREMENT,

`ID` varchar(16) NOT NULL,
`NAME` text,
PRIMARY KEY (`no`))
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 

아래와 같이 ID 필드는 유일한 값만 있도록 설정하는 것이 포인트!

mysql> alter table users ADD UNIQUE (ID);

 

현재 테이블 상태 입니다.

mysql> desc users;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| no    | int         | NO   | PRI | NULL    | auto_increment |
| ID    | varchar(16) | NO   | UNI | NULL    |                |
| NAME  | text        | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

 

입력을 해봅니다.

mysql> INSERT INTO users (ID, NAME) VALUES ('sysdocu', 'HongKilDong') ON DUPLICATE KEY UPDATE NAME='HongKilDong';

 

ID (sysdocu) 가 없으면 INSERT 쿼리문을,

ID (sysdocu) 가 존재할 때는 NAME 컬럼만 UPDATE 합니다.

 

반응형

댓글()

root 관리자 계정 이름을 다른 아이디로 변경 하기

리눅스/MySQL|2019. 12. 6. 16:31
반응형

root 라는 사용자 명은 유추 가능하므로 보안상 다른 계정명으로 변경하여 운영하는 것이 좋습니다.

방법은 간단합니다.

mysql 데이터 베이스 user 테이블에 있는 root 문자를 원하는 계정명으로 업데이트 하면 됩니다.



# mysql -u root -p

Enter password: (관리자 패스워드 입력)


mysql> use mysql;


root 라는 사용자명은 유추 가능하므로 보안상 다른 계정명으로 변경합니다.

mysql> update user set user='sysdocu' where user='root';


mysql> flush privileges;


mysql> exit



그 다음 부터는 변경된 계정명으로 로그인이 가능합니다.

# mysql -u sysdocu -p

Enter password: (관리자 패스워드 입력)



[참고]

관리자 계정 추가를 원할 경우 아래와 같은 모든 DB 접근 권한을 주면 됩니다.


mysql> grant all privileges on *.* to sysdocu@localhost identified by '12345678';

mysql> flush privileges;

반응형

댓글()

MySQL 5.6 소스 설치

리눅스/MySQL|2019. 8. 29. 14:42
반응형

mysql 5.5 이상 버전 부터 cmake 를 이용하여 설치 하기 때문에 cmake를 먼저 설치 후 mysql 설치를 진행 합니다.

# cd  /usr/local/src

 

# groupadd mysql
# useradd -g mysql mysql

 

# wget https://src.fedoraproject.org/repo/pkgs/cmake/cmake-2.8.5.tar.gz/3c5d32cec0f4c2dc45f4c2e84f4a20c5/cmake-2.8.5.tar.gz
# tar zxvfp ./cmake-2.8.5.tar.gz
# cd  ./cmake-2.8.5
# ./bootstrap
# make
# make install

# cd ../

# wget https://distfiles.macports.org/mysql56/mysql-5.6.45.tar.gz
# tar xvzf mysql-5.6.45.tar.gz
# cd mysql-5.6.45
# cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_USER=mysql \
-DMYSQL_TCP_PORT=3306 \
-DENABLE_DOWNLOADS=1

 

* euckr 으로 설치를 원할 경우 위 파란 부분을 각각 euckr 과 euckr_korean_ci 로 변경


# make
# make install

# cp -arp /usr/local/mysql/support-files/my-default.cnf /etc/my.cnf
# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/my.cnf --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
# cp -arpf /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
 

소유권 그룹 권한등을 변경 하여 줍니다.

# chown -R mysql:mysql /usr/local/mysql/
# chmod 700 /etc/init.d/mysqld
# chmod 711 /usr/local/mysql
# chmod 700 /usr/local/mysql/data
# chmod 751 /usr/local/mysql/bin
# chmod 750 /usr/local/mysql/bin/*
# chmod 755 /usr/local/mysql/bin/mysql
# chmod 755 /usr/local/mysql/bin/mysqldump
 

mysql 명령어를 사용할 수 있게 환경변수를 등록하여 줍니다.

# vi /etc/profile
PATH="$PATH:/usr/local/mysql/bin"

# source /etc/profile

# chkconfig mysqld --add
# chkconfig mysqld on
# /etc/init.d/mysqld start

 

 

[출처] https://idchowto.com/?p=26547

반응형

댓글()

mongodump 사용시 조건을 주어 백업하기

리눅스/MySQL|2019. 6. 18. 09:25
반응형

원격일 경우,

--collection 컬렉션이름 : 이 옵션을 안쓰면 전체 db를 백업하게 됩니다.

 

mongodump --host 대상서버아이피 --port 포트번호 --db db이름 --collection 컬렉션이름 --out 백업시킬경로 --query 쿼리조건

 

 

예)

저희가 저장하고 있는 incident_traffic 컬렉션의 데이터 중

time : 2014-02-18 00:12:41

이렇게 시간 컬럼이 있습니다.

 

백업 서버 : 1.1.1.1

데이터가 실제 있는 서버 : 2.2.2.2

몽고DB의 포트 : 27017

db 이름 : aptsys

 

하루동안의 데이터만 백업시키려면 다음과 같이 합니다

 

mongodump -u userID -p userPW --host 2.2.2.2 --port 27017 --db aptsys --collection incident_traffic --out /home/mongo/backup --query '{time:{"$gte":"2014-02-18 00:00:00" ,"$lte":"2014-02-18 23:59:59"}}'

 

time 필드가 아니고 info 필드 내의 time 필드 (?) 일 경우 이와 같이 사용

> info.time

 

1.1.1.1 서버의 /home/mongo/backup 의 공간에 해당 데이터들이 쌓입니다.

 

주의점 -> 항상 전체 컬렉션에서 해당 쿼리에 맞는 데이터를 쌓기 때문에 오늘 덤프를 뜨든, 내일 덤프를 뜨든 늘 전체 데이터를 full scan 합니다. 항상 전체 데이터에서 퍼센테이지 올라가는거보고 " 왜 쿼리가 안먹혀? " 라고 생각하지 마세요~

 

백업된 dump 파일을 서버로 옮기려면

mongorestore 를 합니다.

 

mongorestore --host 127.0.0.1 --port 27017 /home/mongo/backup/aptsys

 

 

[출처] https://m.blog.naver.com/PostView.nhn?blogId=atoz333&logNo=120207822356&proxyReferer=https%3A%2F%2Fwww.google.com%2F

반응형

댓글()

mysqldump 사용시 조건을 주어 백업하기

리눅스/MySQL|2019. 6. 18. 08:16
반응형

# mysqldump -u root -p {DB명} {table명} --where="id='1234'" > filename.sql

 

위와 같이 --where 옵션에 조건을 주면 된다.

 

 

 

반응형

댓글()

MySQL general 로그를 logrotate 로 관리하기

리눅스/MySQL|2019. 6. 4. 12:06
반응형

1. general 로그 설정

 

[root@sysdocu ~]# vi /etc/my.cnf

[mysqld]

general_log_file  = /usr/local/mysql/data/general.log

general_log  = 1

 

 

2. logrotate 설정

 

[root@sysdocu ~]# vi /etc/logrotate.d/mysql

/usr/local/mysql/data/general.log {

    daily

    rotate 1    // 사용중인것 말고 날짜로 된것 하나만 보관하도록 한다

    dateext

    missingok

    sharedscripts

    create 660 mysql mysql

    postrotate

        /usr/local/mysql/bin/mysqladmin -uroot -p'00000000' flush-logs

    endscript

}

 

[root@sysdocu ~]# chmod 640 /etc/logrotate.d/mysql

 

강제 실행 테스트

[root@sysdocu ~]# logrotate -f /etc/logrotate.d/mysql

 

 

3. 로그 압축 백업 설정

 

용량이 큰 general 로그를 압축하여 보관하도록 한다.

 

[root@sysdocu ~]# vi /etc/crontab

59 23 * * * root sh /root/general_log.sh

 

[root@sysdocu ~]# vi /root/general_log.sh

!#/bin/bash

 

find /data2/general_log/ -ctime +200 -print -exec rm -f {} \;

date=`date +%Y%m%d`

tar cvzf /data2/general_log/general_log_${date}.tar.gz /data1/general.log-${date}

 

exit 0

 

[root@sysdocu ~]# chmod 700 /root/general_log.sh

 

반응형

댓글()

MySQL 5.7 소스 설치하기

리눅스/MySQL|2019. 5. 13. 09:39
반응형

필수 구성 요소

# yum -y install wget gcc* ncurses-devel

 

 

1. cmake 설치

# cd /usr/local/src

# wget http://github.com/Kitware/CMake/releases/download/v3.18.4/cmake-3.18.4.tar.gz

# tar xvzf cmake-3.18.4.tar.gz

# cd cmake-3.18.4

# ./bootstrap

# make

# make install

 

MySQL 5.7.x 설치시 boost 라이브러리를 참조하기 때문에 이부분을 컴파일 과정에서 추가해줘야 됩니다.

 

# cd ..

# wget http://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz

# tar xvfz boost_1_59_0.tar.gz

# mv boost_1_59_0 /usr/local/

 

MySQL ./configure 설행시 아래 옵션 잊지말고 추가합니다.

-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost_1_59_0

 

 

2. 계정 생성

# groupadd -g 400 mysql
# useradd -u400 -g400 -d /usr/local/mysql -s /bin/false mysql

 

 

3. MySQL 설치

# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26.tar.gz

# tar xvzf mysql-5.7.26.tar.gz

# cd mysql-5.7.26

# cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DSYSCONFDIR=/etc -DMYSQL_TCP_PORT=3306 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost_1_59_0

# make

# make install

 

[참고]

euckr 로 설치를 원할 경우 옵션을 변경해줍니다.

-DDEFAULT_CHARSET=euckr -DDEFAULT_COLLATION=euckr_korean_ci

 

 

4. DB생성 및 기본 보안 설정

 

실행 파일을 생성하고 부팅시 자동 구동 되도록 합니다.

# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
# chmod 700 /etc/init.d/mysqld
# chown root.root /etc/init.d/mysqld
# chkconfig --add mysqld

 

기본 DB 를 생성하기 전에 환경 설정 파일을 먼저 만들어 줍니다.

# vi /etc/my.cnf

[client]
default-character-set = utf8

[mysqld]
server-id = 1
skip-name-resolve
max_connections = 10240
thread_cache_size = 50
wait_timeout = 28800
sort_buffer_size = 512K
collation-server = utf8_general_ci
character-set-server = utf8
skip-character-set-client-handshake
default-storage-engine = InnoDB
innodb_file_per_table = 1
innodb_data_home_dir = /usr/local/mysql/data
innodb_data_file_path = ibdata1:1024M:autoextend
innodb_autoextend_increment = 100
innodb_log_group_home_dir = /usr/local/mysql/data
innodb_buffer_pool_size = 5G
innodb_log_buffer_size = 16M
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
innodb_thread_concurrency = 0
innodb_lock_wait_timeout = 20
innodb_force_recovery = 0
innodb_flush_method = O_DSYNC
innodb_doublewrite = 0
innodb_sync_spin_loops = 20
innodb_table_locks = 1
innodb_thread_sleep_delay = 1000
innodb_max_purge_lag = 0
innodb_commit_concurrency = 0
innodb_concurrency_tickets = 500

log-bin = binlog
max_binlog_size = 1G

general_log = 1
general_log_file = /usr/local/mysql/data/general_query.log

slow-query-log = 1
long_query_time = 10
slow_query_log_file = /usr/local/mysql/data/slow_query.log

[mysqldump]
default-character-set = utf8

[mysql]
default-character-set = utf8

 

이제 기본 DB 를 생성합니다.

MySQL 5.7 의 경우 아래와 같이 초기화할 경우 root 패스워드 없이 생성됩니다.

# /usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

 

초기화시 패스워드가 랜덤으로 생성되게 하려면 위 파란색 옵션을 아래 옵션으로 대체하면 됩니다.

(설치 화면 마지막줄에 출력)

--initialize

 

mysql 을 가동하고 root 패스워드를 새로 설정합니다.

MySQL 5.7 버전부터 mysql.user 테이블의 password 필드는 사라졌고, 변경 방법이 아래와 같이 바뀌었습니다.

 

# /etc/init.d/mysqld start

# /usr/local/mysql/bin/mysql -p

Enter password: (설치시 패스워드)

 

mysql> alter user root@localhost identified with mysql_native_password by '새패스워드';

mysql> flush privileges; 

 

반응형

댓글()

MariaDB Galera Cluster 구성 (MySQL, MariaDB 지원)

리눅스/MySQL|2018. 12. 5. 11:27
반응형

Galera Cluster 는 두대 이상의 DB 서버를 '마스터 - 마스터' 형태로 운영토록 해주므로 아주 매력있는 기술이지만

실제 서비스를 가동하는데 있어 기능제한이나 오류 등이 많이 발견되고 있어 고객 서버에 적용하기에 적합하지 않습니다.

버전이 올라감에 따라 단점이 보완 될 것으로 보이므로 미리 설치, 테스트를 거쳐 고객 응대하는데 도움이 되시기 바랍니다.


본 매뉴얼은 Galera Cluster 를 CentOS 7.4 에서 MariaDB 10.2 환경에서 구성하였습니다.


[테스트 서버]

- 49.247.212.17    // 마스터 노드

- 49.247.212.46    // 슬레이브 노드

* 마스터 및 슬레이브 노드의 구분은 최초 구동 명령의 차이 밖에 없습니다. (반드시 기억해야 할 부분. 이유는 맨 하단 테스트에 나옴)



1. Galera Cluster 개요


1) 장점

- 모든 노드 읽기/쓰기가 가능하므로 Active - Active 방식의 멀티 마스터 구성 가능

- 노드간에 트랜젝션을 지원하므로 데이터의 일관성이 보장

- 노드 추가 및 제거가 간단


2) 단점

InnoDB 테이블만 지원

데이터베이스 단위가 아닌 서버 단위로 구성

한 노드에서 테이블 락이 걸리면 모든 노드에서 락이 걸림

- 한 노드에서 insert 시에 모든 노드에 데이터 insert 요청을 하게 되므로 쓰기 성능 저하

   => 이 문제로 순식간에 양 노드에 쓰기가 들어간다면 Auto Increment 충돌로 인한 장애 또는 데이터 유실이 발생할 수 있음


3) 지원 버전

MySQL 5.5, 5.6 이상 지원

MariaDB 5.5 이상 지원

* MariaDB 10.1 부터 기능이 기본 포함되어 설정이 더 간편해 졌습니다.



2. 설치


CentOS 7.4 가 설치된 상태에서 yum 명령을 통해 mariadb 를 설치하면 버전이 5.5.60 이 설치되므로

repositories 를 추가하여 더 높은 버전 (10.2.19) 의 mariadb 를 설치하도록 합니다.


1) 서버 공통 작업


[MariaDB 설치]


# vi /etc/yum.repos.d/MariaDB.repo


[MariaDB]

name = MariaDB

baseurl = http://yum.mariadb.org/10.2/centos7-amd64

gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB

gpgcheck = 1 


# yum -y install mariadb-server galera rsync

// 복제 방식은 rsync 를 사용할 것이므로 rsync 패키지도 같이 설치


# vi /etc/my.cnf.d/server.cnf


[galera]

wsrep_on=ON                                                                                                                // galera cluster 사용 여부

wsrep_provider=/usr/lib64/galera/libgalera_smm.so                                 // libgalera_smm.so 모듈 위치

wsrep_cluster_address="gcomm://49.247.212.17,49.247.212.46"         // 본 서버를 포함한 동기화될 서버 IP LIST

wsrep_cluster_name=cluster                                                                                   // 그룹명 (동기화 될 서버가 모두 동일해야 함)

wsrep_node_address="49.247.212.17"                                                               // 현재 서버 IP

wsrep_node_name="sysdocu1"                                                                             // 현재 서버의 이름 (동기화될 서버간에 중복되면 안됨)

wsrep_sst_method=rsync                                                                                         // 동기화 될 데이터 전송 방식

wsrep_sst_auth="root:12345678"                                                                         // 데이터 전송 방식에 사용할 계정

binlog_format=row                                                                                                      // 바이너리 로그 파일 형식

default_storage_engine=InnoDB                                                                          // 스토리지 엔진 타입

innodb_autoinc_lock_mode=2                                                                              // 

bind-address=0.0.0.0                                                                                                  // 모든 IP 에서 접근 허용


마스터 서버는 위와 같이 구성하고, 나머지 서버는 위 내용에서 wsrep_node_addresswsrep_node_name각 서버의 고유한 값으로 바꾸어 줍니다.


[iptables 방화벽 설정]


아래 포트 리스트를 모든 서버에 동일하게 적용해줍니다. (선진행 필수)

3306/tcp

4444/tcp

4567/tcp

4567/udp

4568/tcp


2) 마스터 노드


데이터를 최초 배포 하는 마스터 노드에서 아래와 같이 실행합니다.


# galera_new_cluster


* 주의 : (모든 노드가 다운 상태인) 최초 구동일 경우에만 사용합니다.


3) 슬레이브 노드 (마스터 노드를 제외한 모든 서버)


# service mysql start



3. 동기화 확인 및 테스트


1) 확인


# mysql -p

(mysql root 비밀번호 입력)


MariaDB [(none)]> show status like 'wsrep_cluster_size';

+--------------------+-------+

| Variable_name      | Value |

+--------------------+-------+

| wsrep_cluster_size |    |

+--------------------+-------+

1 row in set (0.01 sec)


MariaDB [(none)]> show status like 'wsrep_incoming_addresses';
+--------------------------+---------------------------------------+
| Variable_name            | Value                                 |
+--------------------------+---------------------------------------+
| wsrep_incoming_addresses | 49.247.212.46:3306,49.247.212.17:3306 |
+--------------------------+---------------------------------------+
1 row in set (0.00 sec)

2) 데이터베이스, 테이블 생성 및 데이터 입력


마스터 노드에서 아래와 같이 테이블을 생성하고 데이터를 입력합니다.


MariaDB [(none)]> use test

MariaDB [test]> create table memo (name varchar(20), email varchar(250));

MariaDB [test]> insert memo (name, email) values ('SYSDOCU', 'sysdocu@sysdocu.tistory.com');


그리고 슬레이브 노드에서 데이터 입력을 확인하면 됩니다.
이와 같이 여러대의 서버를 cluster 로 묶은 경우 반대쪽 노드에서 insert 를 해서 반영이 되었는지 양방향으로 꼭 확인을 해봅니다.


4. 장애 복구 테스트


운영중 발생한 장애에 대하여 데이터를 동기화할 필요성이 있습니다.

한 대의 노드가 중지 된 상태에서 입력된 데이터는 나중에 해당 노드가 복구되어서 DB가 가동 되었을때 자동으로 sync 가 맞추어 집니다.

(마스터, 슬레이브 구분 없음)


[테스트 - 슬레이브 노드 장애]

1) 49.247.212.46 노드 셧다운

2) 49.247.212.17 노드에 데이터 insert

3) 49.247.212.46 노드 부팅 및 mariadb 가동

     # service mysql start

4) 49.247.212.46 노드에서 17번 입력 데이터 확인

     -- DB 데이터 sync 확인 --


[테스트 - 마스터 노드 장애]

1) 49.247.212.17 노드 셧다운

2) 49.247.212.46 노드에 데이터 insert

3) 49.247.212.17 노드 부팅 및 mariadb 가동

4) 49.247.212.17 노드에서 46번 입력 데이터 확인

     -- DB 데이터 sync 확인 --


[테스트 - 마스터, 슬레이브 노드 동시 장애]

1) 49.247.212.17 노드 셧다운

2) 49.247.212.46 노드에 데이터 insert

3) 49.247.212.46 노드 셧다운

     -- DB 서비스 완전 종료 --

4) 49.247.212.46 노드 부팅 및 mariadb 가동    // Master - Master 기반의 환경이지만 두번째 서버이므로 구동이 되지 않음

     # service mysql start

5) 49.247.212.17 노드 부팅 및 mariadb 가동    // 성공. 모든 노드 다운시에는 마스터 서버 부터 가동해야 함

     # galera_new_cluster

6) 49.247.212.46 노드 부팅 및 mariadb 가동

     # service mysql start

7) 17번, 46번 노드에서 데이터 확인

     -- DB 데이터 sync 확인 --


[장애 복구 테스트 결론]

- 운영중 마스터, 슬레이브 상관없이 어느 노드 하나가 다운 되었다면, 장애 서버 부팅만으로 데이터 sync 를 맞출 수 있습니다.

- 모든 노드의 서버가 다운되었을 경우, 마스터 노드부터 부팅을 시키는게 일반적이지만

   마스터 노드 다운 후 슬레이브 노드로 insert 된 데이터가 있다면 마스터 노드부터 가동할 경우 슬레이브 노드에 추가된 데이터가 유실 됩니다.

   유실을 막는 대안으로는 (데이터가 추가로 존재하는) 슬레이브 노드에서 galera_new_cluster 명령 먼저 가동하고 나머지 노드를 service mysql start 로 가동하면 됩니다.

   (마스터, 슬레이브 노드 역할을 바꿈)



5. 노드 추가


새로운 노드 IP : 49.247.212.68


1) 새로운 노드에 MariaDB를 설치하고 환경을 위와 같이 설정합니다.

     다만 아래 항목에서는 추가된 노드 IP를 추가해 주어야 합니다.


     wsrep_cluster_address="gcomm://49.247.212.17,49.247.212.46,49.247.212.68"


2) 방화벽 설정

     위 'iptables 방화벽 설정' 내용을 참고하여 설정합니다.


3) MariaDB 가동

     # service mysql start    // 이때 데이터가 동기화 되므로 데이터 양이 많다면 그만큼 기다려야 합니다.


4) MariaDB 에 로그인 해서 데이터 sync 된 것을 확인합니다.


5) 관리 목적상 헷갈리지 않도록 17번과 46번 노드의 설정 파일도 일관성 있게 아래 옵션에 새로운 노드 IP를 추가해 줍니다. (mysql 재시작 불필요)

     추가 설정 여부와 관계없이 데이터는 이미 양방향으로 전송이 가능한 상태입니다.


     wsrep_cluster_address="gcomm://49.247.212.17,49.247.212.46,49.247.212.68"



반응형

댓글()

CentOS7 에서 MySQL 8.0 소스 설치

리눅스/MySQL|2018. 11. 14. 14:46
반응형

필수 패키지 설치

# yum -y install cmake ncurses-devel gcc* openssl openssl-devel



계정 추가

# groupadd -g 400 mysql

# useradd -u400 -g400 -d /usr/local/mysql -s /bin/false mysql



설치

# cd /usr/local/src

# wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.12.tar.gz

# tar xvfz mysql-8.0.12.tar.gz 

# cd mysql-8.0.12

# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 -DWITH_SSL=system -DMYSQL_TCP_PORT=3306 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_COLLATION=utf8_general_ci -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/include/boost

# make

# make install



초기 데이터 베이스 구성 및 권한 설정

# cd

# /usr/local/mysql/bin/mysqld --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql

# chown -R mysql.mysql /usr/local/mysql/

# chmod 711 /usr/local/mysql

# chmod 700 /usr/local/mysql/data

# chmod 751 /usr/local/mysql/bin/

# chmod 750 /usr/local/mysql/bin/*

# chmod 755 /usr/local/mysql/bin/mysql

# chmod 755 /usr/local/mysql/bin/mysqldump



boost 설치

# cd /usr/local/include/boost/boost_1_66_0    // boost 버전이 다를 수 있음

# ./bootstrap.sh 

# ./b2 install



자동 실행 설정 및 기타 파일 적용

# vi /etc/my.cnf

[mysqld]

datadir=/usr/local/mysql/data

basedir=/usr/local/mysql/

port=3306

socket=/tmp/mysql.sock


[mysqld_safe]

log-error=/var/log/mysql_log.err

pid-file=/usr/local/mysql/mysql.pid 


# cp -arp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

# chkconfig --add mysqld

# chkconfig mysqld on



이후 작업

- iptables 방화벽 설정 (tcp 3306 추가)

- root 패스워드 업데이트


반응형

댓글()