1. Data Directory 확인 및 파일 관련
데이터가 저장되는 기본 디렉터리
바이너리 배포 버전일 경우 |
/var/lib/mysql/data |
RPM 설치 버전 |
/var/lib/mysql |
파라미터로 확인 |
mysql> show global variables like '%datadir%' ; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | datadir | /var/lib/mysql/ | +---------------+-----------------+
또는 /etc/my.cnf 파일에서 datadir 파라미터 값을 확인 (서버가 기동 중이지 않을 때)
[root@mmysql ~]# cat /etc/my.cnf | grep datadir datadir=/var/lib/mysql |
데이터 베이스는 데이터 베이스 디렉터리 안에서 개별 디렉터리로 구분 됨
데이터 베이스 디렉터리 안에 자동으로 생성되는 파일 이외에 유저가 생성한 파일이 존재 할 경우, drop database명령문은 에러가 발생한다.
이 경우 수동으로 디렉터리 안의 파일들을 삭제 한 후에 다시 drop database명령을 수행하면 된다.
mysql> show global variables like 'datadir' ; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | datadir | /var/lib/mysql/ | +---------------+-----------------+ 1 row in set (0.00 sec)
mysql> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | tpcc | | tpch | +--------------------+ 6 rows in set (0.00 sec)
mysql> exit Bye [root@mmysql mysql]# cd /var/lib/mysql/ [root@mmysql mysql]# ls -d */ mysql/ performance_schema/ sys/ tpcc/ tpch/ <-- 각각의 폴더가 데이터 베이스를 나타냄
디렉터리 안에 db.opt 파일은 다음과 같이 기본 캐릭터 셋과 콜레이션 정보를 가진다. [root@mmysql tpcc]# cat db.opt default-character-set=latin1 default-collation=latin1_swedish_ci
테이블을 생성하게 되면 확장자가 .frm인 파일이 생성되며, 스토리지 엔진에 따라서 데이터가 들어가 있는 파일이 생성된다. innoDB엔진일 경우 다음과 같이 확장자가 ibd인 파일이 생성되어 데이터가 저장된다. innoDB엔진이 동일 테이블 스페이스를 사용하게 설정이 되어 있고, 16K의 페이지를 사용할 경우 최대 테이블 크기는 40억페이지를 가지는 테이블을 생성할 수 있다. 그러나 개별 테이블 스페이스를 사용하게 설정이 되어 있다면 개별 테이블의 정보는 ibd파일에 저장되며 최대 크기는 운영체제 파일크기의 제약에 따른다. (innodb_file_per_table=1)
[root@mmysql tpcc]# ls -al total 1380116 drwxr-x--- 2 mysql mysql 4096 Jun 24 14:47 . drwxr-x--x 7 mysql mysql 4096 Dec 4 20:41 .. -rw-r----- 1 mysql mysql 9388 Jun 23 13:31 customer.frm -rw-r----- 1 mysql mysql 58720256 Jul 21 14:25 customer.ibd -rw-r----- 1 mysql mysql 65 Jun 23 13:31 db.opt
MyISAM엔진을 사용할 경우 *.frm 파일은 테이블 구조 명세를 저장한 파일이며, *.myd 는 데이터가 저장된 파일, *.myi는 인덱스에 대한 정보를 저장한 파일이 된다. .myd와 .myi 파일은 최대 256TB의 크기 제한을 가진다. 테이블 생성 시 avg_row_length와 max_rows 옵션을 사용하면 최대 65,536TB 의 크기까지 가능하다. 운영중에 135,136 에러가 발생하게 된다면 alter table문을 이용해서 이 값을 증가 시켜주면 된다.
Memory엔진을 사용할 경우 *.frm 파일만 데이터 베이스 디렉터리 안에 존재 하게 되며, 모든 데이터는 메모리에 존재 한다. 그래서 서버가 종료 될 경우 데이터 및 인덱스 정보는 모두 사라진다. 서버가 재 기동되면 테이블은 존재 하지만 데이터는 없는 상태가 된다.
트리거 파일은 확장자가 trg가 되며 트리거 명.trg가 아니라, 트리거가 생성되어 있는 테이블명.trg가 되고, 해당 테이블에 트리거가 많을 경우 하나의 trg파일에 모두 저장되고, 트리거명.trn 파일이 생성된다.
Show tables from dbName ; 문을 수행하면 해당 데이터베이스 디렉터리 안의 *.frm 파일명을 보여주는 것과 같다.
유닉스 계열에서는 파일 시스템에서 대/소 문자를 구분하기 때문에 abc , ABC 는 abc.frm ABC.frm 파일로 생성된다. 그래서 두 개는 서로 다른 테이블로 인식이 된다. 이런 환경에서 대소문자를 구분하지 않는 시스템으로의 이전을 고려할 경우 신중해야 한다(테이블이 하나 생성 안될 수도 있으므로)
그래서 lower_case_table_name 값을 1을 주게 되면 소문자 테이블 명을 사용할 수 있게 되며 내부적으로는 다음과 같다. 1. 테이블 정보를 가진 .frm파일을 생성할 때, 테이블 명을 소문자로 변경 후 .frm 파일을 생성한다. 2. FROM 절에 대문자로 기술된 테이블이 있을 경우 내부적으로 소문자로 변경 후 쿼리를 수행한다.
기존에 대문자의 데이터베이스 명이나 테이블 명을 가진 시스템에서 소문자로 변경 하고자 한다면, 다음과 같은 방법을 써야 한다. 데이터베이스 명과 테이블 명 둘 다 대문자가 있을 경우 mysqldump --database dbname > dbname.sql drop database dbname ; 디비 중지 후 /etc/my.cnf 파일에 lower_case_table_name값을 1로 설정 후 기동 mysql < dbname.sql
테이블명만 대문자 일 경우 rename table 테이블명
|
2. 데이터 파일 재 배치
데이터 파일을 재 배치 하여 I/O 분산이 주 목적
모든 재 배치 작업 전에는 Flush tables 명령 수행 후 전체 데이터 베이스에 대한 백업을 실시 한다.
전체 데이터 디렉터리 |
시작옵션 변경 : 시작 시 --datadir=/data1 또는 /etc/my.cnf 파일에 datadir=/data1 추가 심볼릭 링크 사용 : 기존의 디렉터리 내용을 다른 곳으로 이동 후 심볼릭 링크 생성 |
개별 데이터 베이스 디렉터리 |
심볼릭 링크 사용 1. mysql shutdown ( mysqladmin -p -u root shutdown ) 2. cd /usr/local/mysql/data 3. tar cf - bigdb | ( cd /var/db; tar xf - ) 4. rm -rf bigdb 5. ln -s /var/db/bigdb bigdb 6. mysql startup mysqld_safe &
|
개별 테이블 |
심볼릭 링크 사용 유닉스 환경의 MyISAM테이블만 지원 함. mysql> show global variables like 'have_symlink' ; +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_symlink | DISABLED | +---------------+----------+ 위의 환경변수 값이 enabled(YES)가 되면 사용가능.
.MYD .MYI파일을 이동 후, 원본 디렉터리에 동일 이름의 심볼릭 링크 생성. .frm 파일은 이동 없이 원본 디렉터리에 존재 해야 함. |
innodb 테이블 스페이스 파일 |
시작 옵션 변경
mysql> show global variables like 'innodb_data%' ; +-----------------------+------------------------+ | Variable_name | Value | +-----------------------+------------------------+ | innodb_data_file_path | ibdata1:12M:autoextend | | innodb_data_home_dir | | +-----------------------+------------------------+
|
서버 PID 파일 |
시작 옵션 변경 또는 시작옵션 변경
mysql> show global variables like 'pid_file' ; +---------------+----------------------------+ | Variable_name | Value | +---------------+----------------------------+ | pid_file | /var/run/mysqld/mysqld.pid | +---------------+----------------------------+
--pid_file=/tmp/mysqld.pid 또는 [mysqld] pid_file=/tmp/mysqld.pid |
로그 파일 |
시작 옵션 변경
[mysqld] log_error= general_log=1 general_log_file= log-bin= |
3. MySQL 상태와 로그 파일
기본적으로 설정되어 있는 로그파일 정보는 다음과 같다.
mysql> show global variables like '%log%' ; 필요한 정보만 남김... +-----------------------------------------+--------------------------------+ | Variable_name | Value | +-----------------------------------------+--------------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/mmysql.log | | log_bin | ON | | log_bin_basename | /var/lib/mysql/mysql-bin | | log_bin_index | /var/lib/mysql/mysql-bin.index | | relay_log | | | relay_log_basename | | | relay_log_index | | | slow_query_log | ON | | slow_query_log_file | /var/lib/mysql/mmysql-slow.log | +-----------------------------------------+--------------------------------+
|
4. 계정 및 권한 관리
기본적으로 설치 되는 데이터 베이스인 mysql 데이터베이스에 유저 및 권한 정보가 저장되며, mysql 데이터 베이스의 user라는 테이블에 사용자 정보가 저장되며, db라는 테이블에 권한 정보가 저장된다.
최초 설치 시에는 비밀번호가 설정되지 않는다. 그래서 관리자가 해야 할 첫 번째 일을 비밀번호를 설정 하는 일이다.
설치 시 mysql_install_db 스크립트에는 권한 테이블을 설정 하는 것이다.
mysql> select host , user , plugin , password_last_changed , password_expired , account_locked -> from user ; +-----------+-----------+-----------------------+-----------------------+------------------+----------------+ | host | user | plugin | password_last_changed | password_expired | account_locked | +-----------+-----------+-----------------------+-----------------------+------------------+----------------+ | localhost | root | mysql_native_password | 2016-06-21 10:56:41 | N | N | | localhost | mysql.sys | mysql_native_password | 2016-06-20 13:13:18 | N | Y | | % | root | mysql_native_password | 2016-06-21 13:16:38 | N | N | | % | repl | mysql_native_password | 2016-06-21 16:14:35 | N | N | +-----------+-----------+-----------------------+-----------------------+------------------+----------------+ |
비밀번호 변경 방법
mysql.user 테이블에 password 칼럼이 있는 경우
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD ('root1122') ; mysql> flush privileges ; 또는 mysql> update mysql.user set password=password('root1122') where user = 'root' ; mysql> flush privileges ;
mysql.user 테이블에 password 칼럼이 없는 경우
mysql> update mysql.user set authentication_string=password('root1122') where user ='root' ; mysql> flush privileges ;
mysql> flush privileges ;를 해 주는 이유는 변경내용을 메모리상에 반영해 주기 위함 임. |
mysqld 프로세스는 mysql 데이터 디렉터리의 컨텐츠에 접근하고 관리하는 것 이외에 다른 권한이 필요 없다. 그래서 root로 MySQL을 기동해서 위험을 감수 하지 않고 일반 유저로 기동시켜도 된다. 그러기 위해서는 일반 유저를 생성 후 데이터 디렉터리에 대한 권한을 주면 된다.
다음의 예는 mysql이라는 유저가 mysql을 기동할 수 있게 하기 위한 설정이다.
1. 서버 종료 mysqladmin -p -u root shutdown 2. 데이터 디렉터리 권한 변경 chown -R mysql /var/lib/mysql chgrp -R mysql /var/lib/mysql 3. mysql 이외의 유저가 접근하는 것을 막기 위하여 다음과 같이 group과 other권한을 제한한다, chmod -R go-rwx /var/lib/mysql
root가 아닌 일반 유저로 기동 시킬 경우는 --user=mysql 옵션을 추가 시켜서 기동 시키거나, /etc/my.cnf 파일에 user=mysql을 추가 하면 된다. |
5. 서버 장애 시 서버 제어 방법
5.1 소켓 파일 이상으로 접속이 안 되는 경우
서버가 운영되다가 접속 장애가 발생 하는 경우가 있다. 이 경우 웬만하면 서버를 재 기동 시켜주면 다시 정상으로 되지만, 서버에 접속 할 수 가 없어서
서버를 재 기동 시키지 못하는 경우가 있다. (/tmp 밑의 소켓파일이 삭제 되거나 했을 경우)
이럴 경우 --protocol=tcp 옵션을 사용하거나 localhost대신 127.0.0.1을 호스트 값으로 주어서 접속 후 서버를 재 기동 시켜 주면 된다.
127.0.0.1은 소켓 접속이 아닌 tcp/ip 방식의 접속을 사용한다.
mysqladmin -u root -p --protocol=tcp shutdown 또는 mysqladmin -u root -p -h 127.0.0.1 shutdown |
소켓 파일이 문제 였을 경우 새로운 곳에 소켓파일을 생성하게 수정 후 재 기동 시켜 주면 되는데, 기존 클라이언트가 변경 전 소켓 위치를 참조할 수 있으므로
다음과 같이 서버와 클라이언트 모두 변경을 해 준다.
/etc/my.cnf 파일에 다음과 같이 설정
[mysqld] socket=/usr/local/mysql/mysql.sock [client] socket=/usr/local/mysql/mysql.sock |
5.2 root 암호를 분실했을 경우
root암호를 분실 했을 경우 반드시 서버의 접근 권한을 획득한 후에 비밀번호를 변경해야 함.
pid 파일을 이용하거나 ps 명령을 이용하여 processid를 획득 한 후에 다음 순서로 진행 한다.
1. 테이블과 로그들을 정상 반영 후 down 시키기 위하여 term 옵션을 주고 수행 함. 그래도 반응이 없을 경우는 -9 옵션으로 강제 종료를 시킨다. mysqld_safe로 기동 시켰을 경우 -9 옵션으로 서버를 종료 시키면 즉시 서버를 재 기동 시키게 되어 있다. 그래서 종료 전 mysqld_safe 프로세스를 먼저 죽이는 과정이 필요 함.
kill -TERM pid
2. 권한 테이블을 통한 검증을 비활성 화 시키기 위하여 --skip-grant-tables 옵션을 이용하여 기동
mysql --skip-grant-tables
3. flush privileges 명령어를 통하여 권한 정보를 읽어 옴. 이때 접속 중인 세션은 그대로 유지가 되기 때문에 상관없고, 이후 접속 되는 연결은 권한을 체크 한다. (flush privileges 명령을 수행하지 않으면 패스워드 변경이 불가능 하다.)
mysql> flush privileges ;
4. root의 패스워드를 변경한다.
5. 정상적으로 서버를 재 기동 시킨다. |
6. 환경 변수
MySQL에서 사용하는 변수는 크게 시스템 변수와 성능 모니터링을 가능하게 하는 상태 변수 두 가지가 존재 한다.
6.1 시스템 변수
서버의 동작 파라미터들을 제어 한다.
변수들은 show variables명령어로 확인을 할 수 있으며, Global/Session 변수 두 가지가 존재 한다.
시스템 변수는 서버 운영 중에도 SET 명령을 이용하여 변경 할 수 있다.
(수행 중 동적으로 변경 한 값은 서버 재 기동 시 적용되지 않으므로 /etc/my.cnf 파일에 명시적으로 써 주는 것이 좋다.)
변수 값을 확인하는 방법은 show variables 또는 @@변수명 두 가지를 이용할 수 있으며, @@global.변수명 또는 @@local.변수명(@@session.변수명)
을 사용할 수 있다. global이나 session 또는 local을 빼고 @@변수명만 사용할 시에는 기본적으로 세션의 변수설정 값을 보여준다.
#세션 레벨에서 시스템 변수 값 변경 mysql> set sql_mode = 'STRICT_TRANS_TABLES' ; Query OK, 0 rows affected (0.00 sec)
글로벌 변수를 변경하려면 mysql> set global sql_mode = 'STRICT_TRANS_TABLES' ;
#show 명령을 이용하여 시스템 변수 값 확인 mysql> show global variables like 'sql_mode' ; +---------------+----------------------------------------+ | Variable_name | Value | +---------------+----------------------------------------+ | sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES | +---------------+----------------------------------------+ 1 row in set (0.00 sec)
mysql> show session variables like 'sql_mode' ; +---------------+---------------------+ | Variable_name | Value | +---------------+---------------------+ | sql_mode | STRICT_TRANS_TABLES | +---------------+---------------------+ 1 row in set (0.00 sec)
mysql> show variables like 'sql_mode' ; +---------------+---------------------+ | Variable_name | Value | +---------------+---------------------+ | sql_mode | STRICT_TRANS_TABLES | +---------------+---------------------+ 1 row in set (0.00 sec)
#@@를 이용하여 변수 값 확인 mysql> select @@global.sql_mode ; +----------------------------------------+ | @@global.sql_mode | +----------------------------------------+ | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES | +----------------------------------------+ 1 row in set (0.00 sec)
mysql> select @@local.sql_mode ; +---------------------+ | @@local.sql_mode | +---------------------+ | STRICT_TRANS_TABLES | +---------------------+ 1 row in set (0.00 sec)
mysql> select @@session.sql_mode ; +---------------------+ | @@session.sql_mode | +---------------------+ | STRICT_TRANS_TABLES | +---------------------+ 1 row in set (0.00 sec)
mysql> select @@sql_mode ; +---------------------+ | @@sql_mode | +---------------------+ | STRICT_TRANS_TABLES | +---------------------+ 1 row in set (0.00 sec)
|
global 시스템 변수 들은 일반적으로 서버가 기동 될때 설정되는데, /etc/my.cnf 파일에 명시적으로 설정 하는 방법과 기동 시 "--변수=값" 으로 지정하는 방법이 있다.
두 개가 동시에 설정된 변수는 기동 시 command 라인에 주어지는 "--변수=값"이 적용된다.
크기나 길이를 나타내는 변수들은 특별한 설정이 없으면 byte 단위로 지정된다. 'K' , 'M' , 'G' 를 사용하여 지정해 줄 수 있다.(대소문자 안 가림)
다음은 다양한 방법을 이용한 변수 설정 방법
# global 변수 선언
set global var_name = value ; set @@global.var_name = value ;
# Session 변수 선언
set session var_name = value ; set var_name = value; set @@session.var_name = value ; set @@var_name = value;
# 다른 변수 값 참조
set session read_buffer_size = 2 * @@global.read_buffer_size ;
# 한 번에 여러변수 설정 하기
set session sql_warnings =0 , global default_storage_engine = InnoDB ; set global v1 = val1 , v2 = val2 , session v3 = val3 , v4 = val4 ; v1, v2는 global, v3, v4는 session 변수
|
6.2 상태 변수
MySQL 서버 수행 중 서버의 성능 관련 정보를 제공해 줌
상태 변수들은 show status 명령어로 확인 할 수 있다. global, Session 둘 다 있음
시스템 변수 변경으로 인한 성능 개선 정도는 상태 변수의 정보를 통해서 확인할 수 있다. 설정은 불가능 하고
information_schema 데이터 베이스의 global_status , session_status 테이블을 조회할 수 도 있다.
5.6이상 버전이면 mysql> set global show_compatibility_56 = 1 ; 수행해 주어야 함.
mysql> set @uptime = (select variable_value from information_schema.global_status where variable_name = 'uptime') ; Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select @uptime ; +---------+ | @uptime | +---------+ | 2794 | +---------+ |
7. PLUG-IN
MySQL은 스토리지 엔진, information_schema 테이블, 복제 매카니즘, 인증 등 다양한 기능을 플러그 인 방식으로 구현한다.
그래서 DBA는 자신에게 맞는 기능을 플러그 인 방식으로 사용할 수 있다.
기본적으로 plugin 파일은 설치 디렉터리 안에 lib/plugin 디렉터리 안에 존재 한다. 하지만 plugin_dir 변수를 이용하여 다른 곳으로 지정 할 수 있다.
install plugin 명령을 이용하여 플러그 인을 로딩하고, 등록 시킬 수 있다.
플러그인 파일은 리눅스인 경우 확장자가 *.so이고, 윈도우인 경우는 *.dll 이다.
로딩 하는 방법은 command line에서 --plugin-load나 --plugin-load-add 옵션을 사용하거나, /etc/my.cnf 파일에 명시적으로 기록
plugin-load는 여러 번 사용 시 가장 마지막 하나의 값만 인식되는 반면, plugin-load-add 플러그인 목록에 계속 추가한다.
#plugin-load 설정
[mysqld] plugin-load=my_engine.so;info_tables.so
또는 플러그 인을 개별로 나열 plugin-load=my_engine=my_engine.so;locks=info_tables.so;users=info_tables.so
info_tables.so 중에 locks만 로딩 하고 싶으면 plugin-load=locks=info_tables.so
#plugin-load는 마지막 하나만 적용된다.
[mysqld] plugin-load=my_engine.so 다른 설정들…. plugin-load=info_tables.so
위와 같이 하면 info_tables.so만 적용 됨.
#plugin-load-add
[mysqld] plugin-load-add=my_engine.so 다른 설정들…. plugin-load-add=info_tables.so
#운영 중에 플러그인 로드 (내부적으로 mysql.plugin 테이블에 플러그인을 등록 함)
INSTALL PLUGIN my_engine SONAME 'my_engine.so' ; INSTALL PLUGIN locks SONAME 'info_tables.so' ; INSTALL PLUGIN users SONAME 'info_tables.so' ;
#플러그인 제거 (다음 재 시작 시 자동으로 로드 시키지 않음)
UNINSTALL PLUGIN my_engine ; UNINSTALL PLUGIN locks ;
|
#플러그인 파일 위치 확인
mysql> show global variables like 'plugin_dir' ; +---------------+------------------------------+ | Variable_name | Value | +---------------+------------------------------+ | plugin_dir | /usr/local/mysql/lib/plugin/ | +---------------+------------------------------+ 1 row in set (0.00 sec)
[root@mysqlent5 ~]# ls /usr/local/mysql/lib/plugin/ adt_null.so innodb_engine.so libtest_services.so libtest_sql_cmds_1.so libtest_sql_shutdown.so mypluglib.so semisync_slave.so audit_log.so keyring_file.so libtest_services_threaded.so libtest_sql_commit.so libtest_sql_sqlmode.so mysql_no_login.so test_security_context.so authentication_pam.so keyring_okv.so libtest_session_detach.so libtest_sql_complex.so libtest_sql_stored_procedures_functions.so mysqlx.so test_udf_services.so auth_socket.so keyring_udf.so libtest_session_info.so libtest_sql_errors.so libtest_sql_views_triggers.so openssl_udf.so thread_pool.so debug libmemcached.so libtest_session_in_thd.so libtest_sql_lock.so libtest_x_sessions_deinit.so rewrite_example.so validate_password.so firewall.so libpluginmecab.so libtest_sql_2_sessions.so libtest_sql_processlist.so libtest_x_sessions_init.so rewriter.so version_token.so ha_example.so libtest_framework.so libtest_sql_all_col_types.so libtest_sql_replication.so locking_service.so semisync_master.so
[root@mysqlent5 ~]# ls /usr/local/mysql/lib/plugin/ | wc -l 48
#등록된 플러그 인 확인 mysql> show plugins ; +----------------------------+----------+--------------------+---------+-------------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+---------+-------------+ | binlog | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | mysql_native_password | ACTIVE | AUTHENTICATION | NULL | PROPRIETARY | | sha256_password | ACTIVE | AUTHENTICATION | NULL | PROPRIETARY | | InnoDB | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | PROPRIETARY | | PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | MyISAM | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | MEMORY | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | CSV | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | partition | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | FEDERATED | DISABLED | STORAGE ENGINE | NULL | PROPRIETARY | | ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | | ngram | ACTIVE | FTPARSER | NULL | PROPRIETARY | +----------------------------+----------+--------------------+---------+-------------+ 44 rows in set (0.00 sec)
mysql> select plugin_name , plugin_status , plugin_version , plugin_type from information_schema.plugins ; +----------------------------+---------------+----------------+--------------------+ | plugin_name | plugin_status | plugin_version | plugin_type | +----------------------------+---------------+----------------+--------------------+ | binlog | ACTIVE | 1.0 | STORAGE ENGINE | | mysql_native_password | ACTIVE | 1.1 | AUTHENTICATION | | sha256_password | ACTIVE | 1.1 | AUTHENTICATION | | InnoDB | ACTIVE | 5.7 | STORAGE ENGINE | | INNODB_TRX | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_LOCKS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_LOCK_WAITS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMP | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMP_RESET | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMPMEM | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMPMEM_RESET | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMP_PER_INDEX | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_CMP_PER_INDEX_RESET | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_BUFFER_PAGE | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_BUFFER_PAGE_LRU | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_BUFFER_POOL_STATS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_TEMP_TABLE_INFO | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_METRICS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_DEFAULT_STOPWORD | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_DELETED | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_BEING_DELETED | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_CONFIG | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_INDEX_CACHE | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_FT_INDEX_TABLE | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_TABLES | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_TABLESTATS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_INDEXES | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_COLUMNS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_FIELDS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_FOREIGN | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_FOREIGN_COLS | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_TABLESPACES | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_DATAFILES | ACTIVE | 5.7 | INFORMATION SCHEMA | | INNODB_SYS_VIRTUAL | ACTIVE | 5.7 | INFORMATION SCHEMA | | PERFORMANCE_SCHEMA | ACTIVE | 0.1 | STORAGE ENGINE | | MRG_MYISAM | ACTIVE | 1.0 | STORAGE ENGINE | | MyISAM | ACTIVE | 1.0 | STORAGE ENGINE | | MEMORY | ACTIVE | 1.0 | STORAGE ENGINE | | CSV | ACTIVE | 1.0 | STORAGE ENGINE | | BLACKHOLE | ACTIVE | 1.0 | STORAGE ENGINE | | partition | ACTIVE | 1.0 | STORAGE ENGINE | | FEDERATED | DISABLED | 1.0 | STORAGE ENGINE | | ARCHIVE | ACTIVE | 3.0 | STORAGE ENGINE | | ngram | ACTIVE | 0.1 | FTPARSER | +----------------------------+---------------+----------------+--------------------+ 44 rows in set (0.00 sec)
|
8. 스토리지 엔진
스토리지 엔진이란 테이블 핸들러라는 이름으로 불리었다.
사용하지 않는 불 필요한 스토리지 엔진은 비 활성화 시켜서 메모리 리소스 낭비를 막는다.
(--archive=OFF --blackhole=OFF --federated=OFF --innodb=OFF)
#기본 스토리지 엔진 확인
mysql> show global variables like 'default_storage_engine' ; +------------------------+--------+ | Variable_name | Value | +------------------------+--------+ | default_storage_engine | InnoDB | +------------------------+--------+
mysql> show global variables like 'default_tmp_storage_engine' ; +----------------------------+--------+ | Variable_name | Value | +----------------------------+--------+ | default_tmp_storage_engine | InnoDB | +----------------------------+--------+
#자신의 서버에서 지원하는 스토리지 엔진 확인
mysql> show engines ; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | CSV | YES | CSV storage engine | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ 9 rows in set (0.00 sec)
support : 해당 엔진 지원 여부 xa : 분산 트랜잭션을 지원하는지 여부 savepoint : 부분 트랜잭션 롤백을 지원하는지 여부
# 각각의 디비(테이블)에서 사용하는 스토리지 엔진 확인 방법
MariaDB [(none)]> SELECT table_schema , table_name , engine FROM information_schema.tables WHERE table_schema IN ('HOME001' ,'mysql','performance_schema') ; +--------------------+----------------------------------------------+--------------------+ | table_schema | table_name | engine | +--------------------+----------------------------------------------+--------------------+ | HOME001 | tbl_bgm | TokuDB | | HOME001 | tbl_bookmark_me | TokuDB | | HOME001 | tbl_folder | TokuDB | | HOME001 | tbl_friend | TokuDB | | HOME001 | tbl_group | TokuDB | | HOME001 | tbl_group_member | TokuDB | | HOME001 | tbl_home | TokuDB | | HOME001 | tbl_home_deco | TokuDB | | HOME001 | tbl_home_delete_log | TokuDB | | HOME001 | tbl_home_tag | TokuDB | | HOME001 | tbl_like | TokuDB | | HOME001 | tbl_link | TokuDB | | HOME001 | tbl_linker | TokuDB | | HOME001 | tbl_mylike | TokuDB | | HOME001 | tbl_network_update | InnoDB | | HOME001 | tbl_news | TokuDB | | HOME001 | tbl_news_get | TokuDB | | HOME001 | tbl_post | TokuDB | | HOME001 | tbl_reply | TokuDB | | HOME001 | tbl_tag | TokuDB | | HOME001 | tbl_visit_count | TokuDB | | HOME001 | tbl_visit_count_bak | TokuDB | | mysql | columns_priv | MyISAM | | mysql | db | MyISAM | | mysql | event | MyISAM | | mysql | func | MyISAM | | mysql | general_log | CSV | | mysql | help_category | MyISAM | | mysql | help_keyword | MyISAM | | mysql | help_relation | MyISAM | | mysql | help_topic | MyISAM | | mysql | host | MyISAM | | mysql | ndb_binlog_index | MyISAM | | mysql | plugin | MyISAM | | mysql | proc | MyISAM | | mysql | procs_priv | MyISAM | | mysql | proxies_priv | MyISAM | | mysql | servers | MyISAM | | mysql | slow_log | CSV | | mysql | tables_priv | MyISAM | | mysql | time_zone | MyISAM | | mysql | time_zone_leap_second | MyISAM | | mysql | time_zone_name | MyISAM | | mysql | time_zone_transition | MyISAM | | mysql | time_zone_transition_type | MyISAM | | mysql | user | MyISAM | | performance_schema | cond_instances | PERFORMANCE_SCHEMA | | performance_schema | events_waits_current | PERFORMANCE_SCHEMA | | performance_schema | events_waits_history | PERFORMANCE_SCHEMA | | performance_schema | events_waits_history_long | PERFORMANCE_SCHEMA | | performance_schema | events_waits_summary_by_instance | PERFORMANCE_SCHEMA | | performance_schema | events_waits_summary_by_thread_by_event_name | PERFORMANCE_SCHEMA | | performance_schema | events_waits_summary_global_by_event_name | PERFORMANCE_SCHEMA | | performance_schema | file_instances | PERFORMANCE_SCHEMA | | performance_schema | file_summary_by_event_name | PERFORMANCE_SCHEMA | | performance_schema | file_summary_by_instance | PERFORMANCE_SCHEMA | | performance_schema | mutex_instances | PERFORMANCE_SCHEMA | | performance_schema | performance_timers | PERFORMANCE_SCHEMA | | performance_schema | rwlock_instances | PERFORMANCE_SCHEMA | | performance_schema | setup_consumers | PERFORMANCE_SCHEMA | | performance_schema | setup_instruments | PERFORMANCE_SCHEMA | | performance_schema | setup_timers | PERFORMANCE_SCHEMA | | performance_schema | threads | PERFORMANCE_SCHEMA | +--------------------+----------------------------------------------+--------------------+ 63 rows in set (0.04 sec)
#엔진 종류 archive : 데이터를 압축해서 저장 함.(인서트 후 행의 변경 없음) blackhole : 쓰기는 무시하고 비어 있는 값을 반환하는 엔진 csv : 컴마로 구분된 값의 형태로 저장 federated : 원격 테이블 접속을 위한 엔진 mrg_myisam : MyISAM 테이블의 집합 관리
# 엔진에 의해서 생성 된 파일 InnoDB : *.frm(메타정보) ,*.ibd (데이터 와 인덱스가 저장됨) MyISAM : *.frm(메타정보), *.MYD(데이터) , *.MYI(인덱스) CSV : *.CSV(데이터), *.CSM(메타데이터) Memory : *.frm(메타정보)
|
InnoDB 스토리지 엔진
# InnoDB엔진에서 하나의 테이블 스페이스를 사용할 경우
mysql> show global variables like 'innodb_data_home_dir' ; -- 테이블 스페이스를 구성하는 컴퍼넌트들의 부모 디렉터리, 미 지정 시 datadir +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_data_home_dir | | +----------------------+-------+ 1 row in set (0.00 sec)
mysql> show global variables like 'innodb_data_file_path' ; -- 테이블 스페이스를 구성하는 파일들의 정보 저장. 하나 이상의 파일이 ;로 구분 +-----------------------+------------------------+ | Variable_name | Value | +-----------------------+------------------------+ | innodb_data_file_path | ibdata1:12M:autoextend | -- ibdata1이라는 테이블스페이스가 초기 12M 크기이며 자동 증가된다. +-----------------------+------------------------+
예를 들어서 2개의 테이블스페이스(tbs1, tbs2)를 /usr/tbs 밑에 만들면서 각각 4G짜리로 만든다고 하면
innodb_data_home_dir = /usr/tbs innodb_data_file_path = tbs1:4G:autoextend;tbs2:4G:autoextend
또는
innodb_data_home_dir = innodb_data_file_path = /usr/tbs/tbs1:4G:autoextend;/usr/tbs/tbs2:4G:autoextend
자동 증가 사이즈는 다음 변수 값이 적용 된다.
mysql> show global variables like 'innodb_autoextend_increment' ; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | innodb_autoextend_increment | 64 | +-----------------------------+-------+
Free Space 확인
mysql> SELECT tablespace_name , sum(data_free) as freespace -> FROM information_schema.partitions -> WHERE tablespace_name is not null -> GROUP BY tablespace_name ;
# InnoDB엔진에서 테이블당 개별 파일로 관리하고자 한다면 다음의 변수 설정
mysql> show global variables like 'innodb_file_per_table' ; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+
기본은 하나의 테이블 스페이스로 관리를 하지만, 특정 테이블만 파일 형태로 관리 하고 싶으면 다음과 같이 사용할 수 있다.
set global innodb_file_per_table = 1 ; CREATE TABLE abcd …. ENGINE=INNODB ROW_FORMAT=COMPRESSED ; set global innodb_file_per_table = 0 ;
# InnoDB를 사용할 경우 파일 포멧
mysql> show global variables like 'innodb_file_format' ; +--------------------+-----------+ | Variable_name | Value | +--------------------+-----------+ | innodb_file_format | Barracuda | +--------------------+-----------+
# InnoDB 변수 들 중 동작에 영향을 주는 변수들
mysql> show global variables like 'innoDB%' ; +------------------------------------------+------------------------+ | Variable_name | Value | +------------------------------------------+------------------------+ | innodb_buffer_pool_size | 134217728 | | innodb_log_buffer_size | 16777216 | | innodb_log_file_size | 50331648 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | +------------------------------------------+------------------------+
innodb_buffer_pool_size : Physical I/O를 줄일 목적 innodb_log_buffer_size : 로그 버퍼의 사이즈 innodb_log_file_size : 개별 로그파일 사이즈 innodb_log_files_in_group : 로그 그룹의 개수 innodb_log_group_home_dir : 로그 파일 위치
로그 파일의 이름은 ib_로 시작한다.
[root@mysqlent5 data]# ls -al ib_* -rw-r----- 1 mysql mysql 551 Dec 7 18:00 ib_buffer_pool -rw-r----- 1 mysql mysql 50331648 Dec 7 19:59 ib_logfile0 -rw-r----- 1 mysql mysql 50331648 Dec 4 00:12 ib_logfile1
|
9. Globalization
MySQL설정과 관련된 국제화(Internationalization)와 지역화(Localization) 관점
1. 서버의 기본 시간대 (time zone)
2. 기본 문자세트와 콜레이션
3. 진단과 에러 메시지를 위한 언어
4. 요일과 월 이름 지정
9.1 기본 시간대
기본적으로 시스템 상의 시간대를 많이 사용하게 된다.
연관이 있는 시스템 변수로는 global.system_time_zone , global.time_zone, session.time_zone 이 있다.
system_time_zone은 시스템의 시간을 사용하게 되지만, TZ 환경변수를 사용해서 변경 할 수 있다.
time_zone의 기본 설정 값은 system_time_zone의 값을 사용하는 SYSTEM이다.
# 서버 호스트에 영향을 주는 시스템 시작 시점에 결정되는 시간대 (동적 변경 안됨)
mysql> show global variables like 'system_time_zone' ; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | KST | +------------------+-------+
# MySQL 서버의 기본 시간대
mysql> show global variables like 'time_zone' ; +---------------+--------+ | Variable_name | Value | +---------------+--------+ | time_zone | SYSTEM | +---------------+--------+
mysql> show variables like 'time_zone' ; +---------------+--------+ | Variable_name | Value | +---------------+--------+ | time_zone | SYSTEM | +---------------+--------+
mysql> select @@global.time_zone , @@session.time_zone ; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | SYSTEM | +--------------------+---------------------+
세션에서 로케일을 참조하려면
set session time_zone = 'US/Central' ; set session time_zone = 'CST6CDT' ; set session time_zone = 'Asia/Jakarta' ;
|
9.2 기본 캐릭터 셋과 콜레이션
캐릭터 셋은 문자열 값으로 허용된 문자를 결정한다. MySQL은 다중 문자 세트를 지원한다. ( show character set / show collation )
콜레이션은 문자 비교와 정렬에 영향을 준다.
캐릭터 셋과 콜레이션은 char, varchar, text, enum, set 자료형에 영향을 미친다.
캐릭터 셋은 서버, 데이터 베이스, 테이블, 칼럼 등에서 개별적으로 명시해 줄 수 있으며, 명시적으로 콜레이션을 지정해 줄 수도 있다.
서버는 인덱스가 생성된 칼럼의 콜레이션을 변경 할 경우 자동으로 인덱스를 재 정렬 시킨다.
기본 캐릭터 셋은 latin1 이고, 콜레이션은 latim1_swedish_1 이다.
콜레이션은 반드시 캐릭터 셋과 호환이 되어야 한다. (show collation으로 확인)
변경하고자 한다면 시작시점에 command-line 또는 /etc/my.cnf 파일에 명시해 준다.
에러 메세지용 언어 설정은 lc_messages 시스템 변수로 설정 한다.
# 기본 캐릭 터 셋과 콜레이션
mysql> show global variables like 'character\_set\_%' ; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | euckr | | character_set_connection | euckr | | character_set_database | euckr | | character_set_filesystem | binary | | character_set_results | euckr | | character_set_server | euckr | | character_set_system | utf8 | +--------------------------+--------+ 7 rows in set (0.00 sec)
mysql> show global variables like 'collation\_%' ; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | euckr_korean_ci | | collation_database | euckr_korean_ci | | collation_server | euckr_korean_ci | +----------------------+-----------------+
|
# 캐릭터 셋과 콜레이션 지정 방법
- DB Level CREATE DATABASE db_name CHARACTER SET charset COLLATE collation ;
- Table Level CREATE TABLE tb_name ( …… ) CHARACTER SET charset COLLATE collation ;
- Table & Column Level CREATE TABLE tb_name ( id char(10) CHARACTER SET charset COLLATE collation , ……. ) CHARACTER SET another_charset COLLATE another_collation ;
# 특정 캐릭터 셋으로 정렬(콜레이션)을 하고 싶다면 COLLATE 연산자
SELECT c FROM tab ORDER BY c COLLATE latin1_spanish_ci ;
|
9.3 에러 메시지용 언어 설정
MySQL 서버는 진단과 에러 메시지를 다양한 언어로 지원한다.
기본 값은 english이며, 사용 가능한 언어를 확인해 보려면 설치된 MySQL의 Shared 디렉터리 안의 서브 디렉터리들의 이름을 확인하면 된다.
# 에러 메시지용 언어 설정
mysql> show global variables like 'lc_messages%' ; +-----------------+-------------------+ | Variable_name | Value | +-----------------+-------------------+ | lc_messages | en_US | | lc_messages_dir | /usr/share/mysql/ | +-----------------+-------------------+
lc_messages_dir은 에러 메시지 파일이 있는 디렉터리 임.
|
9.4 로케일 설정
lc_time_names 시스템 변수를 이용하여 날짜와 월 이름을 표현하는 방식을 결정한다.
해당 변수는 dayname() , monthname() , date_format()함수등에 영향을 준다.
# 로케일 시스템 변수 확인
mysql> show global variables like 'lc_time_names' ; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | lc_time_names | en_US | +---------------+-------+
mysql> select dayname (now()) , monthname(now()) ; +-----------------+------------------+ | dayname (now()) | monthname(now()) | +-----------------+------------------+ | Friday | December | +-----------------+------------------+
# 세션레벨에서 로케일 변수 변경
mysql> set session lc_time_names = 'es_ES' ;
mysql> select dayname (now()) , monthname(now()) ; +-----------------+------------------+ | dayname (now()) | monthname(now()) | +-----------------+------------------+ | viernes | diciembre | +-----------------+------------------+ |
10. 서버 튜닝
사용 중인 서버의 성능을 극대화 하기 위한 최적화 방법으로 시스템 파라미터 튜닝이 있다.
파라미터를 변경 할 때는 한번에 하나씩 변경해 가면서 변화에 대한 영향을 평가해야 한다.
시스템 변수를 점진적으로 증가 시킨다. 한번에 증가 시킬 경우 시스템의 리소스 부족을 초래 할 수 있다.
직접 운영서버에 반영 하기 보다는 테스트 서버에서 반영 후 이상이 없을 경우 운영 서버에 반영을 시도한다.
불 필요한 스토리지 엔진은 비활성화 한다. (서버에 불 필요한 메모리 공간 할당을 하지 않게 함으로써 리소스 낭비를 막는다.)
10.1 일반적인 시스템 변수
연결 |
max_connections |
최대 동시 클라이언트 접속자 수 . Max_used_connections / Connection_errors_max_connections 상태 지표값을 참조 하면서 증가 시킨다. |
|
|
back_log |
현재 연결을 진행하는 중에 다른 연결 요청이 오면 지연 요청 큐에 담을 수 있는 최대 개수. 접속자가 많은 사이트에서 클라이언트 접속이 느리게 진행되면 이 값을 증가 시킨다. |
|
테이블 |
table_open_cache |
서버가 테이블 파일을 열고 닫는 동작을 최소화 하기 위해 되도록이면 열린 상태를 유지한다. 이를 위해 테이블 캐시가 열린 파일들의 정보를 유지한다. 동시에 접근하는 테이블이 많을 경우 캐시가 금방 차게 되는데, Opened_tables / Table_open_cache_overflows 상태 지표를 참조하여 증가 시킨다. |
|
|
table_definition_cache |
table_open_cache값을 증가 시키면 table_definition_cache의 증가도 같이 고려해야 한다. .frm 파일의 정보를 저장하는 캐시의 크기이다. Opened_table_definitions 상태 지표를 참조하여 증가 시킨다. |
|
|
open_files_limit |
max_connections나 table_open_cache의 값을 증가 시키면 서버는 많은 수의 파일 디스크립터를 사용함으로써 운영체제의 프로세스별 파일 디스크립터 개수 제한을 넘어서는 문제가 발생 할 수 있다. 이 제한 값을 우회하는 방법으로는 다음과 같은 방법이 있다.
|
|
통신 |
max_allowed_packet |
blob나 text값을 포함하는 긴 수행문을 보내는 클라이언트의 경우 서버단과 클라이언트단 모두에서 max_allowed_packet변수 값을 증가 시킨다. |
|
쿼리 |
read_buffer_size |
세션에서 사용하는 읽기 버퍼. 세션별로 할당이 되므로 과도하게 크게 설정이 되면 시스템 리소스 부족을 초래 할 수 있다. 필요 시 세션레벨에서 변경해서 사용. |
|
|
sort_buffer_size |
세션에서 사용하는 정렬 버퍼. 정렬이 사용되지 않으면 할당되지 않는다. 세션별로 할당이 되므로 과도하게 크게 설정이 되면 리소스 부족을 초래 할 수 있다. 필요 시 세션 레벨에서 변경해서 사용. |
|
|
join_buffer_size |
세션에서 사용하는 쿼리에 조인이 있을 경우에 할당되어 사용됨. 여러 개의 조인이 있을 경우 복수개의 조인 버퍼가 할당되어 사용됨. |
10.2 스토리지 엔진 튜닝
스토리지 엔진 별로 서로 다른 테이블 정보 캐시를 가진다.
InnoDB는 버퍼 풀, MyISAM DB는 key buffer라고 부르지만 기본 원리는 다음과 같다.
1. 초기 캐시는 비어 있다.
2. 쿼리 수행 시 테이블의 데이터를 확인하기 위하여 먼저 캐시를 확인하고, 맞는 내용이 있으면 메모리의 값을 사용한다. 메모리에 원하는 값이 없으면
디스크에서 읽어서 메모리로 캐시한 후에 사용한다.
3. 새로 읽어야 하는 값이 있는데 캐시가 가득 찼다면, 오래된 캐시를 제거하여 필요한 공간을 확보한다. 만약 제거해야 할 캐시가 변경된 상태라면 변경 내역을
테이블에 반영하고 해당 캐시를 사용한다.
innodb_buffer_pool_size |
버퍼 풀의 총 사이즈(단위는 바이트) |
innodb_buffer_pool_instances |
버퍼 풀의 총 사이즈 안에서 몇 개의 작은 버퍼 풀로 나누어 사용할지 개수 지정 |
innodb_old_blocks_pct |
|
innodb_old_blocks_time |
일회성 full table 스캔 같은 경우, 한 번 접근 후 더 이상의 접근이 없는 데이터 임에도 이 데이터 들로 인해서 다른 데이터 들이 캐시에서 밀려날 수 있다. 그래서 이런 쿼리가 수행될 때는 이 값을 0 이상으로 주어서 기존 캐시의 데이터에 영향을 주지 않게 한다.
그러나 시스템 재 부팅 후 preload를 할 경우는, full table 스캔으로 자주 사용하는 테이블의 데이터를 로드 시켜 놓아야 하기 때문에 이 값을 0 으로 준 후에 데이터를 로드 시켜 주고, 다시 0보다 큰 값으로 변경 시켜 준다. |
MyISAM은 데이터와 인덱스를 분리해 저장하고 다르게 처리한다. (실제 파일이 나뉘어서 저장됨을 보면 알 수 있다.)
MyISAM 스토리지 엔진에 가장 큰 영향을 주는 것은 키 버퍼 크기다. (key_buffer_size)
동일 테이블이나 인덱스에 대한 경합은 해당 테이블이나 인덱스를 모두 담을 수 있는 크기로 키 버퍼를 크게 해 주면 된다.
10.3 query cache 사용
반복적으로 사용되는 쿼리를 위한 쿼리 캐시를 사용하여, 쿼리문의 성능을 향상 시킬 수 있다.
동일 SQL문이 수행되면 동일한 SQL을 수행하지 않고, 쿼리 캐시에 있는 결과를 반환한다.
참조하는 테이블이 변경이 되면, 해당 쿼리는 무효화 된다.
오라클의 result cache라고 생각하면 된다.
쿼리 캐시는 성능을 향상 시키지만, 사이즈가 지나치게 크게 되면, 쿼리 캐시 내에서 동일 SQL문을 찾는데 과도한 시간을 보내게 될 수 있다.
show processlist에서 state 칼럼에 waiting for query cache lock을 자주 보게 된다면, 쿼리 캐시 접근 경합이 발생하는 것이므로 쿼리 캐시를 끄는 것을 고려해 봐야 한다.
# 쿼리 캐시 관련 시스템 변수
mysql> show global variables like '%query%' ; +------------------------------+-----------------------------------+ | Variable_name | Value | +------------------------------+-----------------------------------+ | have_query_cache | YES | | query_alloc_block_size | 8192 | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 1048576 | | query_cache_type | OFF | | query_cache_wlock_invalidate | OFF | | query_prealloc_size | 8192 | +------------------------------+-----------------------------------+
have_query_cache : 시스템에서 쿼리 캐시를 지원하는지 여부 확인 query_cache_type : 0 (OFF) : OFF 1 (ON) : SELECT SQL_NO_CACHE로 시작하는 것만 제외하고 저장 가능한 쿼리 다 저장 2 (DEMAND): SELECT SQL_CACHE로 시작하는 것들 중 저장 가능한 쿼리 저장 query_cache_size : 캐시로 할당하는 메모리 사용량. query_cache_type이 0 이더라도 이 메모리는 할당 됨. 사용하지 않을 때는 0으로설정 query_cache_limit : 쿼리 결과로 저장할 수 있는 최대 결과 값 지정. 이 값보다 크면 저장 안됨.
|
11. 서버로그
로그는 문제를 분석, 서버 성능 향상, 서버 복제, 장애 복구 시에 유용하게 사용된다.
에러로그는 시작과 종료를 기록하고, 문제와 예외 상황에 대한 메시지도 기록 함.
일반 질의 로그는 클라이언트 연결과 클라이언트가 요청한 SQL문, 기타 이벤트에 대한 정보를 기록한다.
bin로그는 DML, DDL등의 변경 내역을 기록하는 로그 파일로 장애 발생 시, 기존 백업으로 복구 후 mysqlbinlog를 이용하여 바이너리 내용을 텍스트로 변경 후 이 내용을 반영하여 데이터 베이스를 복구 시키는데 사용된다. 또한 Slave로 전송되어서 최신의 데이터를 유지하는 데에도 사용된다.
로그들 중에서 일반 질의 로그가 서버를 모니터링 하는데 가장 유용하나, 디스크 공간 사용 측면에서 끄는 경우가 많다.
# 로그 설정 시스템 변수들
mysql> show global variables like '%log%' ; +-----------------------------------------+-----------------------------------+ | Variable_name | Value | +-----------------------------------------+-----------------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/localhost.log | | innodb_log_group_home_dir | ./ | | log_bin | ON | | log_bin_basename | /var/lib/mysql/mysql-bin | | log_bin_index | /var/lib/mysql/mysql-bin.index | | log_error | /var/log/mysqld.log | | log_output | FILE,TABLE | | log_warnings | 2 | | relay_log | | | relay_log_basename | | | relay_log_index | | | slow_query_log | ON | | slow_query_log_file | /var/lib/mysql/localhost-slow.log | +-----------------------------------------+-----------------------------------+
general_log : 일반 쿼리 로그 활성화 general_log_file : 일반 쿼리 로그 파일 위치 log_bin : 바이너리 로그 활성 화 log_bin_basename : 바이너리 로그 파일 이름 log_bin_index : 바이너리 로그 인덱스 파일 log_error : 에러 로그 파일 log_output : 에러 로그 및 일반 쿼리 로그 출력 위치 log_warnings : 에러 로그의 로깅 정보의 양 조절 slow_query_log : 슬로우 쿼리 로그 활성화 slow_query_log_file : 슬로우 쿼리 로그 파일 위치 innodb_log_group_home_dir : InnoDB가 엔진 자동 복구를 위하여 사용하는 로그가 저장되는 위치 (기본은 datadir 위치 )
일반 로그와 슬로우 쿼리 로그를 테이블로 아웃풋 되게 했다면 주기적으로 다음 명령을 수행해서 사이즈를 줄여야 한다.
mysql> use mysql
mysql> truncate general_log ;
mysql> truncate slow_log ;
|
로그 플러싱(log flushing)
버퍼된 로그 정보를 디스크에 확실히 써지게 하기 위한 명령으로, 오라클로 따지면 switch logfile 정도로 보면 될 것이다.
mysqladmin flush-logs 명령이나 FLUSH LOGS 명령문을 수행
버퍼 캐시 안의 데이터 까지도 플러싱 하고 싶으면 mysqladmin refresh 명령을 이용한다.
# 로그 플러싱
mysql> show master status ; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000183 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+
mysql> flush logs ;
mysql> show master status ; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000184 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+
[root@localhost ~]# mysqladmin -u root -p flush-logs
mysql> show master status ; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000185 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+
[root@localhost ~]# mysqladmin -u root -p refresh
mysql> show master status ; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000186 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+
# 로그 플러 시 만을 위한 계정 생성
CREATE USER 'flush'@'localhost' IDENTIFIED BY 'flushpass' ; GRANT RELOAD ON *.* TO 'flush'@'localhost' ;
# 마스터 서버에서 bin log 삭제하기 마스터 서버에서 bin 로그를 삭제하기 전에 slave 서버에서 해당 로그들이 다 반영되었는지 확인 후 삭제를 해야 한다. 마스터 서버에서는 슬레이브 서버가 몇 개 기동중이며, 어디까지 반영 되었는지 모르기 때문에 일일이 슬레이브에 접속해서 show slave status를 수행 후 master_log_file 값을 확인해 봐야 한다.
확인 후 삭제 해도 되는 로그 번호를 확인 한 후에 예를 들어서 40번까지 삭제해도 된다고 한다면…
mysql> purge binary logs to 'mysql-bin.000041' ; 41보다 작은 것 삭제 하라는 명령임.
|
12. 멀티 서버 운영 주의사항
하나의 머신에서 여러 개의 서버를 운영 할때, 엔진을 설치 하거나 하는 경우 기존 운영중인 데이터베이스와의 충돌이 없어야 하므로 다음 사항들을 주의 하자.
엔진 설치는 기본으로 /var/mysql아래에 설치를 하되, 설치 버전명으로 디렉터리를 구분하여 설치 하도록 하자.
(cmake -DCMAKE_INSTALL_PREFIX=/var/mysql/50525 )
모든 서버에서 공통으로 사용하는 서버변수는 /etc/my.cnf 파일에 저장시켜 놓고, 개별 서버들의 설정은 다른 임의의 파일에 저장 시켜 놓은 후에
--default-extra-file=file_name으로 지정해서 사용할 수 있다.
또는 하나의 /etc/my.cnf 파일에 mysql_multi 스크립트를 사용.
다음의 시스템 변수의 설정을 확인하자.
basedir=dir_name |
MySQL 설치 루트 디렉터리의 경로명 |
datadir=dir_name |
데이터 디렉터리의 경로명 |
port=port_num |
TCP/IP 연결을 위한 포트 번호 |
socket=file_name |
유닉스 소켓파일 경로명 또는 윈도우 네임드 파이프명 |
general_log |
일반 로그 활성화 |
general_log_file=file_name |
일반 로그 파일명 |
log_bin=file_name |
바이너리 로그 활성화 |
log_bin_index=file_name |
바이너리 로그 인덱스 파일 |
log_error=file_name |
에러로그 활성 화 |
log_output=destination |
일반로그 및 슬로우 쿼리 로그 출력 위치 |
pid_file=file_name |
프로세스 ID 파일 |
slow_query_log |
슬로우 쿼리 로그 활성화 |
slow_query_log_file=file_name |
슬로우 쿼리 로그 파일 |
MySQL multi 스크립트
여러 서버를 사용할 때 MySQL Multi 스크립트를 사용하는 것이 가장 간편하다.
multi 스크립트는 서버 시작 시에 특정 번호(n)에 기반을 두고 동작한다.
/etc/my.cnf 파일에 [mysqln] 으로 구분지어서 시스템 변수를 설정 할 수 있다.
서버 기동 시에 mysqld_multi --nolog start 1 또는 한번에 여러 대 기동 시키기 위해서는 mysqld_multi --nolog 1,2,3
비밀번호를 일일이 써 주는 것은 보안상 안 좋으므로 .my.cnf 파일에 다음과 같이 설정 한다.
[mysqld_multi]
13. 보안과 접근
적절한 권한을 가진 사용자만이 데이터에 접근 할 수 있게 데이터 베이스를 안전하게 유지해야 한다.
데이터 디렉터리에 대한 접근모드가 너무 관대한 경우 악성 사용자가 권한테이블에 해당하는 파일을 완전히 다른 파일로 교체해 클라이언트 접근을 방해할 수 있다.
13.1 파일 시스템 접근 보안
데이터 디렉터리에 대한 접근 권한이 있을 경우 특정 테이블 파일을 카피해서, 새로운 서버를 구성하고 새로운 서버의 데이터 디렉터리에 카피를 하는 것 만으로
해당 테이블의 내용을 쉽게 확인 할 수 있다.
디렉터리에 대한 접근은 인증된 사용자만 할 수 있도록 디렉터리 권한 강화
data 디렉터리를 제외한 모든 디렉터리를 root 소유로
chown -R root /usr/local/mysql
chgrp -R mysql /usr/local/mysql
chown -R mysql /usr/local/mysql/data
chgrp -R mysql /usr/local/mysql/data
chmod -R go-rwx /usr/local/mysql/data data 디렉터리에 대한 읽고,쓰고, 실행하는 권한을 mysql에게만 줌.(그룹의 권한도 빼앗음)
chmod 755 /usr/local/mysql 또는 chmod u=rwx, go=rx /usr/local/mysql
chmod 755 /usr/local/mysql/bin 또는 chmod u=rwx, go=rx /usr/local/mysql/bin
13.2 유닉스 소켓 파일 보안
로컬 호스트 클라이언트의 서버 접속을 위해 유닉스 도메인 소켓 파일을 사용한다.
소켓 파일은 공개적으로 접근 가능하기 때문에 클라이언트 프로그램이 사용 가능하다.
그러나 임의의 클라이언트가 삭제 권한까지 보유하면 안 된다. 소켓파일이 삭제되면 클라이언트들이 로컬 호스트를 통해 서버에 접근이 안된다.
이럴 경우는 mysql --protocol=tcp 옵션을 주어서 접속한 후 소켓 파일을 재 생성해 주면 된다.(재 기동)
파일 생성자만이 삭제를 할 수 있도록 스티키 비트(sticky bit)를 설정해 주자.
chmod +t /tmp
다른 위치에 소켓 파일을 생성하고자 한다면, socket 시스템 변수를 설정해 주자.
이때 client도 동일한 위치를 참조 할 수 있게 다음과 같이 설정을 해 주어야 한다.
# 서버와 클라이언트 모두 설정해 주어야 한다. [mysqld] socket=/usr/local/mysql/mysql.socket
[client] socket=/usr/local/mysql/mysql.socket
# 소켓 파일을 엑세스 할 수 있게 다음과 같이 권한을 주어야 한다.
chmod go+x /usr/local/mysql |
13.3 옵션 파일
옵션 파일은 공개 되지 않아야 하는 정보를 가지고 있다.
/etc/my.cnf 파일은 전역 클라이언트 변수도 같이 저장되기 때문에 공개적인 읽기 권한이 주어진다. 이 파일에 비밀번호 같은 정보를 저장하지 않아야 한다.
유저 아이디나 패스워드 같은 경우는 각 유저의 홈 디렉터리에 .my.cnf 파일로 설정을 하며, 해당 파일은 해당 유저만 쓸 수 있게
chmod u=rw, go-rwx .my.cnf 로 파일 권한을 변경해 주어야 한다.
14. 사용자 계정 관리
사용자 계정 생성과 삭제 이름변경은 CREATE USER, DROP USER, RENAME USER를 이용하여 할 수 있다.
권한 부여, 제거는 GRANT, REVOKE를 이용하여 할 수 있다.
패스워드 변경은 SET PASSWORD 또는 UPDATE user SET authentication_string = password('password') WHERE user = 'root' ;
계정의 권한 정보는 show grants ;
# 계정의 권한 정보
mysql> show grants ; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | | GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
mysql> select current_user() ; +----------------+ | current_user() | +----------------+ | root@localhost | +----------------+
mysql> show grants for current_user() ; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | | GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
mysql> show grants for 'root'@'%' ; +-------------------------------------------------------------+ | Grants for root@% | +-------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION | +-------------------------------------------------------------+
|
권한 테이블
user |
서버에 연결 가능한 사용자와 전역 권한 정보 |
db |
데이터 베이스 권한 |
table_priv |
테이블 권한 |
columns_priv |
칼럼 권한 |
procs_priv |
스토어드 프로시저 권한 |
proxies_priv |
프록시 사용자 권한 |
14.1 계정 관리
계정은 user_name과 host_name 두개의 조합으로 생성 된다.
특정 클라이언트 host로 부터 특정 유저의 접속을 허용하기 위함이다.
# 유저 생성
CREATE USER 'user_name'@'host_name' IDENTIFIED BY 'password' ;
create user 'boris'@'localhost' identified by 'boripass' ; create user 'fred'@'ares.mars.net' identified by 'fredpass' ; create user 'joe'@'192.168.10.11' identified by 'joepass' ; create user 'joe1'@'192.168.10.%' identified by 'joe1' ; create user 'joe3'@'192.168.128.0/255.255.255.0' identified by 'joe3pass' ;
create user 'max'@'%' identified by 'maxpass' ;
|
14.2 권한 관리
grant 문은 유저가 존재 할 경우 유저의 권한을 할당 하지만, 유저가 없을 경우 유저를 생성하고 권한을 할당 한다.
권한은 크게 관리자 권한과 객체 권한으로 구분 된다.
GRANT 권한 ON 식별자 TO user@host ;
관리자 권한
create user |
create user, drop user, rename user, revoke all privileges 사용 가능 |
file |
서버 호스트에 파일을 읽고, 쓰는 권한 |
grant option |
다른 사용자에게 grant option권한을 포함해 자신이 가진 권한을 부여 할 수 있다. |
process |
show processlist, mysqladmin processlist 문을 사용할 수 있다 |
proxy |
다른 사용자의 권한을 대행 할 수 있다. 다른 사용자의 대리인 역할을 수행하며, 해당 사용자가 수행 할 수 있는 모든 일을 할 수 있다. |
reload |
flush 와 reset 수행 가능 reload, refresh, flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads 등의 mysqladmin 명령어 수행 |
replication client |
show master status, show slave status 수행 가능 |
replication slave |
마스터 서버에 연결과, 서버의 업데이트 요청을 가능하게 한다. show slave hosts, show binlog events 수행. 마스터 서버에 자주 접근하는 슬레이브 서버 계정에는 반드시 부여 해야 한다. |
show databases |
show database 명령문 수행 시 전체 데이터 베이스를 보이게 할지 여부 결정 이 권한이 없는 상태에서 show databases명령을 수행하면 자기에게 부여된 데이터 베이스만 보임. |
shutdown |
mysqladmin shutdown 명령과 같은 서버 중단 권한 |
super |
kill , mysqladmin kill 명령을 이용하여 서버 프로세스를 종료 시킬 수 있다. set, change master, purge binary logs, show master status, show slave status, start slave, stop slave 가능 |
객체 권한
create |
데이터 베이스와 테이블을 생성하는 권한 |
alter |
테이블에 따라서 추가 권한이 필요할 수도 있지만, 기본적으로 alter table 사용권한 |
drop |
데이터 베이스와 테이블을 삭제 할 수 있는 권한. 인덱스는 삭제 할 수 없다. |
create routine |
프로시저나 펑션을 생성할 수 있는 권한 |
alter routine |
프로시저나 펑션을 변경하거나 제거 할 수 있는 권한 |
execute |
프로시저나 펑션 수행 권한 |
create tablespace |
테이블 스페이스를 생성, 변경, 삭제 할 수 있는 권한 |
create temporary tables |
create temporary table 구문을 이용하여 임시 테이블을 생성 할 수 있는 권한 |
create view |
뷰를 생성 할 수 있는 권한 |
show view |
뷰 정의 내용을 볼 수 있는 show create view 명령 수행 가능 |
index |
테이블의 인덱스를 생성, 삭제 및 key 캐시에 인덱스 할당 및 프리로드 권한 |
lock table |
명시적으로 lock table 구문을 이용해서 테이블 락을 걸수 있는 권한. 기본으로 SELECT 권한이 있는 테이블에 대하여 lock table문을 사용할 수 있다. |
trigger |
트리거 추가, 제거 권한 |
event |
이벤트 스케줄러의 이벤트 조정 권한 |
insert |
테이블에 행 추가 권한 |
update |
테이블의 행 변경 권한 |
delete |
테이블의 행 삭제 권한 |
select |
테이블의 데이터를 조회할 권한 |
권한 레벨 식별자
ON *.* |
모든 데이터 베이스와 데이터 베이스 안의 모든 객체 |
ON * |
기본 데이터 베이스에 대한 데이터 베이스 레벨의 권한 |
ON dbname.* |
dbname 데이터베이스 내의 모든 객체 |
ON dbname.tb_name |
dbname 데이터베이스의 tb_name 테이블의 모든 칼럼 |
ON tb_name |
기본 데이터 베이스내의 지정된 테이블의 모든 칼럼 |
ON dbname.routine_name |
dbname 데이터베이스내의 지정된 루틴의 권한 |
ON account |
프록시 권한: 계정 프록시 사용자 |
# 권한 부여 예)
GRANT ALL ON *.* TO 'user1'@'localhost' ; 'user1'@'localhost' 유저에게 모든 데이터베이스에 대한 권한을 부여 GRANT reload ON *.* TO 'flush'@'localhost' ; 'flush'@'localhost' 유저에게 flush 가능한 reload 권한을 부여 GRANT ALL ON sampdb.* TO 'bill'@'mamba.example.com' ; 'bill'@'mamba.example.com' 유저에게 sampledb의 모든 객체 권한 부여 GRANT select ON sampdb.* TO 'reader'@'%' ; reader유저로 접속하는 세션에게 sampdb의 모든 객체에 대하여 SELECT 권한 부여 GRANT select,insert,update,delete ON sampdb.* TO 'jenie'@'%' ; GRANT select, update(experation,street,city,state,zip) ON sampdb.member TO 'assis'@'%' ; assis유저에게 sampdb 데이터베이스의 member 테이블에 대하여 select 및 (experation,street,city,state,zip) 칼럼에 대한 업데이트만 허용
REVOKE ALL ON *.* FROM 'user1'@'localhost' ; REVOKE insert, delete ON sampdb.* FROM 'jenie'@'%' ; REVOKE grant option ON sampdb.* FROM 'bill'@'localhost' ;
|
14.3 계정 리소스 관리
특정 계정의 특정 시간대 접속 횟수와 SQL 수해 횟수, 업데이트 수행 횟수 등을 제한 할 수 있다.
이 값들은 with 절을 이용해 제한 할 수 있다.
GRANT ALL ON sampledb.* TO 'spike'@'localhost'
WITH MAX_CONNECTIONS_PER_HOUR 10
MAX_QUERIES_PER_HOUR 200
MAX_UPDATES_PER_HOUR 50 ;
spike유저에게 sampledb의 모든 객체에 대한 권한을 주면서 시간당 10회 접속이 가능하고, 시간당 200회의 SQL을 수행할 수 있으며, 시간당 50번의 업데이트만 가능하게 함.
제한을 해제 하기 위해서는 0으로 설정 하면 된다.
GRANT ALL ON sampledb.* TO 'spike'@'localhost'
WITH MAX_CONNECTIONS_PER_HOUR 0 ;
mysql.user 테이블의 max_questions, max_updates, max_connections, max_user_connections 칼럼의 값 을 확인하면 된다.
max_questions : 시간당 최대 허용 SQL 수행 수
max_updates : 시간당 최대 허용 UPDATE 수행 수
max_connections : 시간당 최대 허용 접속 수
max_user_connections : 허용 된 최대 동시접속 자 수
15. 데이터베이스 유지보수와 백업, 복제
- InnoDB 스토리지 엔진은 자동으로 문제를 체크 한 후 커밋 된 후 redo log에는 저장되어 있지만, 테이블로 플러시 되지 않은 트랜잭션을 다시 수행한다.(rollforward)
그러나 장애가 발생함으로써 커밋 되지 않았던 채로 남아있는 트랜잭션은 undo log를 이용하여 rollback 시킨다.
드물게 자동으로 복구를 시도하다가 안될 경우, 서버는 에러로그를 남기고 다운된다. 이때 어떻게든 살려서 데이터를 살리고 싶으면 innodb_force_recovery=4를 주고 강제적으로 기동 시킨 후 mysqldump를 이용하여 InnoDB 테이블을 dump한다. 이후 innodb_force_recovery라인을 삭제 후 재 기동 시킨 다음 손상된 테이블을 삭제나 dump파일을 이용하여 복구 시킨다.
- MyISAM테이블에 일관성을 체크하거나 복구를 수행하려면 check table이나 repair table문을 사용하여 서버가 작업을 하게 하는 것이 가장 좋은 방법이다.
그러나 여의치 않을 경우 수동으로 myisamchk 명령어를 수행해야 하는데 이 명령어는 자체적으로 테이블의 파일을 엑세스 하기 때문에, 데이터베이스와 동일 테이블에 대한 경합이 발생할 수 있다. 이로 인하여 테이블에 손상이 발생할 수도 있으므로 사용에 신중해야 한다.
- mysqlcheck와 mysqldump는 서버와 연결된 상태에서 동작을 하기 때문에 서버와의 경합은 발생 하지 않는다.
- mysqldump와 mysqlhotcopy 프로그램은 테이블 복구를 대비하여 데이터 베이스 백업 본을 만들게 해 준다.
- mysqlimport는 벌크 데이터를 로딩 하는데 사용된다. 그러나 mysqldump파일로 백업받은 텍스트를 읽는 목적이 아니라, 데이터 레코드를 읽는데 사용된다.
- mysqlcheck는 테이블 점검, 복구, 최적화를 위한 프로그램이다.
- 부하 분산을 목적으로 SELECT 조회 위주의 slave 서버를 구성하였다면, read_only 모드로 운영함을 고려해 봐야 한다.
- 또한 슬레이브 서버가 정상적으로 master의 로그를 가져와서 반영이 잘 되고 있으면, 슬레이브에서 백업을 하는 것도 고려해 봐야 한다.
5.1 데이터 베이스 백업
백업에는 크게 두 가지 백업이 존재 한다.
- mysqldump를 이용하여 텍스트 형식으로 테이블의 내용을 저장하는 백업. (논리적 백업)
- MySQL서버에 접속해서 데이터를 복구 하기 위한, create table, insert … 문을 만들어 내기 때문에 물리적 백업보다 시간이 오래 걸린다.
- 테이블에 존재하는 index에 대한 정보는 백업 내용에 포함되어 있지 않지만, 덤프 파일을 이용해서 데이터를 복구 시에는 인덱스가 생성된다.
- 하드웨어가 틀린 다른 머신 에서도 호환이 된다.
- 설정파일이나 로그파일 등은 백업이 되지 않는다.
- --opt 옵션을 사용하면 덤프과정을 최적화 시키지만, --opt를 사용하는 순간 모든 테이블에 lock을 설정하기 때문에 다른 세션에서 DML이 불가능 하다.
- --opt 옵션은 기본적으로 extended-insert 를 활성화 시켜서, 한 건 한 건 insert하는 구문이 아니다. 그래서 로그 사이즈가 줄어든다.
- 전체 데이터 베이스를 백업 받을 때는 --flush-logs 옵션을 같이 사용하면 좋다.
- 기본적으로 테이블과 연관된 데이터만 백업을 받게 되므로 --routines --triggers --events 옵션을 사용하여 덤프 파일에 추가해야 한다.
- --master-data는 복제 슬레이브 서버를 만들 목적으로 master서버에서 덤프 파일을 생성할 때 유용하다.
- 물리적으로 실제 사용되고 datadir, 로그파일, 설정 파일 등을 직접 복사 하여서 저장시켜 놓는 바이너리 백업. (물리적 백업)
- 물리적 백업은 cp, tar, rsync 프로그램을 사용한다.
- 필요에 의해서 서버가 중단 되어야 할 수도 있다.
mysqldump 사용법
# tpcc 데이터베이스의 customer 테이블만 백업 받기
[root@mmysql ~]# mysqldump tpcc customer > customer_2016_12_10.dmp
백업 받은 파일은 기존 테이블이 존재하면 drop하고 create한 후에 insert하는 식으로 만들어져 있다. 해당 테이블에 Index가 있을 경우 index 생성 스크립트는 없음.
# 백업 받은 customer 테이블의 데이터를 다시 복구 하기
[root@mmysql ~]# mysql tpcc < customer_2016_12_10.dmp
# 특정 데이터 베이스 안의 모든 테이블 백업 받기 create database 구문 없음 (백업 받으면서 압축하기)
[root@mmysql ~]# mysqldump -uroot tpcc | gzip > /root/tpcc_2016_12_10.sql.gz
[root@mmysql ~]# gzip -d /root/tpcc_2016_12_10.sql.gz [root@mmysql ~]# mysql < tpcc_2016_12_10.sql
# 데이터 베이스 백업 받기
[root@mmysql ~]# mysqldump --databases tpcc > tpcc_db.sql
# 데이터 베이스 복구
[root@mmysql ~]# mysql < tpcc_db.sql
# 테이블의 생성 스크립트만 백업 받기
[root@mmysql ~]# mysqldump tpcc customer_test --no-data > customer_test_ddl_only.sql
# 데이터만 백업 받기
[root@mmysql ~]# mysqldump tpcc customer_test --no-create-info > customer_test_data_only.sql
# 전체 데이터 베이스 백업 받기 (권한 테이블도 덤프 되기 때문에 다른 MySQL에 넣으려면 다른 옵션을 사용할 것 !!)
[root@mmysql ~]# mysqldump --all-databases | gzip > all_db_2016_12_10.sql.gz [root@mmysql ~]# mysqldump --all-databases --flush-logs --opt | gzip > all_db_flush_opt.sql.gz [root@mmysql ~]# mysqldump --all-databases --flush-logs --opt --routines --triggers --events | gzip > all_db_flush_opt_r_t_e.sql.gz
[root@mmysql ~]# ls -al all_db* -rw-r--r-- 1 root root 738113600 Dec 9 17:19 all_db_2016_12_10.sql.gz -rw-r--r-- 1 root root 738113601 Dec 9 17:28 all_db_flush_opt.sql.gz
# 전체 데이터 베이스 백업 파일을 가지고, 특정 데이터 베이스만 복구 하기
mysql> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | tpcc | | tpch | +--------------------+
mysql> drop database tpcc ;
mysql> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | tpch | +--------------------+
[root@mmysql ~]# zcat all_db_flush_opt.sql.gz | grep "CREATE DATABASE" > create_db.sql create_db.sql에서 DB Creation 문장 추출….. db가 존재하는 상태라면 skip….
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `tpcc` /*!40100 DEFAULT CHARACTER SET euckr */;
mysql> CREATE DATABASE /*!32312 IF NOT EXISTS*/ `tpcc` /*!40100 DEFAULT CHARACTER SET euckr */; Query OK, 1 row affected (0.01 sec)
mysql> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | tpcc | | tpch | +--------------------+
mysql> use tpcc ; Database changed mysql> show tables ; Empty set (0.00 sec)
[root@mmysql ~]# zcat all_db_flush_opt.sql.gz | mysql -o tpcc (-o = one database )
mysql> show tables ; +----------------+ | Tables_in_tpcc | +----------------+ | customer | | customer_test | | district | | history | | item | | new_order | | order_line | | orders | | orders_test | | stock | | test | | warehouse | +----------------+
# 데이터 베이스 백업 중에서 특정 테이블만 복구 하기
전체 데이터 베이스 백업 중에서 특정 테이블만 복구를 하려면 다음과 같은 순서로 진행 한다. 1. 임시 데이터 베이스 생성 2. 복구에 필요한 정보가 있는 데이터 베이스의 내용을 복구 3. 필요한 테이블의 데이터를 읽어서 복구
tpcc데이터 베이스의 test 테이블의 데이터만 복구 하고자 한다면 , tpcc 데이터 베이스의 백업을 이용하여 복구를 시도한다.
1. mysql -e "create database temp;" 2. mysql temp < tpcc_backup.sql 3. mysql -e "truncate tble tpcc.test; " 3. mysql -e "insert into tpcc.test select * from temp.test ;"
|
물리적 백업
물리적 백업을 할 때는 다음의 두 가지 포인트를 꼭 확인하자.
1. 해당 테이블이 사용되고 있지 않은 상태여야 함. 복사 과정에서 테이블의 데이터를 변경하려고 한다면 물리적 백업이 의미가 없어 짐.
서버를 중지 시키고 백업 받는 게 제일 좋지만, 그렇지 않을 경우 읽기 전용으로 변경 후 복사를 진행 하자.
2. 백업하려는 테이블들을 복원하기에 필요한 모든 파일들을 복사 해야 한다.
데이터 베이스 별로 datadir이 아닌 다른 곳에 심볼릭 링크를 이용하여, 다른 곳에 데이터 파일을 위치 시켰을 수 있으니 심볼릭 링크의 데이터 복사에 유의!!!
서버가 슬레이브 서버라면 master.info, relay-log.info , 임시 디렉터리(slave_load_tmpdir)에 SQL_LOAD-xxx 파일을 포함하여 백업한다. (중지 필요)
데이터 베이스를 다른 서버로 복사
- 덤프 파일을 이용하는 방법
중간 파일이 존재 함.
1. mysqldump --databases tpcc > tpcc_db.sql
2. scp tpcc_db.sql remote서버:/tmp/.
3. remote 서버에서 mysql < /tmp/tpcc_db.sql
중간 파일을 생성하지 않고 바로 import
1. mysqldump --database tpcc | mysql -h remote_server
OR
mysqldump --database tpcc | mysql --compress -h remote_server tpcc
OR
서버에 직접 mysql -h remote_server로 접속을 할 수 없는 상황이라면 ssh를 이용하여 접속하여 실행
mysqldump --database tpcc | ssh remote_server mysql
- 데이터 베이스 디렉터리 카피 (MyISAM)
동일한 하드웨어나, 카피 하려는 바이너리가 이식 가능한 엔진일 경우 데이터 베이스 디렉터리를 copy 하는 것으로 복사 가능
카피 시에 해당 데이터 베이스의 파일들에 대한 변경 작업이 없어야 한다.
datadir이 /usr/local/mysql/data 이라고 가정하고, tpcc 데이터 베이스가 MyISAM 스토리지 엔진이라고 가정 함.
1. cd /usr/local/mysql/data
2. scp -r tpcc 리모트:/usr/local/remote/mysql/data
슬레이브 서버를 이용한 백업
슬레이브 서버를 이용할 경우, SQL 슬레이브 스레드만 중지(stop slave sql_thread)를 한 후에 mysqldump를 이용하여 백업을 수행 한 후에
start slave를 수행하여 백업을 종료 한다.
슬레이브 서버 설정은 18. 복제 서버 구성을 참조
16. 테이블 점검과 수리
데이터 베이스가 손상을 입었을 경우에는, 데이터 베이스 복구를 시도하지만 운영 중에 특별한 테이블만 손상이 발생 하였을 경우
다음과 같이 조치를 취한다.
InnoDB 엔진의 테이블이 손상 되었을 경우
1. CHECK TABLE 또는 mysqlcheck 명령을 이용하여 해당 테이블 검사
2. mysqldump를 이용하여 테이블 백업
3. 문제의 테이블 삭제
4. 테이블 백업 본을 이용하여 테이블 재 생성
MyISAM 엔진의 테이블이 손상 되었을 경우
1. CHECK TABLE 또는 mysqlcheck 명령을 이용하거나, myisamcheck를 수행한다.
CHECK TABLE 또는 mysqlcheck는 서버가 알아서 락 관련 작업들을 하지만, myisamcheck를 이용할 경우는 수동으로 lock 작업을 해 주어야 한다.
2. REPAIR TABLE 명령으로 테이블을 복구 한다.
16.1 CHECK TABLE을 이용한 테이블 검사
InnoDB, MyISAM, ARCHIVE, CSV 테이블과 뷰에서 동작 함.
MyISAM에만 적용되는 옵션:
changed : 테이블이 정상적으로 닫히지 않았거나, 마지막으로 체크된 시점 이후에 발생한 변경이 없을 때는 테이블 체크를 건너뜀
extended : 테이블의 일관성을 완전히 보장하기 위해 추가적인 체크를 수행한다.
fast : 테이블이 정상적으로 닫힌 경우에만 체크를 수행한다.
medium : 인덱스를 체크하고 문제 상황에 관련된 데이터 레코드를 스캔 해 체크 섬을 검증한다. (기본 값)
quick : 인덱스만 스캔하고 데이터 레코드는 건너 뛴다.
for update : 체크된 테이블이 현재 MySQL 버전에 호환되는지 여부를 확인한다. 업그레이드 이후에 유용함.
CHECK TABLE table1, table2, table3 FAST MEDIUM ;
16.2 REPAIR TABLE을 이용한 테이블 수리
MyISAM, ARCHIVE, CSV 테이블에서 동작 함
MyISAM에만 적용 되는 옵션 :
extended : 인덱스를 재 생성하는 수리 방법으로 수행
quick : 인덱스에 대해서만 수리를 하고, 데이터 파일은 그대로 둔다.
use_frm : 인덱스를 초기화 하고 .frm 파일을 읽어 들여서 인덱스를 다시 빌드 함. 인덱스가 유실되거나 복구 불가능하게 손상을 입은 경우에 유용하나 테이블에 손상이 있을 수 있으므로 최후의 수단으로 사용해야 한다.
repair_table : 대부분의 문제를 수리하지만, 고유한 값을 가져야 하는 인덱스에 중복 값이 들어가는 경우는 수리 불가능 (기본값)
16.3 mysqlcheck명령을 이용하여 테이블 점검과 수리
check table과 repair table 문장에 대한 command line 인터페이스를 제공한다.
mysqlcheck 뒤에 테이블 이름을 주면 테이블만 점검하지만, 데이터 베이스 이름을 주면 데이터 베이스 내의 모든 테이블에 대한 점검을 한다.
--databases --all-databases 옵션을 이용할 수 있다.
내부적으로 check table과 repair table을 수행하는 것과 같으므로, repair table은 MyISAM, ARCHIVE, CSV 테이블에 대해서만 수리를 해 주는 것 처럼 mysqlcheck도 해당 테이블만 수리를 한다.
17. 복구
복구는 백업파일과 바이너리 로그라는 두 가지 소스를 가지고 한다.
백업 파일은 mysqldump 를 이용하여 생성한 덤프 파일일 수도 있고, 바이너리 백업 방법 중 한 가지를 이용하여 만들어 놓은 복사된 파일일 수도 있다.
백업 파일을 이용하여 백업 당시의 시점으로 복원을 한 후에, 로그파일을 이용하여 백업 이후의 변경 사항에 대한 변경 내역을 반영해 주면 된다.
mysqlbinlog 프로그램을 이용하여 로그파일의 내용을 SQL 문장으로 변경 후 해당 SQL을 재 수행해 주면 된다.
17.1 mysqlbinlog 사용법
바이너리 로그 파일의 내용을 읽어서 텍스트 형태로 변경하여 쉽게 실행 할 수 있게 해 준다.
mysqlbinlog의 출력 파일은 mysql에서 바로 실행 시킬 수 있다.
모든 로그 또는 특정 데이터 베이스 또는 특정 시간대의 바이너리 로그만을 테스트로 변경 할 수 있다.
# bin log 파일의 이름 및 위치 파악
mysql> show global variables like 'log_bin%' ; +---------------------------------+--------------------------------+ | Variable_name | Value | +---------------------------------+--------------------------------+ | log_bin | ON | | log_bin_basename | /var/lib/mysql/mysql-bin | | log_bin_index | /var/lib/mysql/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | +---------------------------------+--------------------------------+
# 로그 파일 확인
[root@mmysql ~]# ls -al /var/lib/mysql/mysql-bin* -rw-r----- 1 mysql mysql 177 Dec 8 02:10 /var/lib/mysql/mysql-bin.000179 중략… -rw-r----- 1 mysql mysql 105703077 Dec 9 17:46 /var/lib/mysql/mysql-bin.000217 -rw-r----- 1 mysql mysql 105009570 Dec 9 17:47 /var/lib/mysql/mysql-bin.000218 -rw-r----- 1 mysql mysql 39889796 Dec 9 17:53 /var/lib/mysql/mysql-bin.000219 -rw-r----- 1 mysql mysql 201 Dec 9 17:53 /var/lib/mysql/mysql-bin.000220 -rw-r----- 1 mysql mysql 201 Dec 9 17:54 /var/lib/mysql/mysql-bin.000221 -rw-r----- 1 mysql mysql 154 Dec 10 20:31 /var/lib/mysql/mysql-bin.000222 -rw-r----- 1 mysql mysql 154 Dec 10 20:31 /var/lib/mysql/mysql-bin.000223
# 로그 파일을 읽어서 바로 반영
[root@mmysql ~]# mysqlbinlog /var/lib/mysql/mysql-bin.[0-9]* | mysql
# 로그 파일을 읽어서 텍스트 파일에 저장 후, 불 필요한 drop database 문장이나 drop table, delete 문장 등을 삭제 할 수 있다. 필요에 의해서 use 데이터 베이스 명을 삭제할 필요도 있다.
[root@mmysql ~]# mysqlbinlog /var/lib/mysql/mysql-bin.[0-9]* > /tmp/binlog.txt
# 특정 데이터 베이스의 변경 사항만 추출하려면 --database 옵션을 사용한다.
[root@mmysql ~]# mysqlbinlog --database=tpcc /var/lib/mysql/mysql-bin.[0-9]* > /tmp/tpcc_binlog.txt
# 특정 시간대의 변경 사항만 추출하려면
[root@mmysql ~]# mysqlbinlog --start-datetime=20161210160000 --stop-datetime=20161210170000 /var/lib/mysql/mysql-bin.[0-9]* > /tmp/time_binlog.txt |
17.2 데이터 베이스 복구
하나 이상의 데이터 베이스에 대한 복구는 다음과 같은 절차로 진행 한다.
1. 사용중인 데이터 베이스 파일을 다른 곳에 복사를 해 둔다.(혹시 잘 못 될 경우 다시 사용하기 위함)
2. 덤프 파일을 이용하려면 외부의 원격 접속을 못하게 --skip-networking 옵션을 사용하여 DB를 기동 시키거나, 복구 해야 할 데이터 베이스가 권한 정보를 가지고 있는 mysql 데이터 베이스 라면 --skip-grant-tables 옵션을 이용하여 서버를 기동 한 후에 복구를 진행해야 한다. 그렇지 않을 경우 권한 테이블을 찾을 수 없는 문제를 야기 할 수 도 있다.
3. 바이너리 백업을 이용하려면 데이터베이스를 중지 시킨 후 백업 파일로 복구를 시킨다.
4. 바이너리 로그를 이용하여 백업 이후의 변경 사항을 적용 시킨다. (mysqlbinlog --database 옵션을 이용하여 특정 데이터 베이스 로그 적용)
17.3 개별 테이블 복구
개별 테이블을 복구 하는 것은, 데이터 베이스에 대한 복구 보다 힘들다.
데이터 베이스 레벨의 복구를 시킨 후 특정 테이블의 데이터만 재 사용하게 한다.
1. 복구하고자 하는 테이블을 포함하는 데이터 베이스의 데이터를 빈 데이터 베이스로 복구 시킨다.
데이터 베이스 레벨로 덤프 한 덤프 파일이나, 전체 데이터 베이스 레벨로 덤프를 받은 파일은 덤프 파일 안에 use 데이터 베이스 명; 이 존재 한다.
복구를 할 때 이 부분을 삭제 하거나 빈 데이터 베이스 이름으로 변경 후 수행시켜야 한다.
mysqlbinlog를 이용하여 복구하고자 하는 테이블을 포함한 데이터 베이스 로그를 파일로 저장 한 후에, 마찬가지로 빈 데이터 베이스 이름으로 바꿔 줘야 한다.
2. mysqldump를 이용하여 복구하고자 하는 테이블을 덤프 한 후, 복구하고자 하는 테이블을 삭제하고, 덤프 파일로 테이블을 재 생성 하거나
복구하고자 하는 테이블을 truncate 한 후에 insert into 복구데이터베이스.복구테이블 select * from 빈데이터베이스.복구테이블 ; 명령을 사용
MyISAM 테이블일 경우 서버를 종료 후 빈 데이터 베이스의 .MYD .MYI .frm 파일을 직접 복구 하고자 하는 데이터베이스 디렉터리로 복사를 해도 된다.
18. 복제 서버 설정
Master-Slave 환경에서 MySQL은 다음과 같이 동작을 한다.
1. 하나의 서버는 마스터가 되고 다른 서버는 슬레이브가 되며, 각각의 서버는 고유한 복제 ID를 가진다.
2. 마스터마다 여러 개의 슬레이브가 존재 할 수 있다. 슬레이브는 다른 서버의 마스터가 될 수 있기 때문에 복제 서버의 체인을 생성 할 수 있다.
3. 슬레이브 데이터의 업데이트는 마스터 서버의 바이너로 로그에 기반을 두고 수행된다. 즉, 마스터 서버는 바이너리 로깅이 활성화 되어 있어야 한다.
바이너리 로그에 저장된 업데이트 내용은 "이벤트"라는 이름으로 불린다.
4. 마스터 서버는 슬레이브의 연결과 업데이트 요청이 오면, 이전 연결 이후 얼마만큼의 바이너리 로그가 진행 되었는지 알려 준다. 이전 진행 이후의 로그파일명과 로그파일에서의 위치 값을 전달 받은 슬레이브는 모든 이벤트를 읽어서 반영 한다.
5. 마스터 서버는 슬레이브의 연결을 일반 클라이언트 처럼 다루기 때문에 접속이 많을 경우, max_connections 제한에 걸릴 수 있다.
6. 슬레이브 서버는 복제 동작을 하기 위하여 두 개의 스레드를 사용한다.
I/O 스레드는 마스터로 부터 이벤트를 받아서 릴레이 로그에 기록을 한다.
SQL 스레드는 릴레이 로그로 부터 이벤트를 읽어 들여 실행한다.
릴레이 로그는 단순히 I/O 스레드가 받아온 이벤트를 SQL 스레드로 전달하기 위한 수단으로 사용된다. 릴레이 로그의 내용이 모두 반영되면 릴레이 로그는 삭제 된다.
I/O 스레드와 SQL 스레드는 독립적으로 동작이 된다.
그래서 백업을 위하여 SQL 스레드가 잠시 동작을 못하고 있는 상황에도 I/O 스레드는 마스터로 부터 받아온 이벤트를 릴레이 로그에 저장 한다.
18.1 복제 서버 구성
서로 다른 서버에 마스터-슬레이브를 구성하는 방법
1. 마스터 서버와 동일한 엔진으로 슬레이브 서버를 설치 한다.
2. 각 서버에 고유한 ID를 결정 하고, 마스터 서버는 바이너리 로그를 활성화 시킨다.
[mysqld] #Replication for Master server server-id=1 log-bin=mysql-bin max_binlog_size=100M max_allowed_packet=128M expire_logs_days=3 autocommit=1 |
[mysqld] #Replication for Slave server server-id=2 log-bin=mysql-bin max_binlog_size=100M max_allowed_packet=128M expire_logs_days=3 relay-log=relay-bin slave_skip_errors=1032,1061,1062 autocommit=1 read_only=1
# Slave 서버에 log-bin을 활성화 시켜 놓아도 이 슬레이브가 master가 되지 않는 한 로그는 쌓이지 않는다. # relay-log-bin은 replication I/O thread가 읽어온 것을 저장하는 로그 파일 # relay-log 파일명에 서버 호스트 명을 주면, 나중에 추가적인 slave 구성 시 귀찮게 되니깐 그냥 relay-bin으로 사용하자. # slave_skip_errors는 slave서버에서 Master에서 전송 된 로그를 반영 하는 도중 발생하는 에러 중에서 1032,1061,1062는 무시하라는 옵션 # log-slave-updates가 활성화 되어 있으면 로그가 쌓임. log-bin을 활성화 시켜 놓아야 나중에 편하게 slave --> Master로 변환 시킬 수 있다. |
3. 마스터 서버에서는 슬레이브 서버에서 마스터 서버에 접속해서, 요청이나 업데이트를 위한 연결에 사용할 유저를 생성해 준다.
mysql> use mysql ; mysql> create user 'slave'@'%' identified by 'slave1122' ; mysql> grant replication slave on *.* to 'slave'@'%' ; |
4. 마스터 서버에서 더 이상의 업데이트가 발생하지 않게 한 후에, 바이너리 로그를 확인 하여 file과 position 값을 기억 한다.
마스터 서버에서 전체 데이터 베이스에 대한 백업을 실시 한다.
# read only 락을 잡는다.
mysql> flush tables with read lock ; mysql> set global read_only=on ; mysql> show master status ; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000224 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+
# backup을 수행한다
mysql> \! /usr/bin/mysqldump --all-databases | gzip > master_224_154.sql.gz OR mysql> \! /usr/bin/mysqldump --master-data | gzip > master_224_154.sql.gz --master-data options doesn't need flush tables with read lock ; lock and unlock tables implicated
# read lock을 해제 한다.
mysql> set global read_only=off ; mysql> unlock tables ;
위의 명령어를 하나의 O/S 명령어로 만들면
echo " flush tables with read lock ; set global read_only=on ; show master status ; \! /usr/bin/mysqldump --all-databases | gzip > master_$(date +"%Y_%m_%d_%I_%M_%p").sql.gz set global read_only=off ; unlock tables ; " | mysql
또는
echo " flush tables with read lock ; set global read_only=on ; show master status ; \! /usr/bin/mysqldump --all-databases --master-data | gzip > master_$(date +"%Y_%m_%d_%I_%M_%p").sql.gz set global read_only=off ; unlock tables ; " | mysql
# 만약 데이터 베이스가 클 경우 mysqldump를 이용할 수 없으므로 O/S상의 파일을 cp,scp,rsync등의 명령을 이용한다. mysqladmin shutdown tar cf /tmp/backup.tar /data zip -r /tmp/backup.zip /data rsync --recoursive /data /tmp/data start master
|
5. 마스터 서버에서 백업 받은 파일을 슬레이브로 전송한다.
[root@mmysql ~]# scp master_224_154.sql.gz root@Smysql:/root/. The authenticity of host 'smysql (192.168.10.16)' can't be established. RSA key fingerprint is 95:db:1f:da:be:4d:7f:d1:e7:7b:ee:bf:19:70:85:ed. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'smysql,192.168.10.16' (RSA) to the list of known hosts. root@smysql's password: master_224_154.sql.gz 10% 73MB 16.7MB/s 00:37 ETA |
6. 마스터 서버의 백업 파일을 이용하여 슬레이브 서버 구성
[root@smysql ~]# zcat master_224_154.sql.gz | mysql |
7. 슬레이브 서버에서 마스터 서버에 대한 구성을 한다.
mysql은 localhost 연결을 위하여 소켓 파일을 사용한다. 하지만 복제는 소켓 파일을 지원하지 않고 TCP/IP 연결을 사용한다.
그래서 마스터와 슬레이브 서버가 동일 서버에 구성되어 있을 때에는 master_host에 localhost 가 아닌 127.0.0.1을 사용해야 한다.
마스터가 기본 포트를 사용하고 있지 않을 경우는 master_port를 이용하여 포트 번호를 지정해 준다.
mysql> \! cat /etc/hosts # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6
#10.10.30.80 Mmysql #10.10.30.81 Smysql
192.168.10.15 Mmysql 192.168.10.16 Smysql 192.168.10.20 MySQLEnt5.7.14
mysql> change master to -> master_host='Mmysql' , -> master_port = 3306 , -> master_user = 'slave' , -> master_password = 'slave1122' , -> master_log_file = 'mysql-bin.000224' , -> master_log_pos = 154 ;
mysql> commit ;
mysql> start slave ; Query OK, 0 rows affected (0.00 sec)
mysql> commit ;
mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: Mmysql Master_User: slave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000225 Read_Master_Log_Pos: 1366 Relay_Log_File: smysql-relay-bin.000004 Relay_Log_Pos: 1579 Relay_Master_Log_File: mysql-bin.000225 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1366 Relay_Log_Space: 1834 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 5123053e-369d-11e6-9615-080027794699 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:
|
18.2 복제 서버를 이용한 백업
복제 서버를 이용하여 백업을 진행하면, master 서버에서 백업을 진행 하는 것보다 이점이 많다.
변경이 안되게 막고 백업을 받아야 하는데 이때 슬레이브 서버를 이용할 경우, 슬레이브는 목적이 read_only 상태로 오픈 하기에 특별히 제약이 없다.
위에도 설명 했지만 슬레이브 서버에서 SQL 스레드를 중지 하더라도 마스터 서버로 부터 이벤트를 받아오는 I/O 스레드는 일을 계속 하기에 반영 로그의 손실은 없다.
백업을 위해서 stop slave sql_thread 명령을 수행하여 SQL 스레드의 작업만 중지 시킬 수 있다.
백업 이후 start slave 명령을 수행하면, 백업 중에 쌓였던 릴레이 로그를 반영 한다.
echo " stop slave sql_thread ; flush tables with read lock ; \! /usr/bin/mysqldump --all-databases | gzip > /root/all_databases_$(date +"%Y_%m_%d_%I_%M_%p").sql.gz unlock tables ; start slave ; " | mysql
위의 명령어를 수행하여 슬레이브 서버에서 백업을 진행 한다.
[root@smysql ~]# echo " > stop slave sql_thread ; > flush tables with read lock ; > \! /usr/bin/mysqldump --all-databases | gzip > /root/all_databases_$(date +"%Y_%m_%d_%I_%M_%p").sql.gz > unlock tables ; > > start slave ; " | mysql
[root@smysql ~]# ls -al /root/all_data* -rw-r--r-- 1 root root 719095862 Dec 11 01:38 /root/all_databases_2016_12_11_01_35_AM.sql.gz
|
18.3 슬레이브 서버 상태 체크
간단한 쉘을 만들어서 슬레이브 서버의 상태를 체크 함.
check_slave.sh
/mysql/local/mysql/bin/mysql -uroot -pTk2dnjfem! -e 'show slave status\G' | egrep "Log_File|Master_Log_Pos|Running|Seconds" | grep -v "relay\."
수행 결과 Master_Log_File: bin.000001 Read_Master_Log_Pos: 379353352 Relay_Master_Log_File: bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Exec_Master_Log_Pos: 379353352 Until_Log_File: Seconds_Behind_Master: 0 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
|
19. Slave 서버를 이용한 또 하나의 slave 서버 생성
Master : Slave 가 1 : 1 이 아닌 1 : M으로 운영하고자 할 때, 운영 중이던 Slave 서버를 이용하여 또 하나의 Slave 서버 생성.
1. 운영 중이던 slave 서버와 동일한 mysql 엔진을 새로운 slave 서버에 설치 한다.
2. 운영 중이던 slave 서버에서 stop slave를 수행 함.
3. 운영 중이던 slave 서버에서 /etc/my.cnf 파일을 새로운 slave 서버로 복사 한다.
4. 운영 중이던 slave 서버에서 datadir 및 기타 log 디렉터리를 압축하거나 scp로 새로운 slave 서버로 복사 한다.
5. 운영 중이던 slave 서버에서 start slave 수행 함.
6. 새로운 slave서버에서 복사해 온 /etc/my.cnf 파일에서 server-id 변경
7. copy해 온 경로의 권한을 변경 chown -R mysql:mysql /data
7. scp로 datadir을 copy해 온 경우는 운영 중이던 서버의 uuid가 설정 된 auto.cnf 파일이 존재 하므로 auto.cnf 파일의 이름을 변경 또는 삭제
8. 복사 해온 slave 서버는 master 서버에 대한 설정이 되어 있는 상태이므로 master.info 파일은 수정 할 필요가 없으나,
relay_log.info, relay_log.index 파일의 내용은 새로운 slave 서버에 맞게 설정
9. 새로운 slave에서 mysql start
10. start slave 명령 수행
정상 수행되면 다행인데 혹시나 에러가 발생 할 경우 mysql stop 후 relay_log.info, relay_log.index 파일의 이름을 변경 후 재 시작 후
start slave 명령을 재 수행해 준다.
20. Promote slave to Master
Master 서버가 장애가 발생 하였을 경우, Slave 서버를 Master 서버로 승격 시켜야 하는데 이 경우의 시나리오들.
Slave들이 log-bin이 설정 되어서 운영되고 있었으면, 단순히 slave 서버에서 stop slave & reset master & change master to master_host='' 명령만으로 승격이 가능 함.
위의 예는 Master : Slave가 1:1 관계 일 때의 이야기 이고, Master : Slave가 1:M일 경우는 다음의 시나리오를 따른다.
참고 문서 :
1. https://dev.mysql.com/doc/refman/5.5/en/replication-solutions-switch.html
2. https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-switch.html
3. https://www.pythian.com/blog/mysql-recipes-promoting-a-slave-to-master-or-changing-masters/
Master : Slave = 1 : M 관계에서
승격 시킬 Slave 서버 선택
1. slave1, slave2, slave3 중에서 Master가 fault가 난 시점에 가장 많이 Master의 로그를 따라간 Slave 선택
show slave status 명령어 수행 후
Read_Master_Log_Pos: 442867964 <-- I/O스레드가 읽어 들인 Master의 로그 포지션
Exec_Master_Log_Pos: 442867964 <-- SQL스레드가 반영한 Master의 로그 포지션 (차이가 없어야 모두 반영 한 것임)
2. 위의 결과로 Slave1이 Master로 승격될 서버로 선정 되었다고 가정 함.
Slave1을 Master로 승격 시키는 경우 (마스터가 down되거나, 아니면 다른 이유로 인해서..)
|
Master |
Slave1 |
Slave2 |
Slave3 |
1 |
Flush logs ;
|
|
|
|
2 |
|
show processlist ; 명령 후 리플리케이션 상태가 'Has read all relay log' 상태 인 것을 확인 show master log; 명령을 이용하여 dml로그가 쌓이는지 확인. 안 쌓이고 있어야 함. |
|
|
3 |
mysqld stop |
stop slave ; |
stop slave ; |
stop slave ; |
4 |
|
reset master ; change master to master_host='' ; set global read_only=0 ; edit /etc/my.cnf read_only=0 |
|
|
5 |
|
|
change master to master_host='Slave1' ; |
change master to master_host='Slave1' ; |
6 |
|
|
start slave ; |
start slave ; |