반응형
반응형

고가용성(HA) :  서버와 네트워크, 프로그램 등의 정보 시스템이 상당히 오랜 기간 동안 지속적으로 정상 운영이 가능한 성질로

고(高)가용성이란 "가용성이 높다"는 뜻으로서, "절대 고장 나지 않음"을 의미한다.

고가용성은 흔히 가용한 시간의 비율을 99%, 99.9% 등과 같은 퍼센티지로 표현하는데, 1년에 계획 된 것 제외 5분 15초 이하의 장애시간을 허용한다는 의미의 파이브 나인스(5 nines), 즉 99.999%는 매우 높은 수준으로 고품질의 데이터센터에서 목표로 한다고 알려져 있다.

하나의 정보 시스템에 고가용성이 요구된다면, 그 시스템의 모든 부품과 구성 요소들은 미리 잘 설계되어야 하며, 실제로 사용되기 전에 완전하게 시험되어야 한다.

고가용성 솔루션(HACMP)을 이용하면, 각 시스템 간에 공유 디스크를 중심으로 집단화하여 클러스터로 엮어지게 만들 수 있다. 동시에 다수의 시스템을 클러스터로 연결할 수 있지만 주로 2개의 서버를 연결하는 방식을 많이 사용한다. 만약 클러스터로 묶인 2개의 서버 중 1대의 서버에서 장애가 발생할 경우, 다른 서버가 즉시 그 업무를 대신 수행하므로, 시스템 장애를 불과 몇 초만에 복구할 수 있다.


위와 같은 목적을 가지고 MySQL에서도 HA구성을 하게 되는데, 대표적으로 MHA(MasterHA)와 MySQL Fabric, MtoM이 있다.

제가 MySQL을 HA로 구성한 방법은 MHA이다.

MySQL Fabric보다 나아서라기보다는 기존의 MySQL 장비에 추가적인 작업 없이 HA를 구성할 수 있었으면 하고

MtoM은 IP에 대한 부분이 IP스위치가 어렵고 MHA는 자동으로 IP가 변경할 수 있기에 MHA로 구성을 해 보았다.


구성은 IP도 할당해야하고 대수도 여러대 필요하기 때문에 AWS에서 테스트를 해보았다.

호스트명

IP

bastion_server

172.31.2.124

mha_manager

172.31.13.97

my_master

172.31.9.88, 172.31.0.79

my_slave1

172.31.6.249

my_slave2

172.31.4.175

bastion_server는 AWS로 들어가는 진입통로이다. 나는 AWS를 접근할 때 처음 통로를 Bastion_server로 놓고 해당 서버에만

EIP를 주어 접속할 수 있게 해놓았다. 그리고 bastion_server에 pem파일을 올려 모든 서버는 bastion_server를 통해

접근하도록 설정되어 있다.

mha_manager는 모든 my_master의 장애를 모니터링하고 장애시 my_slave2가 master로써 승격되고 my_slave1은 기존 my_master에서 my_slave2에 동기화된다.  (bastion_server는 굳이 구성할 때 없어도 되는 서버이다.)







1. 기본 모듈 설치

[manager/master/slave1/slave2]

MHA Perl 모듈로 동작하기 때문에 펄 관련 모듈 설치

yum install -y perl-DBD-MySQL

yum install -y perl-Config-Tiny

yum install -y perl-Params-Validate

yum install -y perl-Parallel-ForkManager

yum install -y perl-Log-Dispatch

yum install -y perl-Time-HiRes

yum install -y perl-ExtUtils-MakeMaker

yum install -y perl-CPAN

 

#perl -MCPAN -e "install Config::Tiny"

#perl -MCPAN -e "install Log::Dispatch"

#perl -MCPAN -e "install Parallel::ForkManager"


2. MHA 노드 설치

[manager/master/slave/slave2]

https://code.google.com/p/mysql-master-ha/wiki/Downloads?tm=2/

mha4mysql-node-0.56.tar.gz download

mha4mysql-manager-0.56.tar.gz download


bastion_server 접속

sftp -o IdentityFile=/key_pair/XXXX.pem ec2-user@172.31.9.88

put mha4mysql-node-0.56.tar.gz

 

sftp -o IdentityFile=/key_pair/XXXX.pem ec2-user@172.31.6.249

put mha4mysql-node-0.56.tar.gz

 

sftp -o IdentityFile=/key_pair/XXXX.pem ec2-user@172.31.4.175

put mha4mysql-node-0.56.tar.gz

 

sftp -o IdentityFile=/key_pair/XXXX.pem ec2-user@172.31.13.97

put mha4mysql-node-0.56.tar.gz

put mha4mysql-manager-0.56.tar.gz

 

tar xvzf mha4mysql-node-0.56.tar.gz

cd mha4mysql-node-0.56

perl Makefile.PL

make

make install


3. MHA 매니저 설치

[manager]

mha_manager서버에 mha4mysql-manager 파일 설치

mkdir /data/mha_manager

cd /data/mha_manager

tar xvzf mha4mysql-manager-0.56.tar.gz

cd mha4mysql-manager-0.56

perl Makefile.PL

==> Auto-install the 1 mandatory module(s) from CPAN? [y] y

 

make

Would you like to configure as much as possible automatically? [yes]

CPAN build and cache directory? [/root/.cpan]

Download target directory? [/root/.cpan/sources]

Directory where the build process takes place? [/root/.cpan/build]

Always commit changes to config variables to disk? [no]

Cache size for build directory (in MB)? [100]

Let the index expire after how many days? [1]

Cache metadata (yes/no)? [yes]

Use CPAN::SQLite if available? (yes/no)? [no]

Policy on installing 'build_requires' modules (yes, no, ask/yes,

ask/no)? [yes]

Always try to check and verify signatures if a SIGNATURE file is in

the package and Module::Signature is installed (yes/no)? [no]

Generate test reports if CPAN::Reporter is installed (yes/no)? [no]

Do you want to rely on the test report history (yes/no)? [no]

Which YAML implementation would you prefer? [YAML]

Do you want to enable code deserialisation (yes/no)? [no]

<make>

Where is your make program? [/usr/bin/make]

 <bzip2>

Where is your bzip2 program? [/usr/bin/bzip2]

 <gzip>

Where is your gzip program? [/bin/gzip]

 <tar>

Where is your tar program? [/bin/tar]

Would you like to configure as much as possible automatically? [yes]

Would you like me to automatically choose some CPAN mirror

sites for you? (This means connecting to the Internet) [yes]

 

make install


4. SSH 설정

[manager/master/slave1/slave2]

모든 IP에 서로 SSH 접근이 가능하도록 추가해준다.

(AWS에서는 security_group에 22번 포트를 열어줌으로써 아래와 같은 작업이 불필요하다.)

vi /etc/hosts.allow

# for MHA

sshd: 172.31.2.124,172.31.1.164,172.31.4.134,172.31.4.134,172.31.0.79


[master/slave1/slave2]

MHA구성으로 사용한 시스템계정 생성

useradd -g mysql -d /home/mhauser -m -s /bin/bash mhauser

cat /etc/passwd | grep mhauser

 

passwd mhauser

패스워드 설정


[manager]

mha_manager 서버에도 시스템계정 생성

groupadd mysql

useradd -r -g mysql mysql

useradd -g mysql -d /home/mhauser -m -s /bin/bash mhauser

cat /etc/passwd | grep mhauser

 

passwd mhauser

 

[manager/master/slave1/slave2]

mhauser에 대한 SSH key파일 설정

su - mhauser

ssh-keygen

Generating public/private rsa key pair.

Enter file in which to save the key (/home/mhauser/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/mhauser/.ssh/id_rsa.

Your public key has been saved in /home/mhauser/.ssh/id_rsa.pub.

The key fingerprint is:

XXXX mhauser@bastion_server

 

cat /home/mhauser/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+Y1teVMIZF3K9X8LjEoHYpV9EFAusugbpXQB3pub8kZ

mhauser@bastion_server

 

 

manager, master, slave1, slave2 서버의 id_rsa.pub 파일을 각각 복사해 서버의 authorized_keys

파일에 붙여 넣는다.

 

cat /root/.ssh/authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+… mhauser@mha_manager

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWqz+… mhauser@my_master

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaeQE+… mhauser@my_slave1

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCg6QU… mhauser@my_slave2

 

 

[manager/master/slave/slave2]

해당 서버에 SSH 접속을 원활하게 하기 위해 /etc/hosts파일에 아래와 같이 내용을 추가한다.

그리고 .ssh 디렉토리 내의 파일에 대한 모든 권한을 변경한다.

(root계정으로 실행)

vi /etc/hosts

172.31.2.124

172.31.2.124 bastion_server

172.31.13.97

172.31.13.97 mha_manager

172.31.9.88

172.31.9.88  my_master

172.31.0.79

172.31.0.79 my_master

172.31.6.249

172.31.6.249 my_slave1

172.31.4.175

172.31.4.175 my_slave2

 

cd .ssh/

chmod 600 *

 

접속테스트(mhauser로 접속한 상태에서 테스트)

각 서버마다 접속해서 아래와 같이 전부 접속 테스트를 해준다.

ssh 172.31.2.124 hostname

ssh 172.31.13.97 hostname

ssh 172.31.9.88 hostname

ssh 172.31.0.79 hostname

ssh 172.31.6.249 hostname

ssh 172.31.4.175 hostname

 

아래와 같은 메시지가 나오면 yes를 누른다.

다음에 실행 시해당 IP 호스트명만 출력된다.

[mhauser@my_slave2 .ssh]$ ssh 172.31.4.175 hostname

The authenticity of host '172.31.4.175 (172.31.4.175)' can't be established.

ECDSA key fingerprint is 49:c7:ae:1c:90:1a:b1:a1:d1.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '172.31.4.175' (ECDSA) to the list of known hosts.

my_slave2

[mhauser@my_slave2 .ssh]$ ssh 172.31.4.175 hostname

my_slave2

 

[master/slave1/slave2]

sudo 권한에 변경작업을 해준다.

root계정 접속

 

visudo

#Default requiretty

 

mhauser ALL=(ALL) NOPASSWD:/sbin/ifconfig

 

[master]

my_master 서버에 서비스로 쓰이는 IP 하나를 할당해준다.

vip 할당

ifconfig eth0:0 172.31.0.79 netmask 255.255.0.0 broadcast 172.31.0.255 up

5. DB접속 계정 생성

[master/slave1/slave2]

MHA 매니저 서버(배스천)에서는 모든 DB서버의 MySQL에 접속할 수 있어야 한다.

/mysql/bin/mysql -uroot -p

grant all on *.* to mhauser@'172.31.2.124' identified by 'XXXXXXXX';

grant all on *.* to mhauser@'172.31.13.97' identified by 'XXXXXXXX';

grant all on *.* to mhauser@'172.31.0.79' identified by 'XXXXXXXX';

grant all on *.* to mhauser@'172.31.9.88' identified by 'XXXXXXXX';

grant all on *.* to mhauser@'172.31.6.249' identified by 'XXXXXXXX';

grant all on *.* to mhauser@'172.31.4.175' identified by 'XXXXXXXX';


[master/slave2]

master의 repl 계정 권한을 마스터 대체서버(slave2)에도 동일하게 적용

GRANT REPLICATION SLAVE, REPLICATION CLIENT

ON *.* TO 'repl'@'172.31.6.249' IDENTIFIED BY PASSWORD 'XXXXXXXX';

GRANT REPLICATION SLAVE, REPLICATION CLIENT

ON *.* TO 'repl'@'172.31.4.175' IDENTIFIED BY PASSWORD 'XXXXXXXX';

flush privileges;



6. MHA 설정

* master 대체 slave서버의 주의사항

- mysqlbinlog 버전이 5.1이상이어야 한다. master의 binlog가 row 포맷이면 mysqlbinlog 5.1부터는

  분석이 가능하다. 만약 5.1보다 낮으면 동기화시 row포맷을 사용해서는 안된다.

- DB서버의 binlog에 접근할 수 있게 디렉토리 권한을 설정해야 한다.

   (저는 mhauser를 mysql 그룹으로 묶어서 mysql이 접근가능한 디렉토리는 mhauser도 접근 가능하게 하였다.)

- 새로운 master가 될 slave에 binlog가 횔성화 되어 있어야 한다.(log-bin)

   (저는 log-bin 뿐만 아니라 log-bin=경로/파일명 이렇게하여 마스터와 동일한 경로와 파일명이 생기도록 하였다.)

- binlog와 relay log의 필터 규칙이 모든 MySQL DB군에서 동일해야 한다.

  즉, binlog에 대해 binlog-db-db나 replicate-ignore-db와 같은 필터 규칙이 정의되어 있다면 모든 MySQL은

  동일하게 해줘야 한다.

새로운 master가 될 slave에 read_only로 읽기 전용으로만 해두는 것이 나중에 교체시 문제를 최소화 시킬 수 있다.


[manager]

MHA를 사용하기 위한 디렉토리 생성

mkdir /data/mha_log                              ## mha 로그파일 저장

mkdir /data/mha_app                             ## mha 실행시 failover 프로그램 저장

mkdir /data/mha_scripts                           ## mha 스크립트 저장

chown mhauser:mysql /data/mha_log

chown mhauser:mysql /data/mha_app

chown mhauser:mysql /data/mha_scripts


7. MHA 매니저 서버 설정파일

* 싱글모드로 설정하여 테스트를 진행하였다.

1) 싱글모드

vi /etc/mha-manager.cnf

[server default]

user=mhauser

password=XXXXXXXX

repl_user=repl

repl_password=XXXXXXXX

 

## mha manager 실행파일이 생길 폴더 지정

manager_workdir=/data/mha_app

## 로그파일 지정

manager_log=/data/mha_log/mha4mysql.log

 

## mysql서버에 실행파일이 생길 폴더 지정

remote_workdir=/data/mha_app

## binlog 파일 폴더 지정

master_binlog_dir=/mysql/var

 

## mysql서버의 mysql 실행파일 폴더 지정

client_bindir=/mysql/bin

## mysql서버의 mysql 라이브러리가 저장되어 있는 폴더 지정

client_libdir=/mysql/lib

ignore_fail=2

 

[server1]

hostname = 172.31.9.88                     ## my_master ip

candidate_master=1

 

[server2]

hostname = 172.31.4.175                  ## replace slave2 ip

candidate_master=1

 

[server3]

hostname = 172.31.6.249                   ## slave1 ip

no_master=1


2) 다중모드

[manager]

vi /etc/mha-manager.cnf

[server default]

user=mhauser

password=XXXXXXXX

ssh_user=mhauser

 

master_binlog_dir=/mysql/var

remote_workdir=/data/mha_app

secondary_check_script= masterha_secondary_check -s remote_host1 -s remote_host2

ping_interval=3

master_ip_failover_script=/data/mha_script/master_ip_failover

shutdown_script=/data/mha_script/power_manager

report_script=/data/mha_script/send_master_failover_mail


vi /etc/my_master.cnf

[server_default]

manager_workdir=/data/mha_app

manager_log=/data/mha_log/mha4mysql.log

 

[server1]

hostname = 172.31.9.88                     ## my_master ip

candidate_master=1

 

[server2]

hostname = 172.31.4.175                  ## replace slave2 ip

candidate_master=1

 

[server3]

hostname = 172.31.6.249                   ## slave1 ip

no_master=1


[master]

할당된 IP 설정을 확인한다.

 

ifconfig

eth0      Link encap:Ethernet  HWaddr 02:8C:A2: 

          inet addr:172.31.9.88  Bcast:172.31.15.255  Mask:255.255.240.0

          inet6 addr: fe80::8c:a2ff:fe61:c841/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

          RX packets:106222 errors:0 dropped:0 overruns:0 frame:0

          TX packets:77495 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:112547338 (107.3 MiB)  TX bytes:11160527 (10.6 MiB)

 

eth0:0    Link encap:Ethernet  HWaddr 02:8C: 

          inet addr:172.31.0.79  Bcast:172.31.0.255  Mask:255.255.0.0

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

 

lo        Link encap:Local Loopback 

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:65 errors:0 dropped:0 overruns:0 frame:0

          TX packets:65 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:10938 (10.6 KiB)  TX bytes:10938 (10.6 KiB)

 

 


활성화

ifconfig eth0:0 172.31.0.79 netmask 255.255.0.0 broadcast 172.31.0.255 down


8. MHA모니터링 시작하기

mha 기동

cd /data/mha4mysql-manager-0.56/bin

nohup masterha_manager --conf=/etc/mha-manager.cnf < /dev/null > /data/mha_log/mha4mysql.log 2>&1 &


중단

/data/mha/mha4mysql-manager-0.56/bin/masterha_stop --conf=/etc/mha_manager.cnf


masterha_check_status로 masterha_manager 모니터링

 

./masterha_check_status --conf=/etc/mha-manager.cnf

mha-manager (pid:18325) is running(0:PING_OK), master:172.31.1.164

 

 


ssh접속이 정상적으로 이루어지는지 확인

 

masterha_check_ssh --conf=/etc/mha-manager.cnf

Thu Jan  5 08:02:14 2017 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.

Thu Jan  5 08:02:14 2017 - [info] Reading application default configuration from /etc/mha-manager.cnf..

Thu Jan  5 08:02:14 2017 - [info] Reading server configuration from /etc/mha-manager.cnf..

Thu Jan  5 08:02:14 2017 - [info] Starting SSH connection tests..

Thu Jan  5 08:02:15 2017 - [debug]

Thu Jan  5 08:02:16 2017 - [debug]   ok.

Thu Jan  5 08:02:16 2017 - [info] All SSH connection tests passed successfully.

 

 


리플리케이션 상태 모니터링

./masterha_check_repl --conf=/etc/mha-manager.cnf

MySQL Replication Health is OK.

 

 


호스트 정보 관리(IP추가)

./masterha_conf_host --command=add --conf=/etc/mha-manager.cnf --hostname=XXX.XXX.XXX.XXX

옵션 : --command=(add/delete)


[slave2]

slave2에 릴레이로그는 mysql 설치시 적용후 자동삭제하게 되어 있다.

master 대체 서버이기 때문에 릴레이로그를 purge하는 것을 중단하고 크론탭에 새벽에 자동 삭제할 수

있게 걸어 놓는다.

/mysql/bin/mysql -uroot -p

set global relay_log_purge=0

릴레이로그 삭제 설정

vi /etc/crontab

0 5 * * * /usr/local/bin/purge_relay_logs --user=root --disable_relay_log_purge >> /data/mha_log/purge_relay_logs.log 2>&1

 

 


9. 스크립트 생성

1) 스위치오버 시 vip도 자동으로 스위치 오버하는 스크립트 생성(root계정으로 실행)

cd /data/mha4mysql-manager-0.56/samples/scripts

cp master_ip_online_change master_ip_online_change.org

chown mhauser:mysql master_ip_online_change

vi master_ip_online_change

## Drop application user so that nobody can connect. Disabling per-session binlog beforehand

## $orig_master_handler->disable_log_bin_local();

## print current_time_us() . " Drpping app user on the orig master..\n";

## FIXME_xxx_drop_app_user($orig_master_handler);

 

## Creating an app user on the new master

      ## print current_time_us() . " Creating app user on the new master..\n";

      ## FIXME_xxx_create_app_user($new_master_handler);

      ## $new_master_handler->enable_log_bin_local();

      ## $new_master_handler->disconnect();

## =========================================================

## vip Change

if ( $new_master_ip eq "172.31.1.164") {

        system("/bin/sh /mysql/mha/scripts/change_vitual_ip_slave_to_master.sh");

}

elsif ( $new_master_ip eq "172.31.15.118") {

        system("/bin/sh /mysql/mha/scripts/change_vitual_ip_master_to_slave.sh");

}

else {}

## ========================================================

 

cd /data/mha_scripts/

vi change_virtual_ip_master_to_slave.sh

#!/bin/sh

 

ssh mhauser@172.31.15.118 sudo /sbin/ifconfig eth0:0 down

ssh mhauser@172.31.1.164 sudo /sbin/ifconfig eth0:0 172.31.0.79 netmask 255.255.0.0 broadcast 172.31.0.255 up

 

vi change_virtual_ip_slave_to_master.sh

#!/bin/sh

 

ssh mhauser@172.31.4.175 sudo /sbin/ifconfig eth0:0 down

ssh mhauser@172.31.9.88 sudo /sbin/ifconfig eth0:0 172.31.0.79 netmask 255.255.0.0 broadcast 172.31.0.255 up

 

vi /etc/mha-manager.cnf

master_ip_online_change_script=/data/mha_scripts/master_ip_online_change

 

 

 

2) 페일오버 시 vip도 자동으로 페일오버하는 스크립트

cd /data/mha4mysql-manager-0.56/samples/scripts

cp master_ip_failover /data/mha_scripts/

cd /data/mha_scripts/

chown mhauser:mysql master_ip_failover

 

vi master_ip_failover

## Creating an app user on the new master

## print "Creating app user on the new master..\n";

## FIXME_xxx_create_user( $new_master_handler->{dbh} );

## $new_master_handler->enable_log_bin_local();

## $new_master_handler->disconnect();

 

      ## Update master ip on the catalog database, etc

      #IXME_xxx;

## vip change

system("/bin/sh /data/mha_scripts/change_virtual_ip.sh");

 

vi change_virtual_ip.sh

#!/bin/sh

 

ssh mhauser@172.31.9.88 sudo /sbin/ifconfig eth0:0 down # master DB server vip down

ssh mhauser@172.31.4.175 sudo /sbin/ifconfig eth0:0 172.31.0.79 netmask 255.255.0.0 broadcast 172.31.0.255 up

 

vi /etc/mha-manager.cnf

master_ip_failover_script=/data/mha_scripts/master_ip_failover

 

cd /data/mha_scripts

chown mhauser:mysql *

 

 

 

10. 테스트

1) 상태확인

[master]

my_master 서버는 read 전용이 아니며 아래와 같은 master 상태값을 가지고 있다.

mysql> show variables like 'read_only';

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

| Variable_name | Value |

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

| read_only     | OFF   |

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

1 row in set (0.01 sec)

 

mysql> show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                       | Executed_Gtid_Set |

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

| mysql-bin.000004 |   120 |             | mysql,test,information_schema,performance_schema |          |

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

1 row in set (0.00 sec)

 

 

ifconfig

eth0      Link encap:Ethernet  HWaddr 02:8C:A2:61 

          inet addr:172.31.9.88  Bcast:172.31.15.255  Mask:255.255.240.0

          inet6 addr: fe80::8c:a2ff:fe61:c841/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

          RX packets:112357 errors:0 dropped:0 overruns:0 frame:0

          TX packets:82278 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:113169520 (107.9 MiB)  TX bytes:11858827 (11.3 MiB)

 

eth0:0    Link encap:Ethernet  HWaddr 02:8C:A2: 

          inet addr:172.31.0.79  Bcast:172.31.0.255  Mask:255.255.0.0

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

 

lo        Link encap:Local Loopback 

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:138 errors:0 dropped:0 overruns:0 frame:0

          TX packets:138 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:27398 (26.7 KiB)  TX bytes:27398 (26.7 KiB)

 

 

 

[slave1]

my_slave1은 현재 my_master(172.31.9.88) master로써 동기화하고 있다.

mysql> show slave status \G;

Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.31.9.88

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000005

          Read_Master_Log_Pos: 120

               Relay_Log_File: my_slave1-relay-bin.000009

                Relay_Log_Pos: 283

        Relay_Master_Log_File: mysql-bin.000005

             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: 120

              Relay_Log_Space: 623

              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: 88

                  Master_UUID: b3146e4b-d3e3-11e6-b88d-028ca261c841

             Master_Info_File: /mysql/var/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           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

 

[slave2]

my_slave2 my_master 대체 슬레이브로써 읽기 전용으로만 사용되고 있고 172.31.9.88(my_master)와 동기화 되어 있다.

mysql> show variables like 'read_only';

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

| Variable_name | Value |

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

| read_only     | ON    |

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

1 row in set (0.00 sec)

 

mysql> show slave status \G;

Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.31.9.88

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000004

          Read_Master_Log_Pos: 120

               Relay_Log_File: my_slave2-relay-bin.000006

                Relay_Log_Pos: 236

        Relay_Master_Log_File: mysql-bin.000004

             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: 120

              Relay_Log_Space: 576

              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: 88

                  Master_UUID: b3146e4b-d3e3-11e6-b88d-028ca261c841

             Master_Info_File: /mysql/var/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           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

 

[manager]

mha_manager 기동하여 위의 모든 서버들을 모니터링하게 한다.

su - mhauser

cd /data/mha4mysql-manager-0.56/bin/

nohup masterha_manager --conf=/etc/mha-manager.cnf < /dev/null > /data/mha_log/mha4mysql.log 2>&1 &

 

[master]

my_master서버에서 mysql를 kill하여 장애를 발생시킨다.

mysql kill

ps -ef | grep mysql

kill -9 22009 22921

 

위와 같이 할 경우, mha_manager서버의 /data/mha_log/mha4mysql.log파일에 마스터와 슬레이브가

스위칭 되는 로그가 남는다.

마지막에 failover report까지 나오면 스위칭이 완료된다.

 

ifconfig

eth0      Link encap:Ethernet  HWaddr 02:8C:A2:61:C8:41 

          inet addr:172.31.9.88  Bcast:172.31.15.255  Mask:255.255.240.0

          inet6 addr: fe80::8c:a2ff:fe61:c841/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

          RX packets:116549 errors:0 dropped:0 overruns:0 frame:0

          TX packets:85789 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:113678944 (108.4 MiB)  TX bytes:12379793 (11.8 MiB)

 

lo        Link encap:Local Loopback 

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:138 errors:0 dropped:0 overruns:0 frame:0

          TX packets:138 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:27398 (26.7 KiB)  TX bytes:27398 (26.7 KiB)

 

[slave2]

마스터에 있던 IP정보가 my_slave2 서버에 옮겨진 것을 확인할 수 있다.

 

ifconfig

eth0      Link encap:Ethernet  HWaddr 02:59:5C:47:DC:2D 

          inet addr:172.31.4.175  Bcast:172.31.15.255  Mask:255.255.240.0

          inet6 addr: fe80::59:5cff:fe47:dc2d/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

          RX packets:104714 errors:0 dropped:0 overruns:0 frame:0

          TX packets:60773 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:112706859 (107.4 MiB)  TX bytes:10153218 (9.6 MiB)

 

eth0:0    Link encap:Ethernet  HWaddr 02:59:5C:47:DC:2D 

          inet addr:172.31.0.79  Bcast:172.31.0.255  Mask:255.255.0.0

          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1

 

lo        Link encap:Local Loopback 

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:371 errors:0 dropped:0 overruns:0 frame:0

          TX packets:371 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:56561 (55.2 KiB)  TX bytes:56561 (55.2 KiB)

 

 

 

[slave1]

slave 상태를 확인하면 my_slave1 서버가 동기화하는 master IP가 변경된 것을 확인할 수 있다.

 

show slave status \G;

Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.31.4.175

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000004

          Read_Master_Log_Pos: 120

               Relay_Log_File: my_slave1-relay-bin.000002

                Relay_Log_Pos: 283

        Relay_Master_Log_File: mysql-bin.000004

             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: 120

              Relay_Log_Space: 460

              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: 175

                  Master_UUID: 02244886-d3e4-11e6-b88f-02595c47dc2d

             Master_Info_File: /mysql/var/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           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

 

 

 

[manager/master/slave/slave2]

mha_manager은 이렇게 IP와 동기화 되는 부분을 자동으로 변경하고 중지된다.

/data/mha_app를 삭제하지 않으면 mha_manager 기동 시 에러가 발생한다.

 

rm -f /data/mha_app/*

* MHA 구성시 에러사항 정리 

 

Mon Jan  9 04:24:20 2017 - [error][/usr/local/share/perl5/MHA/ManagerUtil.pm, ln177] Got Error on finalize_on_error at monitor: Permission denied:/data/mha_app/mha-manager.master_status.health at /usr/local/share/perl5/MHA/MasterMonitor.pm line 633.

chown mhauser.mysql mha_app

chown mhauser.mysql mha_scripts


 

Mon Jan  9 04:29:26 2017 - [error][/usr/local/share/perl5/MHA/ManagerUtil.pm, ln122] Got error when getting node version. Error:

Mon Jan  9 04:29:26 2017 - [error][/usr/local/share/perl5/MHA/ManagerUtil.pm, ln123]

mysql에 mha4node가 설치되어 있지 않았다. 


 

Mon Jan  9 05:28:53 2017 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln158] Binlog setting check failed!

Mon Jan  9 05:28:53 2017 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln405] Master configuration failed.

Mon Jan  9 05:28:53 2017 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln424] Error happened on checking configurations.  at /u

sr/local/bin/masterha_manager line 50.

Mon Jan  9 05:28:53 2017 - [error][/usr/local/share/perl5/MHA/MasterMonitor.pm, ln523] Error happened on monitoring servers.

Mon Jan  9 05:28:53 2017 - [info] Got exit code 1 (Not master dead).

mkdir /data/mha_app 

chown mhauser.mysql /data/mha_app

[출처] MHA 구성|작성자 theswice


반응형
반응형

MS-SQL 에서 MY-SQL 서버를 연결된 서버 ( Linked Server ) 로 등록하는 방법 


1. 제어판 - 관리 도구 - 데이터 원본(ODBC) 실행.

( mysql ODBC 설치가 안되어 있다면 http://dev.mysql.com/downloads/connector/odbc/Viewer 환경에 맞는 ODBC 설치 )






2. SSMS 에서 연결된 서버 - 새 연결된 서버 선택





3. 아래와 같이 입력.


일반 탭



보안 탭




완료 후 테스트 방법은 

OpenQuery 를 이용해서 쿼리를 날려봅니다.


오픈 쿼리에 대한 정보는 http://msdn.microsoft.com/ko-kr/library/ms188427.aspxViewer

반응형
반응형

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:lE9TM7sHONclMNYVtHrwfefdIV3lsn88ZJLuWYc6Rz8.
Please contact your system administrator.
Add correct host key in /Users/md/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/md/.ssh/known_hosts:1
RSA host key for XXX.XXX.XXX.XXX has changed and you have requested strict checking.
Host key verification failed.

원인은 재설치한 Centos에 ssh을 접속하였기 때문이라고 한다.
이전에 접속한 RSA 키 값으로 자꾸 접속하려니까 맞지 않았던 것이라고..
결론은 지우면 된다는거.

ssh-keygen -R [ IP or DomainName]


상단의 내용을 치니, 다음과 같이 나온다.
# Host XXX.XXX.XXX.XXX found: line 1
/Users/md/.ssh/known_hosts updated.
Original contents retained as /Users/md/.ssh/known_hosts.old

이렇게 뜬다면 성공한 것이다.

반응형
반응형
mysql-connector-odbc-5.2.6-winx64.msi

mysql 사이트에가서 다운받는다.

odbc 설치.




cursor/resuts 에서 return matched rows instated of affected rows 는 꼭 체크 한다.. openquery update linked Server 공급자 : Microsoft OLE DB Provider for ODBC Drivers 제품이름 : MySQL 데이터원본 : GA (시스템DNS) 공급자 문자열 : DRIVER[MYSQL ODBC 5.2 Unicode Driver];SERVER=xxx.xxx.xxx.xxx;PORT=3306 카탈로그 : db선택 보안 : 다음보안 컨텍스트트를 이용하여 연결 --시스템 DNS 에 설정한 아이디 비번 서버옵션 데이터엑스스 , RPC, RPC내보내기 , 언격 데이터 정렬 사용 ==> TRUE openquery 사용 select * from openquery(GA, 'select * from mysql_table') insert into openquery(GA, 'select seq from tb_xxxx') values (1) insert into openquery(GA, 'select seq from tb_xxxx') select seq from dbo.mssql_table delete openquery(GA, 'select seq from tb_xxxx') where seq > 0 update xx set xx.col = zz.col from openquery(GA, 'select seq, col from tb_xxxx') xx inner join mssql_table zz on xx.seq=zz.seq;


반응형
반응형

어떤 걸 설치하다보니 갑자기 mysql 이 시작되지 않고 

/usr/bin/mysqld_safe 이런 메시지가 뜨거나 

/var/log 어쩌구 샬라샬라 할 때가 있다.

그럼 100% 이전 my.cnf 를 찾고 있는거다.


find / -name my.cnf 

해서 찾아서 필요없는 건 지워라..-_-;

반응형
반응형

MYSQL에서 쿼리 작성 중 프로그램과의 형변환에러가 난다면

필드에 대한 연산 및 기타함수 사용 시 형변환에러가 난다.


이것은 필드의 형이 달라지는 것이 아닌 상수를 입력하거나

예를 들면 IFNULL(필드, 0)으로 입력 시 0이 기존적으로 BIGINT형식으로 처리되므로

프로그램상에서 필드= TINYINT 로 인식해야하는데 0의 값을 출력하게 되면 BIGINT로 출력하게 되므로

형변환 에러가 나는 것이다.



반응형

'연구개발 > MYSQL' 카테고리의 다른 글

mssql 에서 mysql linked Server 사용하기  (0) 2015.12.08
Couldn't find MySQL server  (0) 2015.11.12
mysql 동적쿼리  (0) 2015.08.05
구분자 함수  (0) 2015.07.28
프로시저  (0) 2015.06.22
반응형

SET @tmp1 = '12,13,14,15';

SET @xxx := CONCAT("SELECT * FROM t_user_master_card where user_seq = 1 and master_card_seq in (", @tmp1, ")");

SELECT @xxx;

PREPARE stmt FROM @xxx  ;

EXECUTE stmt   ;

DEALLOCATE PREPARE stmt ;



SET @tmp2 = 15;

SET @xxx := CONCAT("SELECT * FROM t_user_master_card where user_seq = 1 and master_card_seq in (?)");

SELECT @xxx;

PREPARE stmt FROM @xxx  ;

EXECUTE stmt USING @tmp2   ;

DEALLOCATE PREPARE stmt ;



반응형

'연구개발 > MYSQL' 카테고리의 다른 글

Couldn't find MySQL server  (0) 2015.11.12
형변환 에러시  (0) 2015.09.04
구분자 함수  (0) 2015.07.28
프로시저  (0) 2015.06.22
사용자 정의 변수  (0) 2015.06.16
반응형

use test;

delimiter //

create function strSplit(

   pi_str   varchar(100)

,  pi_delim varchar(5)

,  pi_pos   int

)

returns varchar(100)

charset utf8

deterministic

begin

   return replace(substring(substring_index(pi_str, pi_delim, pi_pos), length(substring_index(pi_str, pi_delim, pi_pos-1)) + 1), pi_delim, '');

end //

delimiter ;


select strSplit('A,B,C,D,E', ',', 2) ex1

      ,strSplit('A1,B2,C3,D4,E5',',',5) ex2

      ,strSplit('A1,B2,C3,D4,E5',',',9) ex3;



반응형

'연구개발 > MYSQL' 카테고리의 다른 글

형변환 에러시  (0) 2015.09.04
mysql 동적쿼리  (0) 2015.08.05
프로시저  (0) 2015.06.22
사용자 정의 변수  (0) 2015.06.16
Datetime 필드 기준 파티션 자동 관리 프로시저 (MySQL)  (0) 2015.06.11
반응형

프로시저 생성 시

OUT을 받을 것라면

프로시저 내에서 DECLARE po_result INT 를 선언하지 않아야 한다.



DROP PROCEDURE getName;

DELIMITER //

CREATE PROCEDURE getName

 (OUT po_result VARCHAR(50))

BEGIN

DECLARE v_sqlstate VARCHAR(5) DEFAULT '00000';

DECLARE v_msg VARCHAR(500);

DECLARE v_err_no INT;

--DECLARE po_result INT signed DEFAULT 0;    -- select로 po_result를 받을 거라면 선언하고 set로 받을거라면 선언하면 안됨.

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING


BEGIN


GET DIAGNOSTICS CONDITION 1 v_sqlstate = RETURNED_SQLSTATE, v_err_no = MYSQL_ERRNO, v_msg = MESSAGE_TEXT;

ROLLBACK;

INSERT INTO ADMIN_DB.log_error (partkey_month, procedure_name, sql_state, msg, reg_date) 

VALUES (month(sysdate()), "usp_ins_skill_index", v_sqlstate, v_msg, sysdate());

SET po_result = v_err_no * -1;

END;

BEGIN


SELECT no INTO @var1 FROM CopyT WHERE no = 1;

INSERT INTO CopyT1 VALUES (10000);

END;


  SET po_result= 0;

END//

DELIMITER ;



반응형

'연구개발 > MYSQL' 카테고리의 다른 글

mysql 동적쿼리  (0) 2015.08.05
구분자 함수  (0) 2015.07.28
사용자 정의 변수  (0) 2015.06.16
Datetime 필드 기준 파티션 자동 관리 프로시저 (MySQL)  (0) 2015.06.11
federated mysql의 linked server 구현  (0) 2015.06.10
반응형
MySQL에서는  두   가지  방법으로   사용자가  정의한  변수를   지원한다.  변수이름은 
alphanumeric 문자와 '_', '$', '.'로 구성된다. 변수에 초기값이 지정되지 않으면, NULL이 디
폴트이며, integer, real, string 값을 저장할 수 있다. 변수이름은 버전 5.0부터는 대·소문자
구분이 없다.

방법1)
SET 문을 사용하여 변수를 설정
SET @variable={integer expression | real expression | string expression }
[,@variable=...]

【예제】
mysql> set @t3=5;
mysql> select @t3;
+------+
| @t3 |
+------+
| 5 |
+------+
mysql>

방법2)
@variable:=expr 문을 사용하여 설정
【예제】
mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |
+----------------------+------+------+------+
| 5 | 5 | 1 | 4 |
+----------------------+------+------+------+


출처 - http://flashcafe.org/index.php?mid=mysql_study&listStyle=webzine&document_srl=3999


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


MySQL 사용자 정의 변수

09 사용자 정의 변수

 

변수의 적용 범위가 서버 전체이면 글로벌 변수 커넥션에 종속적이면 세션 변수

서버 실행중 변경가는한 변수에 따라 동적 변수와 정적 변수로 나눔

MySQL 서버의 설정 파일이나 MySQL 명령헹 인자르 통해 설정된 변수는 시스템변수

사용자 정의 변수는 임의로 이름을 부여할수있다

사용자 변수는 항상 세션변수로 취급하며 값을 변경 가능 하므로 동적 변수이다

사용자변수는 절차적인 목적으로 사용할수 있다

 

9.1 사용자 변수 소개

 

mysql> SET @str := ‘문자열’;

Query OK, 0 rows affected (0.00 sec)

 

mysql> SELECT @str;

+———–+

| @str      |

+———–+

| 문자열    |

+———–+

1 row in set (0.00 sec)

 

mysql> set @rownum=0;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select (@rownum=@rownum+1) as rownum, emp_no, first_name from employees limit 5;

+——–+——–+————+

| rownum | emp_no | first_name |

+——–+——–+————+

|      0 |  11800 | Aamer      |

|      0 |  11935 | Aamer      |

|      0 |  12160 | Aamer      |

|      0 |  13011 | Aamer      |

|      0 |  15332 | Aamer      |

+——–+——–+————+

5 rows in set (0.00 sec)

 

mysql> select (@rownum:=@rownum+1) as rownum, emp_no, first_name from employees limit 5;

+——–+——–+————+

| rownum | emp_no | first_name |

+——–+——–+————+

|      1 |  11800 | Aamer      |

|      2 |  11935 | Aamer      |

|      3 |  12160 | Aamer      |

|      4 |  13011 | Aamer      |

|      5 |  15332 | Aamer      |

+——–+——–+————+

5 rows in set (0.00 sec)

 

MySQL 5.0미만의 버전은 변수명의 대소문자를 구분함 그 이상 버전은 구분 하지 않음

사용자 정의 변수를 사용 하는 쿼리는 쿼리 캐시 기능을 사용 못함

초기화되지 않은 변수는 문자열 ‘NULL’값을 가진다

사용자 변수의 연산 순서는 정해져 있지 않다

MySQL 버전 차이에 따라 작동 방식이나 순서에 차이가 있기에 주의해야한다

 

9.2 기본 활용

 

mysql> select (@rownum:=@rownum+1) as rownum, emp_no, first_name

-> from employees, (select @rownum:=0) tab1

-> limit 5;

+——–+——–+————+

| rownum | emp_no | first_name |

+——–+——–+————+

|      1 |  11800 | Aamer      |

|      2 |  11935 | Aamer      |

|      3 |  12160 | Aamer      |

|      4 |  13011 | Aamer      |

|      5 |  15332 | Aamer      |

+——–+——–+————+

5 rows in set (0.00 sec)

 

set 명령어가 아닌 select 쿼리를 사용하여 초기화

 

mysql> set @old_sal:=50000;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select @old_sal, salary, @old_sal:=salary from salaries limit 1;

+———-+——–+——————+

| @old_sal | salary | @old_sal:=salary |

+———-+——–+——————+

|    50000 |  38623 |            38623 |

+———-+——–+——————+

1 row in set (0.00 sec)

 

mysql> set @old_sal:=50000;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select @old_sal, GREATEST(salary, LEAST(-1, @old_sal:=salary)) as salary from salaries limit 1;

+———-+——–+

| @old_sal | salary |

+———-+——–+

|    50000 |  38623 |

+———-+——–+

1 row in set (0.00 sec)

 

GRAETEST()         둘중 높은 값을 반환

LEAST()               둘중 낮은 값을 반환

 

old_sal 값을 salary칼럼 값으로 초기화함과 동시에 salary칼럼 값만 결과 셋으로 가져오는 쿼리임

 

9.3 시용자 변수 적용 예

 

9.3.1 N번째 레코드만 가져오기

 

mysql> select *

-> from departments, (select @rn:=0) x

-> where (@rn:=@rn+1)=3

-> order by dept_name;

+———+———–+——–+

| dept_no | dept_name | @rn:=0 |

+———+———–+——–+

| d002    | Finance   |      0 |

+———+———–+——–+

1 row in set (0.00 sec)

 

mysql> select *

-> from departments, (select @rn:=0) x

-> having (@rn:=@rn+1)=3

-> order by dept_name;

+———+———–+——–+

| dept_no | dept_name | @rn:=0 |

+———+———–+——–+

| d002    | Finance   |      0 |

+———+———–+——–+

1 row in set (0.00 sec)

 

이 예제는 테으블을 풀스캔하며 건수가 많은 테이블에서는 주의해서 사용해야한다.

 

9.3.2 누적 합계 구하기

 

mysql> select emp_no, salary, (@add_sal:=@add_sal+salary) as add_sal

-> from salaries, (select @add_sal:=0) x

-> limit 10;

+——–+——–+———+

| emp_no | salary | add_sal |

+——–+——–+———+

| 253406 |  38623 |   38623 |

|  49239 |  38735 |   77358 |

| 281546 |  38786 |  116144 |

|  15830 |  38812 |  154956 |

|  64198 |  38836 |  193792 |

| 475254 |  38849 |  232641 |

|  50419 |  38850 |  271491 |

|  34707 |  38851 |  310342 |

|  49239 |  38859 |  349201 |

| 274049 |  38864 |  388065 |

+——–+——–+———+

10 rows in set (0.00 sec)

 

*MySQL에서는 파생된 테이블을 만들어 내는 FROM 절의 서브쿼리에 반드시 별칭(‘x’)을 부여해야한다

 

9.3.3 그룹별 랭킹 구하기

 

mysql> select

emp_no, first_name, last_name,

if(@prev_first_name=first_name,

@rank:=@rank+1, @rank:=1+LEAST(0,@prev_first_name:=first_name)) rank

from employees, (select @rank:=0) x1, (select @prev_first_name:=’DUMMY’) x2

where first_name in (‘Georgi’,'Bezalel’)

order by first_name, last_name limit 5;

 

+——–+————+———–+——+

| emp_no | first_name | last_name | rank |

+——–+————+———–+——+

| 297135 | Bezalel    |Acton     |    1 |

|  25442 | Bezalel    | Adachi    |    2 |

| 446963 | Bezalel    | Aingworth |    3 |

| 241970 | Bezalel    | Anandan   |    4 |

| 241885 | Bezalel    | Ananiadou |    5 |

+——–+————+———–+——+

5 rows in set (0.01 sec)

 

 

9.3.4 랭킹 업데이트

 

mysql> create table tb_ranking (

member_id int not null,

member_score int not null,

rank_no int not null,

primary key (member_id),

index ix_mem (member_score)

);

Query OK, 0 rows affected (0.12 sec)

 

mysql> update tb_ranking r set r.rank_no = (@rank:=@rank+1) order by r.member_score DESC;

Query OK, 0 rows affected (0.03 sec)

Rows matched: 0  Changed: 0  Warnings: 0

 

9.3.5 GROUP BY 와 ORDER BY가 인덱스를 사용하지 못하는 쿼리

 

mysql> create table tb_uv (rid varchar(10));

Query OK, 0 rows affected (0.07 sec)

 

mysql> insert into tb_uv values (‘g’), (‘n’), (‘h’), (‘a’), (‘b’);

Query OK, 5 rows affected (0.04 sec)

Records: 5  Duplicates: 0  Warnings: 0

 

mysql> select  rid, @rank:=@rank+1 as rank

-> from tb_uv, (select @rank:=0) x

-> order by rid;

+——+——+

| rid  | rank |

+——+——+

| a    |    1 |

| b    |    2 |

| g    |    3 |

| h    |    4 |

| n    |    5 |

+——+——+

5 rows in set (0.02 sec)

 

mysql> select  rid, @rank:=@rank+1 as rank from tb_uv, (select @rank:=0) x group by rid order by rid;

+——+——+

| rid  | rank |

+——+——+

| a    |    4 |

| b    |    5 |

| g    |    1 |

| h    |    3 |

| n    |    2 |

+——+——+

5 rows in set (0.00 sec)

 

mysql> explain select  rid, @rank:=@rank+1 as rank from tb_uv, (select @rank:=0) x group by rid order by rid;

+—-+————-+————+——–+—————+——+———+——+——+———————————+

| id | select_type | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra                           |

+—-+————-+————+——–+—————+——+———+——+——+———————————+

|  1 | PRIMARY     | <derived2> | system | NULL          | NULL | NULL    | NULL |    1 | Using temporary; Using filesort |

|  1 | PRIMARY     | tb_uv      | ALL    | NULL          | NULL | NULL    | NULL |    5 |                                 |

|  2 | DERIVED     | NULL       | NULL   | NULL          | NULL | NULL    | NULL | NULL | No tables used                  |

+—-+————-+————+——–+—————+——+———+——+——+———————————+

3 rows in set (0.00 sec)

 

mysql> select rid, @rank:=@rank+1 as rank

-> from (

-> select rid from tb_uv

-> group by rid

-> order by rid

-> )x,

-> (select @rank:=0) y;

+——+——+

| rid  | rank |

+——+——+

| a    |    1 |

| b    |    2 |

| g    |    3 |

| h    |    4 |

| n    |    5 |

+——+——+

5 rows in set (0.03 sec)

 

mysql> alter table tb_uv add index ix_rid (rid);

Query OK, 0 rows affected (0.16 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> select rid, @rank:=@rank+1 as rank

-> from tb_uv, (select @rank:=0) x

-> group by rid

-> order by rid;

+——+——+

| rid  | rank |

+——+——+

| a    |    1 |

| b    |    2 |

| g    |    3 |

| h    |    4 |

| n    |    5 |

+——+——+

5 rows in set (0.01 sec)

 

9.4 주의사항

버전간에 호환성을 보장 하지 않는데 버전 업그레이드시 주의


출처 - http://os.raonnet.com/?p=51


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

구분자 함수  (0) 2015.07.28
프로시저  (0) 2015.06.22
Datetime 필드 기준 파티션 자동 관리 프로시저 (MySQL)  (0) 2015.06.11
federated mysql의 linked server 구현  (0) 2015.06.10
mysql 5.7 설치  (0) 2015.05.07
반응형

[출처] Datetime 필드 기준 파티션 자동 관리 프로시저 (MySQL)|작성자 돌고래사육사

http://seuis398.blog.me/70186283219


MySQL에서 파티셔닝은 성능 문제로 권장되는 옵션은 아니다.

하지만, 로그 데이터와 같이 주기적으로 과거 데이터를 삭제해야 되는 경우라면 파티셔닝이 매우 편리하다.

신규 파티션 추가와 오래된 파티션 삭제를 수작업으로 하기는 번거로울테니, 간단하게 이 과정을 자동화 해 줄 프로시저를 만들어 봄~


[파티션 관리 요건]

- 어떠한 이유에서든지 프로시저가 동작하지 않은 경우라도 데이터 INSERT 실패가 발생하지 않도록 할 것

- 프로시저가 일정 기간 동작하지 않고 다시 재가동 되는 경우에, 프로시저가 주기적으로 동작했던 것과 동일한 파티션 구조를 생성할 것

- 파티션 삭제시 Table Lock으로 인한 영향을 최소화 할 것


[파티션 생성 프로시저]

CREATE PROCEDURE create_partition(p_dbname varchar(255), p_tbname varchar(255), p_future INT, p_interval INT)

SQL SECURITY INVOKER
BEGIN
   DECLARE x, max_pdesc, new_pdesc INT;
   DECLARE pname VARCHAR(64);
   DECLARE alter_cmd VARCHAR(1024);
 
  -- 현재 테이블의 파티션의 가장 마지막 파티션의 HIGH VALUE 값을 구함
   SELECT MAX(PARTITION_DESCRIPTION) - TO_DAYS(current_date()) INTO x FROM information_schema.PARTITIONS
   WHERE TABLE_SCHEMA = p_dbname AND TABLE_NAME = p_tbname AND PARTITION_DESCRIPTION != 'MAXVALUE' ;

   -- 파티션 미리 생성할 기한까지 지정한 interval에 맞도록 파티션 추가
   -- 파티션 추가는 ADD PARTITION이 아닌 MAXVALUE 파티션의 REORGANIZE로 처리됨
   WHILE x <= p_future DO
      SELECT
         CONCAT('p', DATE_FORMAT(current_date() + interval MAX(PARTITION_DESCRIPTION) - TO_DAYS(current_date()) day, '%Y%m%d')),
         MAX(PARTITION_DESCRIPTION),
         MAX(PARTITION_DESCRIPTION) + p_interval
      INTO pname, max_pdesc, new_pdesc
      FROM information_schema.PARTITIONS
      WHERE TABLE_SCHEMA = p_dbname AND TABLE_NAME = p_tbname AND PARTITION_DESCRIPTION!='MAXVALUE';
    
      IF max_pdesc < new_pdesc THEN
         SET @alter_sql := CONCAT('ALTER TABLE ', p_dbname, '.', p_tbname, ' REORGANIZE PARTITION pMAXVALUE INTO (',
                          'PARTITION ', pname, ' VALUES LESS THAN (', new_pdesc, '), PARTITION pMAXVALUE VALUES LESS THAN MAXVALUE)' );
         PREPARE alter_cmd FROM @alter_sql;
         EXECUTE alter_cmd;     
         DEALLOCATE PREPARE alter_cmd;
      END IF;
      SET x = x + p_interval;
   END WHILE;
  
   -- 파티션 정보 출력 (옵션)
   SELECT current_date() + interval MAX(PARTITION_DESCRIPTION) - TO_DAYS(current_date()) - 1 day AS Last_Date,
          COUNT(*) AS Partitions_For_Future
   FROM information_schema.PARTITIONS
   WHERE TABLE_SCHEMA = p_dbname AND TABLE_NAME = p_tbname AND PARTITION_DESCRIPTION != 'MAXVALUE' 
      AND PARTITION_DESCRIPTION > TO_DAYS(current_date()) + 1;
END 


[파티션 삭제 프로시저]

CREATE PROCEDURE delete_partition(p_dbname varchar(255), p_tbname varchar(255), p_del_date INT)
SQL SECURITY INVOKER
BEGIN
   DECLARE done INT;
   DECLARE pname VARCHAR(64);
   DECLARE alter_cmd VARCHAR(1024);
   DECLARE deleted_partition VARCHAR(1024);

  -- 삭제할 파티션 목록 취합
   DECLARE cur CURSOR FOR
      SELECT PARTITION_NAME FROM information_schema.PARTITIONS
      WHERE TABLE_SCHEMA = p_dbname AND TABLE_NAME = p_tbname AND PARTITION_DESCRIPTION!='MAXVALUE'
        AND PARTITION_DESCRIPTION<=TO_DAYS(current_date()) - p_del_date ;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
   SET done = 0;
 
   -- 삭제 대상 파티션 목록 확인 및 작업 완료 후 출력 (옵션)

   SELECT GROUP_CONCAT(PARTITION_NAME) INTO deleted_partition 

   FROM information_schema.PARTITIONS
   WHERE TABLE_SCHEMA = p_dbname AND TABLE_NAME = p_tbname AND PARTITION_DESCRIPTION!='MAXVALUE'
     AND PARTITION_DESCRIPTION<=TO_DAYS(current_date()) - p_del_date ;
   
   OPEN cur;  
   FETCH cur INTO pname;

   WHILE done = 0 DO

     -- MySQL 5.6 버전 이상인 경우 동일 스키마로 빈 테이블을 만들어서 PARTITION EXCHANGE 처리 후 DROP PARTITION

     -- 파티션 삭제 처리 시간 지연으로 인한 Table Lock 영향을 최소화하기 위함

      IF left(version(),3) >= '5.6' THEN
         -- make empty table for exchange
         SET @alter_sql := CONCAT('CREATE TABLE ', p_dbname, '._exchange_', p_tbname, ' LIKE ', p_dbname, '.' , p_tbname);
         PREPARE alter_cmd FROM @alter_sql;
         EXECUTE alter_cmd;
         DEALLOCATE PREPARE alter_cmd;

         SET @alter_sql := CONCAT('ALTER TABLE ', p_dbname, '._exchange_', p_tbname, ' REMOVE PARTITIONING');
         PREPARE alter_cmd FROM @alter_sql;
         EXECUTE alter_cmd;
         DEALLOCATE PREPARE alter_cmd;

         -- exchange
         SET @alter_sql := CONCAT('ALTER TABLE ', p_dbname, '.', p_tbname, ' EXCHANGE PARTITION ', pname, ' WITH TABLE ', p_dbname, '._exchange_', p_tbname);
         PREPARE alter_cmd FROM @alter_sql;
         EXECUTE alter_cmd;
         DEALLOCATE PREPARE alter_cmd;

         -- drop tmp table
         SET @alter_sql := CONCAT('DROP TABLE ', p_dbname, '._exchange_', p_tbname);
         PREPARE alter_cmd FROM @alter_sql;
         EXECUTE alter_cmd;
         DEALLOCATE PREPARE alter_cmd;
      END IF;

      -- 파티션 삭제
      SET @alter_sql := CONCAT('ALTER TABLE ', p_dbname, '.', p_tbname, ' DROP PARTITION ', pname);
      PREPARE alter_cmd FROM @alter_sql;
      EXECUTE alter_cmd;
      DEALLOCATE PREPARE alter_cmd;
      
      FETCH cur INTO pname;
   END WHILE;

   CLOSE cur;


   -- 삭제 처리한 파티션 목록 출력 (옵션)
   SELECT deleted_partition AS Deleted_Partitions ;
END 


[동작 예시]

1) mydb.daily_table 테이블에 대해서 금일 날짜 기준으로 30일이 경과한 파티션을 삭제

 mysql> call delete_partition('mydb', 'daily_table', 30);
 +--------------------+
 | Deleted_Partitions        |
 +--------------------+
 | p20140610,p20140611  |  --> 삭제된 파티션 목록 출력됨
 +--------------------+

2) mydb.daily_table 테이블에 대해서 금일 날짜 기준으로 7일 후까지 1일 간격으로 파티션을 생성

  mysql> call create_partition('mydb', 'daily_table', 7, 1);
 +-----------+------------------+
 | Last_Date    | Partitions_For_Future | 
 +-----------+------------------+
 | 2014-07-18 |                       7 |  --> 미리 생성되어 있는 파티션들의 개수와 수용 가능한 날짜 정보 출력
 +-----------+------------------+
 

[이벤트 스케줄러 적용]

- 이벤트 스케줄러 미활성 상태인 경우 활성화, 이벤트 스케줄러 미지원 버전인 경우에는 crontab 등록
 set global event_scheduler=on;  -- my.cnf에도 추가

- 이벤트 생성 (프로시저는 mysql db에 생성한 것으로 가정)
DELIMITER $
drop event if exists evt_partition_management $

CREATE DEFINER=`root`@`localhost` EVENT evt_partition_management
ON SCHEDULE EVERY '1' DAY STARTS '2014-07-12 01:00:00'    -- 스케쥴러 시작 시점은 반드시 현재 날짜 기준으로 미래 시점이어야 함
DO
BEGIN
  call mysql.delete_partition('mydb', 'daily_table', 30);  
  call mysql.delete_partition('mydb', 'weekly_table', 180);
  call mysql.create_partition('mydb', 'daily_table', 3, 1);
  call mysql.create_partition('mydb', 'weekly_table', 14, 7);
END $
DELIMITER ;

 

[유의사항]

- 파티셔닝 키 컬럼이 datetime이 아닌 timestamp라면 HIGH VALUE 비교하는 부분 수정 필요 (date 타입은 사용 가능)

- MySQL이 아닌 MariaDB를 사용하는 경우 PARTITION EXCHANGE 부분에서 DB 버전 체크하는 부분 수정 필요

- 적용 대상 테이블은 사전에 RANGE 방식의 파티셔닝 구성이 되어 있어야 하며, MAXVALUE 파티션이 만들어져 있어야 함 


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

프로시저  (0) 2015.06.22
사용자 정의 변수  (0) 2015.06.16
federated mysql의 linked server 구현  (0) 2015.06.10
mysql 5.7 설치  (0) 2015.05.07
Avoiding Common MySQL Operations Mistakes.pdf  (0) 2015.04.10
반응형

mysql에서는 FEDERATED라는 엔진이 있다.
FEDERATED 테이블은 사용하기 매우 간단하며, 정상적인 경우, 동일한 호스트, 다른 
호스트 상에서 두대의 서버를 구동할 수 있습니다. 즉 FEDERATED 테이블이 동일한 서버가 관리하는 다른 테이블을 사용할 수 있다는 말이죠. 

우선, 여러분이 FEDERATED 테이블을 사용해서 접속하고자 하는 리모트 서버상에 테이블 가지고 있어야 한다. federated 데이터베이스에 리모트 테이블이 있고  그 테이블이 아래와 같이 정의 되었다고 가정하자: 

 CREATE TABLE test_table ( 
    id    INT(20) NOT NULL AUTO_INCREMENT, 
    name  VARCHAR(32) NOT NULL DEFAULT '', 
    other  INT(20) NOT NULL DEFAULT '0', 
    PRIMARY KEY  (id), 
    INDEX name (name), 
    INDEX other_key (other) 
) 
ENGINE=MyISAM 
DEFAULT CHARSET=latin1; 
  
위의 예문은 MyISAM 테이블을 사용하고는 있지만, 테이블은 모든 스토리지 엔진을 사용할 수 있습니다. 
다음에는, 리모트 테이블의 접속하기 위해 로컬 서버에 FEDERATED 테이블을 생성합니다. 

CREATE TABLE federated_table ( 
    id    INT(20) NOT NULL AUTO_INCREMENT, 
    name  VARCHAR(32) NOT NULL DEFAULT '', 
    other  INT(20) NOT NULL DEFAULT '0', 
    PRIMARY KEY  (id), 
    INDEX name (name), 
    INDEX other_key (other) 
) 
ENGINE=FEDERATED 
DEFAULT CHARSET=latin1 

CONNECTION='mysql://root@remote_host:9306/federated/test_table'; 
(MySQL 5.0.13 이전에는, COMMENT 를 CONNECTION 대신에 사용하였습니다.) 
  
이 테이블의 구조는 반드시 리모트 테이블의 구조와 정확히 같아야 하지만, except that the ENGINE 테이블 옵션은 FEDERATED이고 CONNECTION 테이블 옵션은 리모트 서버에 접속하는 방법을 FEDERATED 엔진에 알려주는 연결 스트링입니다. 

FEDERATED 엔진은 federated 데이터베이스에 test_table.frm 파일만을 생성합니다. 

리모트 호스트 정보는 리모트 서버에게 여러분의 로컬 서버가 어디에 접속되어 있는지를 알려 주고, 데이터베이스 및 테이블 정보는 데이터 소스로 사용되는 리모트 테이블이 어떤 것인지를 알려줍니다. 이 예문에서 보면, 리모트 서버는 remote_host 형태로 구동되어야 한다고 가리켜져 있기 때문에, 포트 9306에서, MySQL 서버는 리모트 서버에서 구동되어야 하고 포트 9306에 리스팅 되어야만 합니다. 

CONNECTION 옵션에서의 연결 스트링의 일반적인 형태는 다음과 같습니다. 
scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name 
이 시점에서 보면, 오직 mysql만이 scheme 값 형태로 지원된다; 패스워드와 포트 번호는 선택 사항입니다. 
아래에 몇 가지 연결 스트링에 대한 예가 있습니다. 

CONNECTION='mysql://username:password@hostname:port/database/tablename' 
CONNECTION='mysql://username@hostname/database/tablename' 
CONNECTION='mysql://username:password@hostname/database/tablename' 

연결 스트링을 지정하기 위한 CONNECTION의 사용은 논-옵티말 (non-optimal)이며 나중에 변경될 예정입니다.FEDERATED 테이블을 사용하는 어플리케이션에 대해서는 이점을 기억해 둡시다. 이러한 어플리케이션은, 연결 정보를 지정하기 위해 포맷이 변경되는 경우에는 수정이 필요할 수도 있습니다. 

연결 스트링에서 주어지는 모든 패스워드는 평이한 텍스트 형태로 저장되기 때문에, EDERATED 테이블에 대해서 SHOW CREATE TABLE 또는 SHOW TABLE STATUS를 사용하는 모든 사용자, 또는 INFORMATION_SCHEMA 데이터베이스에 있는TABLES 테이블을 쿼리하는 모든 사용자가 이것을 볼 수 있게 됩니다.


출처 : http://blog.naver.com/zamzacs/80037978241


반응형
반응형


41.mysql 5.7설치-program.zip


41.mysql 5.7설치.txt



안녕하세요. 준경대디 입니다.

 

"머리만1톤"님도 언급하셨지만,

경우에 따라 기존 설치스크립트대로 MySQL 5.7 설치해보면 여러가지 난관을 경험하게 됩니다.

 

저도 동일한 어려움을 겪고 고생한 적이 있었는데,

문제없이 설치되는 스크립트 공유해 봅니다.

 

 

-- =================================================================================
-- 필수 프로그램 설치
-- =================================================================================

sudo su -

 

yum install -y gcc automake autoconf libtool make cpan libstdc* libaio*
yum install -y perl perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-Params-Validate
yum install -y gzip unzip sysstat* iotop

 

 

-- =================================================================================
-- OS 환경 설정
-- =================================================================================

sudo su -

 

echo ""
echo "*          -       nofile    65536"     >> /etc/security/limits.d/90-nproc.conf
echo "*          -       nproc     unlimited" >> /etc/security/limits.d/90-nproc.conf

cat /etc/security/limits.d/90-nproc.conf

 

echo /usr1/mysql/5705/lib                 >> /etc/ld.so.conf && ldconfig
echo /usr/lib64                           >> /etc/ld.so.conf && ldconfig
echo PATH=$PATH:/usr1/mysql/5705/bin      >> /etc/profile && source /etc/profile

cat /etc/ld.so.conf

. /etc/profile

 

 

-- =================================================================================
-- Installing MySQL 5.7.5 Step.1
-- =================================================================================

sudo su -

 

mkdir -p /usr1/program

 

rm -rf /usr1/mysql/DBSpace_VM

mkdir -p /usr1/mysql/DBSpace_VM/ADMIN
mkdir -p /usr1/mysql/DBSpace_VM/DATA
mkdir -p /usr1/mysql/DBSpace_VM/BINLOG
mkdir -p /usr1/mysql/DBSpace_VM/RELAYLOG
mkdir -p /usr1/mysql/DBSpace_VM/IBLOG
mkdir -p /usr1/mysql/DBSpace_VM/BACKUP

mkdir -p /usr1/mysql/dba/log

ls -l /usr1/mysql/DBSpace_VM/*

 

 

tail -1 /etc/group
tail -1 /etc/passwd

groupadd mysql

useradd super-dba -g mysql -d /home/super-dba

passwd super-dba

tail -1 /etc/group
tail -1 /etc/passwd

 

 

cd /usr1/program

ls -l

-- 프로그램 다운로드 & 업로드

#   -rw-r--r--. 1 root root   1042165 May 27  2014 common_schema-2.2.sql
#   -rw-r--r--. 1 root root     88964 Sep  4 15:10 htop-1.0.3-1.el7.rf.x86_64.rpm
#   -rw-r--r--. 1 root root 423605472 Dec  2 22:56 mysql-5.7.5-m15-linux-glibc2.5-x86_64.tar.gz
#   drwxr-xr-x. 5 root root      4096 Feb 23 15:56 mysql-sys-master
#   -rw-r--r--. 1 root root     52794 Sep 23 22:31 zzdba_objects_v1.2_20140901.sql

#   wget https://downloads.mariadb.com/archives/mysql-5.7/mysql-5.7.5-m15-linux-glibc2.5-x86_64.tar.gz

 

tar zxvf mysql-5.7.5-m15-linux-glibc2.5-x86_64.tar.gz

mv mysql-5.7.5-m15-linux-glibc2.5-x86_64 /usr1/mysql/5705

ls -l


cd /usr1/mysql/

ls -l


cat /etc/ld.so.conf

. /etc/profile

 

ls -l /etc/my.cnf

mv /etc/my.cnf /etc/my.cnf.old

ln -s /usr1/mysql/DBSpace_VM/ADMIN/my.cnf /etc/my.cnf

ls -l /etc/my.cnf

 

vi /usr1/mysql/DBSpace_VM/ADMIN/init.sql
================================================================
set global max_connections = 1000;
================================================================

 

vi /etc/my.cnf
================================================================
... 맨 아래 참고 ...
================================================================

 

chown -R super-dba:mysql /usr1

ls -l /usr1/mysql

 

 

-- =================================================================================
-- Installing MySQL 5.7.5 Step.2
-- =================================================================================

sudo su -

 

cd /usr1/mysql/5705

 

ls -l /usr1/mysql/DBSpace_VM/*

 

./bin/mysql_install_db --no-defaults --insecure -uroot --datadir=/usr1/mysql/DBSpace_VM/DATA --lc-messages-dir=/usr1/mysql/5705/share --lc-messages=en_US -v --defaults-file=/etc/my.cnf --basedir=/usr1/mysql/5705 --user=super-dba

 

ls -l /usr1/mysql/DBSpace_VM/*

 

cat ./../DBSpace_VM/ADMIN/error.log

 

 

-- =================================================================================
-- Installing MySQL 5.7.5 (3)
-- =================================================================================

sudo su -

 

ls -l /etc/init.d/mysqld

ln -sv /usr1/mysql/5705/support-files/mysql.server  /etc/init.d/mysqld

ls -l /etc/init.d/mysqld

 

 

### MySQL 기동 ###

ps -ef | grep mysqld

su - super-dba -c "service mysqld   start"
su - super-dba -c "service mysqld restart"

ps -ef | grep mysqld

 

 

### MySQL root 유저 암호 설정 ###

su - super-dba -c "/usr1/mysql/5705/bin/mysqladmin -u root password oracle"
su - super-dba -c "/usr1/mysql/5705/bin/mysql -uroot --password=oracle -e \"select version();\""

 

su - super-dba -c "/usr1/mysql/5705/bin/mysql -uroot --password=oracle"

   select user, host, password from mysql.user order by user, host;

   delete from mysql.user where user = '';
   update mysql.user set password=password('oracle') where user = 'root';
   drop user 'root'@'::1';

   select user, host, password from mysql.user order by user, host;

   flush privileges;

   exit;

su - super-dba -c "/usr1/mysql/5705/bin/mysql -uroot --password=oracle -e \"select version();\""

 

 

-- =================================================================================
-- OS 유저 (super-dba) 설정
-- =================================================================================

sudo su - super-dba

 

vi /usr1/mysql/dba/.env.ini
=============================================================
#!/bin/bash

export MySQL_VER=5705
export MySQL_BASE=/usr1/mysql
export MySQL_HOME=$MySQL_BASE/$MySQL_VER
export MySQL_PORT=3336
export MySQL_SID=testdb
=============================================================

chmod +x /usr1/mysql/dba/.env.ini

 

 

vi ~/.bash_profile
=============================================================
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

 

export PS1=`hostname`:'$PWD> '

export LD_LIBRARY_PATH=/usr/lib:/usr/local/lib
export PATH=$PATH:$HOME/bin
export PATH=$PATH:/bin:/usr/bin/java/bin:/bin:/usr/bin:/usr/sbin:/etc:/usr/etc
export PATH=$PATH:/usr1/mysql/5705/bin

export TEMPDIR=/tmp
export EDITOR=vi

alias ll="ls -al --color=auto"

source /usr1/mysql/dba/.env.ini
=============================================================

source ~/.bash_profile

 

ps -ef | grep mysqld

service mysqld restart

ps -ef | grep mysqld

 

 

-- =================================================================================================
-- DB 계정 생성
-- =================================================================================================

mysql -u root --password=oracle

   select version();

   select user, host, password from mysql.user order by user, host;

   GRANT SELECT, UPDATE, INSERT, DELETE, EXECUTE ON *.*           TO svc_user@'192.168.86.%' IDENTIFIED BY 'oracle';

   GRANT SELECT, EXECUTE                         ON `test%`.*     TO etl_reader@'%'          IDENTIFIED BY 'oracle';

   GRANT REPLICATION SLAVE                       ON *.*           TO 'repl_dba'@'%'          IDENTIFIED BY 'oracle';

   GRANT SELECT, PROCESS, SUPER, EVENT           ON *.*           TO 'percona_cacti'@'%'     IDENTIFIED BY 'oracle';
   GRANT UPDATE                                  ON `moniter`.*   TO 'percona_cacti'@'%'     IDENTIFIED BY 'oracle';
   GRANT ALL PRIVILEGES                          ON `sys`.*       TO 'percona_cacti'@'%'     IDENTIFIED BY 'oracle';

   FLUSH PRIVILEGES;

   select user, host, password from mysql.user order by user, host;

   show databases;

   create database test;

   show databases;

   exit

 

 

-- =================================================================================================
-- mysql_config_editor 설정
-- =================================================================================================

mysql_config_editor print --all

mysql_config_editor remove --login-path=dbreplica
mysql_config_editor remove --login-path=dbmon
mysql_config_editor remove --login-path=dbreader

mysql_config_editor print --all


mysql_config_editor set --login-path=dbmon     --host=localhost   --user=root        --password --socket=/tmp/mysql.sock --port=3336
mysql_config_editor set --login-path=dbreplica --host=localhost   --user=repl_dba    --password --socket=/tmp/mysql.sock --port=3336
mysql_config_editor set --login-path=dbreader  --host=localhost   --user=etl_reader  --password --socket=/tmp/mysql.sock --port=3336


mysql --login-path=dbmon     -e "SELECT NOW()";
mysql --login-path=dbreplica -e "SELECT NOW()";
mysql --login-path=dbreader  -e "SELECT NOW()";

 

 

-- =================================================================================================
-- zzdba Database 설정
-- =================================================================================================

cd /usr1/program/mysql-sys-master

mysql -u root --password=oracle

   show databases;


   tee /usr1/program/zz_install_zzdba.log

   source /usr1/program/zzdba_objects_v1.2_20140901.sql

   notee

   system cat /usr1/program/zz_install_zzdba.log | grep err

   -- system vi /usr1/program/zz_install_zzdba.log

 

   tee /usr1/program/zz_install_common_schema.log

   source /usr1/program/common_schema-2.2.sql

   show global variables like 'thread_stack';

   notee

   system cat /usr1/program/zz_install_common_schema.log | grep err

   -- system vi /usr1/program/zz_install_common_schema.log

   /*
   ====================================================================
   +---------------+--------+
   | Variable_name | Value  |
   +---------------+--------+
   | thread_stack  | 524288 |
   +---------------+--------+

   -- 최소 thread_stack = 256K 이상 권장함
   ====================================================================
   */

 

   tee /usr1/program/zz_install_mysql-sys-master.log

   show databases;

   source sys_56.sql

   show databases;

   select * from statements_with_full_table_scans limit 1;

   notee

 

   select * from zzdba.dba_metadata limit 10;

   insert into zzdba.dba_metadata (name, value, reg_date)
   select 'BUF_TAB_BIG_SIZE'
        , data
        , now()
     from sys.x$innodb_buffer_stats_by_table
    order by data desc limit 1
       ON DUPLICATE KEY UPDATE value = values(value), reg_date=values(reg_date);

   update zzdba.dba_metadata set svc_name = 'testdb';

   select * from zzdba.dba_metadata limit 10;

 

   exit

 

 

-- =================================================================================================
-- nmon 설정
-- =================================================================================================

sudo su -

 

cd /usr1/program

wget http://sourceforge.net/projects/nmon/files/nmon_linux_14i.tar.gz

tar zxvfp nmon_linux_14i.tar.gz

chmod +x nmon*

mv nmon_x86_64_centos6 /usr/bin/nmon

rm -rf nmon*

mkdir -p /usr1/mysql/dba/log/nmon
mkdir -p /usr1/mysql/dba/log/top
mkdir -p /usr1/mysql/dba/cron/

 

ls -l /usr1/mysql/dba/cron/top.sh

echo '#!/bin/bash'                                                > /usr1/mysql/dba/cron/top.sh
echo ''                                                          >> /usr1/mysql/dba/cron/top.sh
echo 'BACKUP_FILE=/usr1/mysql/dba/log/top/top.`date "+%Y%m%d"`'  >> /usr1/mysql/dba/cron/top.sh
echo ''                                                          >> /usr1/mysql/dba/cron/top.sh
echo '/usr/bin/top  -c -b -n720 -d120 > $BACKUP_FILE'            >> /usr1/mysql/dba/cron/top.sh
echo '/bin/gzip $BACKUP_FILE'                                    >> /usr1/mysql/dba/cron/top.sh
echo ''                                                          >> /usr1/mysql/dba/cron/top.sh
echo '# -c : display full command (not command name only)'       >> /usr1/mysql/dba/cron/top.sh
echo '# -b : Batch mode'                                         >> /usr1/mysql/dba/cron/top.sh
echo '# -n : Number of iterations'                               >> /usr1/mysql/dba/cron/top.sh
echo '# -d : Delay (sec)'                                        >> /usr1/mysql/dba/cron/top.sh

chmod +x /usr1/mysql/dba/cron/top.sh

ls -l /usr1/mysql/dba/cron/top.sh

 

crontab -e

############################################################
# Monitoring by root
############################################################
00 10 * * *    /usr/bin/nmon -f -s 60 -c 1440 -m /usr1/mysql/dba/log/nmon
20 10 * * *    sh /usr1/mysql/dba/cron/top.sh

 

crontab -l


chown -R super-dba:mysql /usr1/


exit

 

-- =================================================================================================
-- dba 폴더 설정
-- =================================================================================================

....

 


-- =================================================================================================
-- 참고.my.cnf
-- =================================================================================================
################################################################
## my.cnf                                                      #
################################################################
[client]
port                                           = 3336
socket                                         = /tmp/mysql.sock
#password                                      = your_password

[mysqld]
server-id                                      = 9999
user                                           = super-dba
port                                           = 3336
socket                                         = /tmp/mysql.sock
basedir                                        = /usr1/mysql/5705
datadir                                        = /usr1/mysql/DBSpace_VM/DATA
tmpdir                                         = /tmp
pid-file                                       = /tmp/mysqld.pid
init_connect                                   = 'SET NAMES utf8;'
init-file                                      = /usr1/mysql/DBSpace_VM/ADMIN/init.sql
character-set-server                           = utf8
collation-server                               = utf8_general_ci
skip-character-set-client-handshake
skip-host-cache
skip-name-resolve
skip-external-locking
skip-slave-start
sysdate-is-now

event_scheduler                                = ON
general-log                                    = OFF
general-log-file                               = /usr1/mysql/DBSpace_VM/ADMIN/general.log
sql_mode                                       = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
log_output                                     = FILE
slow-query-log                                 = ON
slow-query-log-file                            = /usr1/mysql/DBSpace_VM/ADMIN/slowquery.log
long_query_time                                = 0.2
log-queries-not-using-indexes                  = OFF
log-bin                                        = /usr1/mysql/DBSpace_VM/BINLOG/mysql_bin
expire_logs_days                               = 3
log-warnings                                   = 2
log-error                                      = /usr1/mysql/DBSpace_VM/ADMIN/error.log
sync_binlog                                    = 0

back_log                                       = 1024
max_connections                                = 500
max_connect_errors                             = 9999999999
table_open_cache                               = 15000
max_allowed_packet                             = 4M
max_heap_table_size                            = 128M
tmp_table_size                                 = 128M
read_rnd_buffer_size                           = 2M
read_buffer_size                               = 512K
sort_buffer_size                               = 512K
join_buffer_size                               = 512K
thread_cache_size                              = 2048
query_cache_type                               = DEMAND
query_cache_size                               = 64M
query_cache_limit                              = 512K
thread_stack                                   = 512K
ft_min_word_len                                = 4

wait_timeout                                   = 300
interactive_timeout                            = 28800
connect_timeout                                = 300
net_read_timeout                               = 172800
net_write_timeout                              = 172800


default-storage-engine                         = INNODB

lower_case_table_names                         = 1
binlog_cache_size                              = 2M
binlog_format                                  = MIXED
binlog_row_image                               = MINIMAL
transaction_isolation                          = READ-COMMITTED
max_binlog_size                                = 128M
log_bin_trust_function_creators                = 1
open-files-limit                               = 65535

explicit_defaults_for_timestamp                = TRUE


########################################
# INNODB Specific options
########################################
innodb_data_home_dir                           = /usr1/mysql/DBSpace_VM/DATA
innodb_log_group_home_dir                      = /usr1/mysql/DBSpace_VM/IBLOG
innodb_buffer_pool_size                        = 1GB
#innodb_buffer_pool_instance                   = 8
innodb-buffer-pool-instances                   = 8
innodb_data_file_path                          = ibdata1:500M:autoextend
innodb_file_per_table                          = 1

innodb_write_io_threads                        = 8
innodb_read_io_threads                         = 8
innodb_force_recovery                          = 0
innodb_thread_concurrency                      = 16
innodb_flush_log_at_trx_commit                 = 2

innodb_log_buffer_size                         = 8M
innodb_log_file_size                           = 50M
innodb_log_files_in_group                      = 10

innodb_max_dirty_pages_pct                     = 30
innodb_flush_method                            = O_DIRECT
innodb_lock_wait_timeout                       = 15

innodb_doublewrite                             = ON
innodb_file_format                             = Barracuda
innodb_file_format_max                         = Barracuda

innodb_status_file                             = 1
innodb_adaptive_flushing                       = 1
innodb_use_native_aio                          = 1
#innodb_purge_thread                           = 1
innodb-purge-threads                           = 1
innodb_fast_shutdown                           = 0

innodb_stats_auto_recalc                       = OFF
innodb_stats_persistent                        = OFF
innodb_sort_buffer_size                        = 2M
innodb_print_all_deadlocks                     = ON

skip-innodb_adaptive_hash_index

performance_schema                             = ON

federated

innodb_io_capacity                             = 2000
innodb_io_capacity_max                         = 10000

########################################
# Replication related settings
########################################
replicate-ignore-db                            = perf_mon
replicate-ignore-db                            = sys
replicate-ignore-db                            = moniter
replicate-ignore-db                            = mysql
#replicate-do-db                               = xxxdb
#
#relay_log_purge                               = OFF
#relay-log                                     = /usr1/mysql/DBSpace_VM/RELAYLOG/mysql_relay
#log_slave_update
#########################################


########################################
# MyISAM Specific options
########################################
key_buffer_size                                = 64M
bulk_insert_buffer_size                        = 16M
myisam_sort_buffer_size                        = 16M
myisam_max_sort_file_size                      = 16M
myisam_repair_threads                          = 1
#myisam_recover
myisam-recover-options


[mysqldump]
quick
max_allowed_packet                             = 64M


[mysql]
no-auto-rehash
prompt                                         = '[\h] (\d) \R:\m> '


[myisamchk]
key_buffer_size                                = 64M
sort_buffer_size                               = 16M
read_buffer                                    = 16M
write_buffer                                   = 16M


[mysqlhotcopy]
interactive-timeout


[mysqld_safe]
open-files-limit                               = 65535

-- =================================================================================================



출처 : http://cafe.naver.com/mysqlpg/838

반응형
반응형

➨ MYSTERY CONFIGURATION

- config(/etc/my.cnf) 파일 수정시 source control(svn, git) 을 사용해라.


➨ ABANDONED EXPERIMENTS

- default 값이 잘 선택된 값일 지라도 해당 작업 환경에서 더 나은 config value 를 테스트하고 적용해라.


➨ AIMLESS TUNING

- 튜닝 방식에 대한 설명..

- e.g. variables sort_buffer_size 에 대한 영향은 status sort_merge_passes 로 확인 할 수 있다. 해당 변수의 변경우 status 확인으로 최적화된 값을 찾는다.

- pt-mtext (percona-toolkit) 과 Percona monitoring plugin 을 활용할 수 있다.

- global variables 와 session 별 할당 가능한 variables 을 구분하여 활용


➨ BRITTLE BACKUPS

- 복원할수 있는 백업을 해라

- 복원에 대한 전략 / 단계 수립 필요

- 단계별 복원에 대한 테스트를 통하여 백업 전략(스크립트) 수정

- Don’t think of a backup strategy – instead think of a restore strategy


➨ DRIFT HAPPENS

- repliction 의 데이타가 master 와 일치 하지 않을 수 있다.

- set global read_only=1 과 binlog_format=row 가 도움을 줄수 있다.

- pt-table-checksum 으로 확인 가능.  cron 활용 주기적으로 확인필요

- pt-table-sync 로 sync


➨ INDEX HOARDING

- index size 측정 : information_schema.tables.index_length,  INFORMATION_SCHEMA.innodb_buffer_page

- duplicate index 확인 : pt-duplicate-key-checker

- unused index 확인 : pt-index-usage

- schema.table_io_waits_summary_by_index_usage


SELECT OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, COUNT_STAR

FROM performance_schema.table_io_waits_summary_by_index_usage

WHERE COUNT_STAR = 0 AND INDEX_NAME != 'PRIMARY'

AND OBJECT_SCHEMA NOT IN ('mysql', 'performance_schema');


- schema/application 등의 변경 후 주기적 체크 clean up 작업 필요


➨ NO CAPACITY MONITORING

- disk bottlenecks 체크 (disk full, san failure, raid failure)

- io benchmark -> sysbench

- df, iostat 등 활용 monitoring

- cacti alert plugin 활용


➨ SERVICE INTERRUPTIONS

- ALTER TABLE

  : mysql 5.6 online alter table

  : pt-online-schema-change

- upgrade  ( Use a pair of MySQL servers, replicating both ways / master-master replication)

- server failover -> cluster (Percona XtraDB Cluster)



[출처] Avoiding Common MySQL Operations Mistakes.pdf|작성자 SMR

http://blog.naver.com/suheon_kim/120207747626


반응형
반응형

백업 . 

mysqldump --compress --max_allowed_packet=500M -h myhost mydb | gzip > /tmp/mydb.sql.gz 

 

복구

gunzip < /tmp/mydb.sql.gz | mysql --quick --reconnect -u myuser -pmypass -h localhost -D mydb 

 

관련사이트 

http://dba.stackexchange.com/questions/17008/how-to-speed-up-a-loading-data-into-mysql-from-a-zipped-archive 



 [출처] mysql 대용량 백업 빠르게하기. speed up mysqldump |작성자 무한돌파

http://blog.naver.com/kikikl/130171785626

반응형
반응형

1. [Master] Table 백업 : mysqldump --master-data=2

2. [Slave] Replication 중단
1) STOP SLAVE;
2) MASTER_LOG_FILE, MASTER_LOG_POS 확인

3. [임시서버] Replication 을 이용하여 Table Recovery 진행
1) dump 받은 파일 import
2) START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE = 'Log_name', MASTER_LOG_POS = Log_pos;
3) 복구된 테이블 export

4. [Slave] 복구된 테이블 import 및 Replication 재개
1) import
2) START SLAVE;


반응형
반응형

출처: http://www.cmsfactory.net/node/10448

MySQL Database(DB)별로 백업하는 쉘 스크립트

MySQL 데이터베이스는 mysqldump로 백업할 수 있습니다.

다음은 한번의 실행으로 MySQL을 Database별로 백업하는 스크립트입니다.

root 사용자로 백업할 때의 코드로, root이 아닌 사용자로 백업할 경우 빨간색 부분을 해당 사용자 이름으로 변경해야 합니다.

#!/bin/bash
backup_dir="/home/jb_backup/WebSite"
rm -f $backup_dir/*.sql
read pw
db_list=`mysql -uroot -p$pw -e "show databases" | tail -n+2`;
for db_name in $db_list; do
 if [ "$db_name" != "information_schema" -a "$db_name" != "mysql" -a "$db_name" != "performance_schema" -a "$db_name" != "phpmyadmin" -a "$db_name" != "test" ]; then
   mysqldump -uroot -p$pw $db_name > $backup_dir/$db_name.sql
 fi
done

각 코드의 의미는 다음과 같습니다.

#!/bin/bash

스크립트 시작을 알립니다.

backup_dir="/home/backup"

백업할 디렉토리를 정합니다.

rm -f $backup_dir/*.sql

이미 존재하는 백업 파일을 삭제합니다.

read pw

MySQL 비밀번호를 입력받습니다.

db_list=`mysql -uroot -p$pw -e "show databases" | tail -n+2`;

DB 목록을 받아옵니다.

for db_name in $db_list; do

DB 목록별로 작업합니다.

if [ "$db_name" != "information_schema" -a "$db_name" != "mysql" -a "$db_name" != "performance_schema" -a "$db_name" != "phpmyadmin" -a "$db_name" != "test" ]; then
  mysqldump -uroot -p$pw $db_name > $backup_dir/$db_name.sql
fi

백업이 필요 없는 DB를 제외하고 각 DB의 이름으로 백업합니다.

done

반복작업을 마칩니다.

반응형
반응형

출처 : http://minsql.com/mysql/mysql-5-6-gtid-replication-manadatory-options/

ref : http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-howto.html
에 따르면 간단히 다음과 같이 정리할 수 있습니다.


GTID(global transactio identifier)를 사용하기 위한 필수옵션은 다음 네가지입니다. Master, Slaves 모두 (적어도) 네가지 옵션이 주어져야합니다.
shell> mysqld_safe –gtid_mode=ON –log-bin –log-slave-updates –enforce-gtid-consistency &
–gtid-mode는 ON/OFF 값을 주어야합니다. 0/1 사용하지 마세요.

Options
Comments
–gtid_mode=ON

GTID 쓸꺼면 ON하면 됩니다. enumeration이라니 아마도 ON/OFF외에 다른 값도 받을수 있는듯. 살펴봅시다.
–log-bin
이것도 물론 켜야겠죠.
–log-slave-updates
이거 살짝 curious하네요. 지금까지는 chained replication 구성할때 사용했었는데요. 살펴봅시다.
–enforce-gtid-consistency
gtid 쓰면 unsafe 케이스가 있나봅니다. 살펴봅시다.


  1. gtid_mode=ON
    • Introduced5.6.5
      Command-Line Format--gtid-mode=MODE
      System Variable Namegtid_mode
      Variable ScopeGlobal
      Dynamic VariableNo
      Permitted Values
      Typeenumeration
      DefaultOFF
      Valid ValuesOFF
      UPGRADE_STEP_1
      UPGRADE_STEP_2
      ON
    • 물론 global 변수고, dynamic아니고, 네가지 값을 가질수 있네요.
    • ON/OFF할때 주의해야합니다. 실행중이던 트랜잭션이 남아있던 경우에 이 옵션이 켜지거나 꺼지면 문제가 될수 있다고 합니다.
    • Boolean아니니 0/1주면 안됩니다. UPGRADE_STEP_1 , UPGRADE_STEP_2 은 지금은 사용안되고 추후에 추가될 예정이라고합니다. 지금 버젼에서는 이 두개 쓰면 startup 실패합니다.
    • 버젼별 주의사항(gtid_mode=ON일때) 
      • MySQL 5.6.7 미만 : mysql_upgrade 사용안됨, mysql_upgrade하려면 –skip-write-binlog을 명시해야함.
      • MySQL 5.6.7 이후 : mysql_upgrade 실행가능하지만 MyISAM을 사용하는MySQL system tables에 영향이 있을 수 있으므로 사용하지 않는 것이 좋다. (–write-binlog가 default였는데 5.6.7이후부터 –skip-write-binlog가 default임)
      • MySQL 5.6.10 미만 : sql_slave_skip_couter=1 을 설정이 동작하지 않음. slave position을 넘기기 위해서는 CHANGE MASTER TO … MASTER_LOG_FILE = …, MASTER_LOG_POS = …, MASTER_AUTO_POSITION = 0 를 사용해야함.
  2. log-bin
    • Enable binary logging
  3. log-slave-updates
    • slave binlog에 master로 부터 받은 변경사항도 쓰도록 하는 옵션.
    • gtid-mode에서 log-slave-updates를 사용하지 않으면 다음과 같은 에러가 발생한다고 합니다.
    • Master와 Slave binlog에 같은 GTID가 기록되기 때문에 slave는 자신이 최근 적용한 GTID를 가지고 master의 position을 찾아갈수 있음. 즉, auto-positioning을 위해서는 –log-slave-updates가 반드시 활성화되어야함.
  4. enforce-gtid-consistency
    • Introduced5.6.9
      Command-Line Format--enforce-gtid-consistency[=value]
      System Variable Nameenforce_gtid_consistency
      Variable ScopeGlobal
      Dynamic VariableNo
      Permitted Values
      Typeboolean
      Defaultfalse
    • transsactionally safe한 문장만 실행을 허용한다.
    • GTID 모드를 사용하기 전에 이 옵션을 켜서 테스트해볼수 있습니다.
    • transactionally safe한 문장이 어떤걸까. unsafe하다는 걸 보면 알수 있을지도 모르겠네요.
    • 허용되지 않는 문장.
      • CREATE TABLE … SELECT statements
      • CREATE TEMPORARY TABLE statements inside transactions
      • Transactions or statements that update both transactional and nontransactional tables
    • 버젼별 주의사항(enforce-gtid-consistency)
      • MySQL 5.6.9 미만 : 옵션 이름이 –disable-gtid-unsafe-statements 이었음.
      • MySQL 5.6.7 미만 : 이 옵션을 사용하면 temporary tables에 대한  nontransactional DML문이 실패했었음. 심지어 row-based binary logging 사용 환경에서 temporary tables가 로깅될 필요가 없는 경우에도 에러를 발생했었음.
      • MySQL 5.6.7 이후: –disable-gtid-unsafe-statements ( MySQL 5.6.9 이후, –enforce-gtid-consistency) 을 사용하면 temporary tables에 대한  nontransactional DML문이 허용됨
      • MySQL 5.6.7 미만 : mysql_upgrade 사용안됨, mysql_upgrade하려면 –skip-write-binlog을 명시해야함.
      • MySQL 5.6.7 이후 : mysql_upgrade 실행가능하지만 MyISAM을 사용하는 MySQL system tables에 영향이 있을 수 있으므로 사용하지 않는 것이 좋다. (–write-binlog가 default였는데 5.6.7이후부터 –skip-write-binlog가 default임)
      • MySQL 5.6.9 미만 : –disable-gtid-unsafe-statements을 사용하면 nontransactional tables(MyISAM) 에 대한 변경이 불가능했음
      • MySQL 5.6.9 이후 : nontransactional tables(MyISAM) 에 대한 single statement는 가능함.


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

slave 데이터 불일치 시  (0) 2015.04.02
MySQL Database(DB)별로 백업하는 쉘 스크립트  (0) 2015.04.01
MySQL MHA(Master High Availability)  (0) 2015.03.24
mysqlbinlog  (0) 2015.03.24
percona-toolkit 설치  (0) 2015.03.19
반응형
  • 개요

    MHA는 MySQL Replication의 Master 서버가 Failover가 되었을 때, 짧은 Downtime(약 10~30초) 이내에 Slave를 Master로 승격시켜 Failover를 자동화하는 Tool이다. 이를 통해 복잡한 설치과정 없이 복제 일관성을 유지하고, 많은 비용을 들이지 않고 성능문제를 해결하며 구조를 변경할 필요가 없게 된다.

       

  • 주요 기능
    • 자동화된 Master 모니티렁 및 Failover
      • MySQL Replication의 Master 서버를 모니터링하고, Master 서버의 동작을 감시하여 자동으로 Failover를 수행한다
      • 비록 몇몇 Slave 서버가 최근의 Relay Log 이벤트를 받지 못하더라도, MHA는 가장 최근의 Slave서버와 비교해 Relay Log 차이점을 감지하고, 뒤쳐진 Relay Log를 가진 Slave에 이를 적용함으로써 데이터 일관성을 유지할 수 있다.
      • 설정 파일에 우선순위를 설정하여 특정 Slave를 Master 후보로 지정할 수 있다. MHA는 Slave간의 일관성 문제를 해결하기 때문에 특정 Slave를 Master로 승격시킨다 하더라도 일관성 문제에서 자유로울 수 있다
      • Master Failure 감지 시간 : 9~12초
        Split Brain을 피하기 위한 Master 장비 Power Off 시간(옵션) : 7~10초
        새로운 Master에 최신 Relay Log를 적용하는데 걸리는 시간 : 몇 초…
        총 Downtime 시간 : 10~30초
    • 대화형(수동) Master Failover
      • MHA를 모니터링 기능 없이 대화형 Failover용으로만 사용할 수 있다.
    • 비대화형 Master Failover
      • 모니터링은 사용하지 않고, 자동화된 Master Failover를 지원한다. MySQL Master 서버를 모니터링하는 SW를 이미 사용하고 있을 경우 유용하다.
    • 온라인 Master 서버 변경
      • Master 서버의 Failover용이 아닌 하드웨어 교체등으로 인해 Master 서버를 다른 Host로 변경하려 할 때 유용하다.
      • MHA는 0.5~2초 이내의 Writer Block 시간만으로 Master 서버를 변경할 수 있다. 0.5~2초 이내의 Downtime 시간이 허용된다면 이 툴을 이용해 좀 더 쉽게 높은 버전의 MySQL로 업그레이드 하거나 장비를 교체할 수 있다.

           

  • MHA 이점
    • Master Failover에 따른 Slave의 승격이 매우 빠르게 이루어진다
      • DeNA의 경우 150대 이상의 Master/Slave 환경에서 MHA를 사용하고 있다. Master에 장애가 났을 경우, 약 4초만에 Failover가 가능했다. 이는 전통적인 Active/Passive 클러스터링 솔루션에서는 불가능했다
    • Master의 Failover가 데이터 일관성에 영향을 미치지 않는다
      • Master 서버가 다운되어도 MHA는 자동으로 Slave 간의 Relay Log 이벤트의 차이를 감지하여 동기화한다.
      • Semi-Synchronous Replication을 함께 사용하면 데이터 손실이 일어나지 않게 할 수 있다
    • 구축되어 있는 MySQL 서버 세팅의 변경이 필요 없다
      • MHA는 이전의 MySQL 5.0 이상의 Replication 환경에서 MySQL 설정 변경 없이 동작 가능하다.
      • MHA 버전을 업그레이드 할 경우에도 MySQL 서버를 중단시킬 필요가 없다
      • MHA는 MySQL 5.0 이상(5.0 / 5.1 / 5.5 / 5.6)에서 동작하기 때문에 Migration 할 필요가 없다
    • 많은 서버를 증설할 필요가 없다
      • MHA는 MHA Manager와 MHA Node로 구성되어 있다
      • MHA Node는 MySQL 서버에서 동작하고, 관리를 위해 하나 이상(HA를 위해)의 MHA Manager 서버가 필요하다. 하나의 MHA Manager 서버는 많은 MySQL 서버를 모니터링 할 수 있기 때문에 추가적으로 많은 서버가 필요하지 않다
    • 성능에 대한 불이익이 없다
      • MHA는 Master 서버로 N초마다 Ping 패킷만을 전송하기 때문에 성능에 큰 무리가 없다
    • 모든 스토리지 엔진에서 동작한다

       

  • MHA 아키텍처
    • MHA Toolkit

      • Manager
        • Master_monitor : Master 서버 장애 감지
        • Master_switch : Failover 수행(Masterha_manager를 불러와 자동/수동으로 Failover 수행)
      • Node : 모든 MySQL 서버에 배치한다
        • Save_binary_logs : 접근이 가능하다면, Master 서버의 바이너리 로그를 복사
        • Apply_diff_relay_logs : 가장 최근 정보를 가진 Slave 서버로 부터 Relay Log의 차이를 생성하고, 모든 binlog 이벤트와 다른점을 적용한다
        • Filter_mysqlbinlog : 불필요한 ROLLBACK 이벤트를 잘라낸다
        • Purge_relay_logs : SQL Thread 중단 없이 Relay Log를 삭제
    • 데이터 센터의 경우

      • 각 Manager는 같은 데이터센터 내의 많은 Master 서버를 모니터링 한다
      • DC1의 Manager가 DC2, DC3의 Master와 연결되어 있을 경우, 만약 한 Master 서버가 어떠한 Manager로 연결할 수 없을 때, Master Failover 프로시저가 시작한다.
        (Split Brain을 방지하기 위함)
      • 만약 데이터센터가 붕괴되는 등의 큰 장애가 발생하면, 수동으로 Failover를 수행해야 한다
    • 복구 프로시저

    • 복구 단계

      • Slave(i)에서 먼저 SQL Thread가 이벤트를 실행할 때까지 기다린 후, (i1) -> (i2) -> (x) 순으로 적용한다. (단, 가장 최근 정보를 가진 Slave의 경우 (i2)과정 생략)

         

  • (i1) 복구 단계
    • 부분적 트랜잭션

      • 동작중인 Slave 서버의 IO Thread는 유효한 Relay Log 이벤트를 기록한다. 그래서 유효하지 않은(읽을 수 없는) 이벤트는 Relay Log로부터 읽을 수 없다.
      • 그러나 바이너리 로그를 전송하는 도중에 Master 서버에 장애가 발생할 경우, 일부 이벤트만 보내진 후, Slave에서 읽어질 수도 있다
      • 이러한 경우 Slave는 잘려진 마지막 트랜잭션을 실행하지 않는다
      • "Master_Log_File, Read_Master_Log_Pos"는 Relay Log의 마지막 부분을 가리키지만 "Relay_Master_Log_File, Exec_Master_Log_Pos"는 마지막으로 Commit된 트랜잭션을 가리키기 때문이다
    • 누락된 트랜잭션

      • 때때로(예를 들어 매우 긴 트랜잭션이 실행되었을 때) Relay Log는 트랜잭션이 Commit이 되지 않은 상태로 끝나버릴 때가 있다
      • "Read_Master_Log_Pos"는 항상 Relay Log의 맨 마지막 "end_log_pos"를 가리킨다
      • "Exec_Master_Log_Pos"는 트랜잭션의 "end_log_pos"의 맨 마지막(COMMIT 된 부분)을 가리킨다
      • 위의 예제에선 Exec_Master_Log_Pos != Read_Master_Log_Pos 이다. 따라서 Slave1의 SQL Thread는 "BEGIN 과 UPDATE문"을 실행하지 않을 것이다.
      • 적용되지 않은 이벤트는 "mysqlbinlog --start-position=91835" 명령어를 통해 적용할 수 있다.
    • 누락된 트랜잭션 복구

      • Slave1에서 "update 2….." 이벤트는 누락되었다. 또한 Slave1의 SQL Thread는 "update 1….." 이벤트를 실행하지 않는다
      • 동일한 트랜잭션 내에서 (A) + (B)가 Slave 1에서 적용되어야 한다

           

  • (i2) 복구 단계
    • 가장 최신의 Slave 서버 구분

      • 가장 최신의 Slave를 구분하는데 있어 Relay Log 이름/위치는 각 Slave 서버마다 독립적이기 때문에 그다지 도움이 되지 않는다.
      • "Master_Log_File, Read_Master_Log_Pos"를 비교함으로써 가장 최신의 Slave 서버를 찾을 수 있다. (여기선 Slave2가 가장 최신 정보를 갖고 있다)
      • 모든 Slave 서버의 Master Position을 알고 있으며 비교할 수 있기 때문에 Relay Log 이벤트의 차이점을 생성하는 것은 가능하다.
    • Relay Log 보는 방법

    • Slave 서버간 Relay Log 이벤트 차이점 파악        

      • 현재 Slave2는 Slave3보다 더 많은 binlog 이벤트를 받았다
      • Binlog 이벤트 수신에 뒤쳐진 Slave 서버의 "end_log_pos"를 체크한다
        (위의 Slave3의 end_log_pos는 '101719'이다)
      • 가장 최근의 Slave 서버(Slave2)의 Relay Log에서 "end_log_pos=101719'를 찾는다
      • 이를 통해 Slave3에서 누락된 Relay Log Position이 '101835'부터 임을 알 수 있다
      • Slave3에서 "mysqlbinlog --start-position=101835"를 수행하여 데이터를 동기화한다

           

  • (x) 복구 단계
    • 장애가 발생한 Master 서버에서 Binlog 이벤트 저장

      • 장애가 발생한 Master에 SSH 등을 통해 접속할 수 있고, 바이너리 로그에 접근할 수 있다면, binlog 이벤트를 저장할 수 있다
      • 잃어버린 이벤트는 가장 최신의 Slave 서버에서의 "show slave status" 명령어와 mysqlbinlog를 체크하여 알 수 있다. (Master_Log_File, Read_Master_Log_Pos)

      • Semi-Synchronous 복제를 사용하면 이벤트 손실에 대한 위험을 줄일 수 있다

           

  • MHA 0.56 특징
    • MySQL 5.6에 포함된 GTID를 지원한다. GTID와 Auto Position이 활성화되면 MHA는 이전의 Relay Log 기반 Failover가 아닌 GTID SQL Syntax를 이용해 Failover를 자동적으로 수행한다. GTID 기반 Failover를 사용함으로써 더 이상 설정 충돌이 일어나지 않을 것이다.
    • MySQL 5.6 멀티 쓰레드 Slave 지원
    • MySQL 5.6 바이너리 로그 체크섬 지원
    • [binlogN] 이란 새로운 섹션이 생겨 "mysqlbinlog streaming servers"를 지정할 수 있다. 
      MHA가 GTID 기반 Failover를 수행할 경우, MHA는 binlog 서버를 체크하고, 만약 binlog 서버가 다른 Slave 서버보다 앞선다면, MHA는 복구하기 전에 새로운 Master 서버에게 binlog 서버로부터 가져온 binlog 이벤트를 적용한다.
      MHA가 Relay Log 기반 Failover를 수행할 경우엔 binlog 서버를 무시한다. 자세한 사항은 공식 Documetation을 확인하라.
    • Custom mysql과 mysqlbinlog Location 지원
    • Master의 연결을 체크하기 위해 "ping_type=INSERT"가 추가되었다. 만약 디스크 에러 등으로 인해 Master 서버에서 쓰기를 수행할 수 없을 경우 유용하다.
    • Master_ip_online_change_script를 위해 "--orig_master_is_new_slave, --orig_master_ssh_user, --new_master_ssh_user"가 추가되었다
    • "--skip_change_master,  --skip_disable_read_only, --wait_until_gtid_in_sync on masterha_manager and masterha_master_switch (failover mode)" 가 추가되었다

       

  • 제약사항
    • 3-Tier 이상의 Replication은 지원하지 않는다. ( ex> Master -> Master2 -> Slave)
    • SBR기반 "LOAD DATA [LOCAL] INFILE"은 지원하지 않는다
    • 모든 MySQL 서버에서 복제 필터링 룰(binlog-do-db, replicate-ignore-db 등)은 동일해야 한다
    • MySQL 5.0.45 이하 버전에선 동작하지 않는다

       

  • 설정 및 Command
    • 설정 파일
    • 주요 Command
      • Masterha_manager : Master 서버를 모니터링 하고, 다운되었을 경우 자동으로 Failover 수행
      • Masterha_master_switch :
      • Masterha_check_status : Manager가 MySQL Master 서버를 제대로 모니터링 하는지 검사
      • Masterha_check_repl : 설정 파일에 정의된 MySQL 서버들의 복제 상태를 체크
      • Masterha_stop : MHA Manager를 중지
      • Masterha_conf_host : 설정 파일에 Host 추가/삭제를 도와주는 Script
      • Masterha_ssh_check : SSH 설정을 체크
      • Purge_relay_logs : Replication Delay를 발생시키지 않으면서 오래된 Relay Log를 삭제

       

  • 테스트
    • 기존 Master 서버에 장애가 났을 때, Slave 서버의 상태

    • 장애가 발생하기 전에 Masterha_manager를 실행시켰고, 다음과 같이 Failover가 진행된다

    • 로그 파일 내 Failover Report ==> Master(192.168.0.20)가 Failover 되어 새로운 Master(192.168.0.30)로 Master 서버를 변경한 것을 알 수 있다

    • MHA에 의해 Failover가 된 후의 Slave 서버 ==> Master_Host가 192.168.0.20에서 192.168.0.30으로 변경되었다

    •    

  • 정리

       

  • 파일 다운로드
    • MHA4-MySQL-Manager-0.56.tar.gz

      <<mha4mysql-manager-0.56.tar.gz>>

    • MHA4-MySQL-Node-0.56.tar.gz

      <<mha4mysql-node-0.56.tar.gz>>

         

  • 참고


[출처] MySQL MHA(Master High Availability)|작성자 현토
http://blog.naver.com/eqelizer/20208801379


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

MySQL Database(DB)별로 백업하는 쉘 스크립트  (0) 2015.04.01
MySQL 5.6 gtid replication manadatory options  (0) 2015.03.27
mysqlbinlog  (0) 2015.03.24
percona-toolkit 설치  (0) 2015.03.19
Seconds_Behind_Master  (0) 2015.03.18
반응형

--read-from-remote-server

mysqlbinlog 유틸리티가 원격 서버의 바이너리 로그를 백업하도록 하는 핵심 옵션. 이 옵션이 명시되지 않으면

mysqlbinlog는 예전과 같이 로컬 디스크에 있는 바이너리 로그를 찾아서 텍스트 파일로 변환하는 작업만 수행할 것이다.

mysqlbinlog 유틸리티가 --read-from-remote-server 옵션과 함께 실행될 때에는 반드시 원격 서버에 접속할 때

필요한 정보인 --host와 --user 그리고 --password와 --port 옵션이 함께 사용되어야 한다.


--raw

이 옵션이 사용되면 mysqlbinlog 유틸리티는 가져온 이진 형태의 바이너리 로그를 그대로 디스크로 기록한다.

만약 이 옵션이 없으면 mysqlbinlog 유틸리티는 텍스트 형태로 변환된 바이너리 로그를 생성할 것이다.


--stop-never

mysqlbinlog 유틸리티를 사용해서 원격 서버에서 지정된 몇 개의 바이너리 로그만 가져올 수 있고 지정된 바이너리 로그 파일부터

멈추지 않고 계속 생성되는 바이너리 로그 파일을 로컬 디스크로 저장하도록 할 수도 있다. --stop-never 옵션이 사용되면

mysqlbinlog 유틸리티는 원격 서버가 종료되거나 커넥션이 끊어지지 않는 한 멈추지 않고 계속 원격 서버의 바이너리 로그를 복사한다.


--stop-never-slave-server-id=id

--stop-never 옵션이 사용되면 mysqlbinlog 유틸리티는 하나의 슬레이브처럼 작동한다. MySQL 복제에서 항상 모든 서버는 고유한

server-id를 가져야 한다. 이때 mysqlbinlog가 어떤 server-id를 사용할지를 지정해주는 옵션이다. 

특별히 명시되지 않으면 최댓값인 65535로 초기화된다.


--result-file

원격서버로부터 가져온 바이너리 로그 파일을 저장한 파일 명의 접두어(Prefix)를 설정한다. 예를 들어서 원격 서버의 바이너리 로그

파일이 mysql-bin.000002이고 --result-file 옵션이 "/backup/copied-"로 설정되어 있다면 mysqlbinlog는 백업해온 바이너리 로그를

"/backup/copied-mysql-bin.000002"라는 파일명으로 저장할 것이다. 만약 파일명을 원격 서버와 동일하게 유지하려면

--result-file 옵션에 "/backup/"과 같이 디렉터리명만 설정해주면 된다. 디렉터리인 경우에는 반드시 마지막에 디렉터리 구분자인 "/"를

포함하도록 하자.


--to-last-log

이 옵션이 mysqlbinlog와 함께 사용되면 mysqlbinlog는 지정된 바이너리 로그 파일뿐만 아니라 그 이후에 발생한 모든 바이너리 로그를

가져오게 된다. 만약 몇 개의 바이너리 로그 파일만 지정해서 그 파일만 백업하려면 이 옵션이 명시되면 안 된다.

그리고 --stop-never 옵션이 사용되면 자동으로 --to-last-log 옵션도 활성화된다.


#!/bin/sh


BACKUP_BIN=/mysql5.6/bin/mysqlbinlog

LOCAL_BACKUP_DIR=/backup/binlog


REMOTE_HOST=192.168.0.1

REMOTE_PORT=3306

REMOTE_USER=replication_user

REMOTE_PASS=replication_pass


# time to wait before reconnecting after failure

SLEEP_SECONDS=10


## 필요 시 디렉터리 생성

mkdir -p ${LOCAL_BACKUP_DIR}

cd ${LOCAL_BACKUP_DIR}


## while 루프를 돌면서 커넥션이 끊어지면 일정 시간 대기 후 재접속하도록 구현

WHILE :

DO

    LAST_FILE='ls -1 ${LOCAL_BACKUP_DIR} | grep -v orig | tail -n 1'

    TIMESTAMP='date + %s'

    FILE_SIZE=$(stat -c%s "$LAST_FILE")


    IF [ ${FILE_SIZE} -gt 0 ]; THEN

        echo "완성되지 않은 백업 파일을 리네임합니다."

        mv ${LAST_FILE} ${LAST_FILE}.orig_${TIMESTAMP}

    FI


    touch ${LAST_FILE}

    echo "${LAST_FILE} 바이너리 로그 파일부터 백업 재개합니다."

    ${BACKUP_BIN} --raw --read-from-remote-server --stop-never --host ${REMOTE_HOST} \

        --port ${REMOTE_PORT} --user ${REMOTE_USER} --password ${REMOTE_PASS} ${LAST_FILE}


    echo ">> mysqlbinlog 가 종료되었습니다. 리턴 코드 : $?"

    echo ">> ${SLEEP_SECONDS} 초 이후에 다시 재접속 및 백업 재개합니다."

    sleep ${SLEEP_SECONDS}

DONE


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

MySQL 5.6 gtid replication manadatory options  (0) 2015.03.27
MySQL MHA(Master High Availability)  (0) 2015.03.24
percona-toolkit 설치  (0) 2015.03.19
Seconds_Behind_Master  (0) 2015.03.18
MHA  (0) 2015.03.18
반응형
1
2
3
4
5
6
$ wget http://www.percona.com/get/percona-toolkit.tar.gz
$ tar -zxvf percona-toolkit-2.1.3.tar.gz
$ cd percona-toolkit-2.1.3
$ perl Makefile.PL
$ make
$ make install


출처 : http://www.wolflabs.org/2012/08/20/installing-percona-toolkit-on-centos-6-3-x86_64/

반응형

'연구개발 > MYSQL' 카테고리의 다른 글

MySQL MHA(Master High Availability)  (0) 2015.03.24
mysqlbinlog  (0) 2015.03.24
Seconds_Behind_Master  (0) 2015.03.18
MHA  (0) 2015.03.18
MMM (MySQL Multi-Master Manager) INSTALLATION  (0) 2015.03.14
반응형

watch -n 1 "mysql --login-path=dbmon -e 'show slave status\G' | grep 'Seconds_Behind_Master' | awk -F':' '{print \$2}'"

반응형

'연구개발 > MYSQL' 카테고리의 다른 글

mysqlbinlog  (0) 2015.03.24
percona-toolkit 설치  (0) 2015.03.19
MHA  (0) 2015.03.18
MMM (MySQL Multi-Master Manager) INSTALLATION  (0) 2015.03.14
MySQL INNODB Status Monitoring  (0) 2015.03.14
반응형

http://www.arborisoft.com/how-to-configure-mysql-masterslave-replication-with-mha-automatic-failover/



MySQL MHA 설치하기.docx


반응형

'연구개발 > MYSQL' 카테고리의 다른 글

percona-toolkit 설치  (0) 2015.03.19
Seconds_Behind_Master  (0) 2015.03.18
MMM (MySQL Multi-Master Manager) INSTALLATION  (0) 2015.03.14
MySQL INNODB Status Monitoring  (0) 2015.03.14
show status를 통한 MySQL 상태 분석하기  (0) 2015.03.13
반응형
l MMM (MySQL Multi-Master Manager) INSTALLATION

<Server Allocation>
Name
IP
Host Name
Server ID
Monitor
10.1.1.111
mon
-
Master 1
10.1.1.121
db1
1
Master 2
10.1.1.131
db2
2

<Virtual IPs Allocation>
IP
ROLE
DB Work Grantee
10.1.1.211
writer
write only
10.1.1.221
reader
read only
10.1.1.231
reader
read only


<Install MMM>
## Dual-Repl. MySQL 구성 및 초기 설치과정은 기존 참고자료들을 참고하도록 생략.

## MySQL Server Configuration File Parameter Value 추가 (MySQL node both)
-      /etc/my.cnf

. . .

# Setting For Replication  (db1)
binlog_cache_size=4M
max_binlog_size=512M
expire_logs_days = 2
relay-log-purge = 1
log_slave_updates = 1
skip-slave-start
auto_increment_increment = 2
auto_increment_offset = 1      # Set Unique Value to Both Server
bind-address = 0.0.0.0
. . .


. . .

# Setting For Replication (db2)
binlog_cache_size=4M
max_binlog_size=512M
expire_logs_days = 2
relay-log-purge = 1
log_slave_updates = 1
skip-slave-start
auto_increment_increment = 2
auto_increment_offset = 2      # Set Unique Value to Both Server
bind-address = 0.0.0.0
. . .


## MySQL Dual-Repl. 구성 설치 후 MMM설치를 위한 추가적인 GRANTEE작업
MySQL >
GRANT SUPER, REPLICATION SLAVE, REPLICATION CLIENT, PROCESS ON *.* TO replusr@'10.1.1.%' IDENTIFIED BY ‘replusr!@#$’;


## MMM 설치를 위한 필요 패키지 설치
yum install make libart_lgpl.x86_64   perl-Algorithm-Diff   perl-DBD-mysql   perl-DateManip  perl-IPC-Shareable  perl-Log-Dispatch  perl-Log-Dispatch-FileRotate  perl-Log-Log4perl  perl-MIME-Lite  perl-Mail-Sender  perl-MailTools  perl-Net-ARP  perl-Params-Validate  perl-Proc-Daemon  perl-TimeDate  perl-XML-DOM  perl-XML-Parser  perl-XML-RegExp  rrdtool  rrdtool-perl  perl-Class-Singleton

## 모니터링 노드의 경우 mysql library 환경 추가 설치 (DB 노드는 이미 설치되어 있음)
rpm -ivh MySQL-shared-compat-5.5.30-1.rhel5.x86_64.rpm  (monitor node)

## MMM 패키지 설치
wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz

tar -zxvf :mmm2:mysql-mmm-2.2.1.tar.gz && rm -fr :mmm2:mysql-mmm-2.2.1.tar.gz

cd mysql-mmm-2.2.1

make install


mkdir -p  /usr/lib/perl5/vendor_perl/5.8.8/MMM /usr/lib/mysql-mmm /usr/sbin /var/log/mysql-mmm /etc /etc/mysql-mmm /etc/init.d/
cp -r lib/Common/ /usr/lib/perl5/vendor_perl/5.8.8/MMM
[ -f /etc/mysql-mmm/mmm_common.conf ] || cp etc/mysql-mmm/mmm_common.conf /etc/mysql-mmm/
mkdir -p /usr/lib/mysql-mmm/agent/
cp -r lib/Agent/ /usr/lib/perl5/vendor_perl/5.8.8/MMM
cp -r bin/agent/* /usr/lib/mysql-mmm/agent/
cp -r etc/init.d/mysql-mmm-agent /etc/init.d/
cp sbin/mmm_agentd /usr/sbin
[ -f /etc/mysql-mmm/mmm_agent.conf  ] || cp etc/mysql-mmm/mmm_agent.conf  /etc/mysql-mmm/
mkdir -p /usr/lib/mysql-mmm/monitor/
cp -r lib/Monitor/ /usr/lib/perl5/vendor_perl/5.8.8/MMM
cp -r bin/monitor/* /usr/lib/mysql-mmm/monitor/
cp -r etc/init.d/mysql-mmm-monitor /etc/init.d/
cp sbin/mmm_control sbin/mmm_mond /usr/sbin
[ -f /etc/mysql-mmm/mmm_mon.conf    ] || cp etc/mysql-mmm/mmm_mon.conf    /etc/mysql-mmm/
mkdir -p /usr/lib/mysql-mmm/tools/
cp -r lib/Tools/ /usr/lib/perl5/vendor_perl/5.8.8/MMM
cp -r bin/tools/* /usr/lib/mysql-mmm/tools/
cp sbin/mmm_backup sbin/mmm_clone sbin/mmm_restore /usr/sbin
[ -f /etc/mysql-mmm/mmm_tools.conf  ] || cp etc/mysql-mmm/mmm_tools.conf  /etc/mysql-mmm/




















echo $?
0



< Configuration File Setting >

# vi /etc/mysql-mmm/mm_common.conf (both all node)  
   (주석내용은 config 작성시 반드시 제거할 것!!!)

active_master_role      writer

<host default>
cluster_interface                eth1              ## Ethernet Interface
pid_path                         /var/run/mmm_agentd.pid
bin_path                         /usr/lib/mysql-mmm/
replication_user                 replusr
replication_password           5emffld)
agent_user                      replusr
agent_password                5emffld)
</host>

<host db1>
ip                                 10.1.1.121   ## MySQL Master 1 node real ip
mode                            master
peer                              db2
</host>

<host db2>
ip                                 10.1.1.131   ## MySQL Master 2 node real ip
mode                            master
peer                              db1
</host>

<role writer>
hosts                             db1, db2
ips                                10.1.1.211    ## Monitor node virtual ip
mode                             exclusive
</role>

<role reader>
hosts                             db1, db2
ips                                10.1.1.221, 10.1.1.231    ## MySQL Master nodes virtual ip
mode                             balanced
</role>


# vi /etc/mysql-mmm/mmm_agent.conf (mysql node both)

include mmm_common.conf
this db1     ## When node is second master then input db2


include mmm_common.conf
this db2     ## When node is second master then input db2


# vi /etc/mysql-mmm/mmm_mon.conf (monitor node)

include mmm_common.conf
<monitor>
ip                                        127.0.0.1
pid_path                                /var/run/mmm_mond.pid
bin_path                                /usr/lib/mysql-mmm/
status_path                             /var/lib/misc/mmm_mond.status
ping_ips                                10.1.1.121, 10.1.1.131
</monitor>

<host default>
monitor_user                       replusr
monitor_password                ‘replusr!@#$’
</host>

debug 0


<Starting MMM>

- Start the agents (mysql node both) –

chkconfig mysql-mmm-agent on

/etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok


- Start the monitor (monitor node) -

/etc/init.d/mysql-mmm-monitor start
Daemon bin: '/usr/sbin/mmm_mond'
Daemon pid: '/var/run/mmm_mond.pid'
Starting MMM Monitor daemon: Ok


- mmm_control to check the status of the cluster –


mmm_control show
db1(10.168.1.121) master/AWAITING_RECOVERY. Roles:
db2(10.168.1.131) master/AWAITING_RECOVERY. Roles:

mmm_control checks all
db2  ping         [last change: db22013/06/13 15:39:09]  OK
db2  mysql        [last change: db22013/06/13 15:39:09]  OK
db2  rep_threads  [last change: db22013/06/13 15:39:09]  OK
db2  rep_backlog  [last change: db22013/06/13 15:39:09]  OK: Backlog is null
db1  ping         [last change: db22013/06/13 15:39:09]  OK
db1  mysql        [last change: db22013/06/13 15:39:09]  OK
db1  rep_threads  [last change: db22013/06/13 15:39:09]  OK
db1  rep_backlog  [last change: db22013/06/13 15:39:09]  OK: Backlog is null

tail -f /var/log/mysql-mmm/mmm_mond.log
상세 로그내역은 직접 확인.

mmm_control set_online db1
OK: State of 'db1' changed to ONLINE. Now you can wait some time and check its new roles!

mmm_control set_online db2
OK: State of 'db2' changed to ONLINE. Now you can wait some time and check its new roles!

$ mmm_control show
db1(10.168.1.121) master/ONLINE. Roles: reader(10.168.1.231), writer(10.168.1.211)
db2(10.168.1.131) master/ONLINE. Roles: reader(10.168.1.221)



출처 : http://dba-jadelee.blogspot.kr/2014/10/mmm-mysql-multi-master-manager.html

반응형

'연구개발 > MYSQL' 카테고리의 다른 글

Seconds_Behind_Master  (0) 2015.03.18
MHA  (0) 2015.03.18
MySQL INNODB Status Monitoring  (0) 2015.03.14
show status를 통한 MySQL 상태 분석하기  (0) 2015.03.13
tmux - 여러개의 터미널을 실행할 수 있는 TTY 멀티플렉서  (0) 2015.03.09
반응형
-  해당 STATUS출력내역은 각 상세내역 설명을 위해 특정장비를 기준으로 특정시점의 결과를 샘플링  

- 세부적으로 설명한 부분도 있지만 직관적으로 상태정보를 보여주는 부분은 상세한 설명은 생략함. (이 부분들에 대한 추가적인 질문은 개인별로 문의하세요)

- 각 부분에 대한 간략한 기능적 설명이며 모니터링상 중요한 영역에 대한 코멘터리는 각 영역에 대한 설명 마지막 부분에 기재하였음.

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


SQL> SHOW ENGINE INNODB STATUS\G


=====================================
131129 12:58:12 INNODB MONITOR OUTPUT      <--- 분석시점에 대한 출력시간
=====================================
Per second averages calculated from the last 30 seconds   <--- 분석에 대한 대상시간범위 (출력시간으로부터 *초 전까지의 범위)


----------------------------
BACKGROUND THREAD      
----------------------------               
InnoDB 메인 백그라운드 스레드의 작업실행 통계 : 각 숫자는 Innodb Engine이 시작된 이후부터의 카운트 값

srv_master_thread loops: 18613866 1_second, 18613864 sleeps, 1861347 10_second, 1755 background, 1739 flush
<--- 순서대로 초당 루프횟수 / 초당 슬립횟수 / 10초당 루프횟수 / User Transaction이 없는 유휴시간대 백그라운드 연산의 루프횟수, 플러시 루프횟수를 의미

srv_master_thread log flush and writes: 18683584
<--- 로그 메시지를 기록하고 플러시한 횟수를 의미 (Redo + Undo)


-----------------
SEMAPHORES              
-----------------          
InnoDB 내부 세마포어(뮤텍스나 리드/라이트 락 세마포어를 기다리는 스레드에 대한 정보)  통계 : 각 숫자는 Innodb Engine이 시작된 이후부터의 카운트 값이며 각 카운트 값이 갑자기 높은 시간대에 대해서는 DISK I/O 성능 및 InnoDB 엔진경합을 의심

OS WAIT ARRAY INFO: reservation count 1206724952, signal count 3304987791
<--- 전역 대기 배열정보 : 배열이 생성된 후에 셀을 예약한 횟수 / 객체가 시그널을 받은 횟수를 의미

Mutex spin waits 39567225498, rounds 173270862365, OS waits 330572230
<--- 뮤텍스 대기 스핀정보 : 뮤텍스를 기다리는 스핀락의 호출횟수 / 스핀루프의 반복횟수 / OS의 호출을 기다린 횟수를 의미

RW-shared spins 2945944901, rounds 37722913141, OS waits 601963335
<--- 공유 리드락 스핀정보 : 공유 리드락이 걸린 시간동안 스핀락이 기다린 횟수 / 스핀루프의 반복횟수 / OS의 호출을 기다린 횟수를 의미                       

RW-excl spins 684786004, rounds 12265810889, OS waits 163680647
<--- 배타적 라이트락 스핀정보 : 배타적 라이트락이 걸린 시간동안 스핀락이 기다린 횟수 / 스핀루프의 반복횟수 / OS의 호출을 기다린 횟수를 의미

Spin rounds per wait: 4.38 mutex, 12.81 RW-shared, 17.91 RW-excl
<--- 각 뮤텍스에 대해 OS의 호출을 기다리며 스핀루프가 기다린 횟수를 의미


------------------------------------
LATEST FOREIGN KEY ERROR 
------------------------------------            
최근 발생한 트랜잭션별 참조키 에러내역 히스토리 : 제약조건에 위배되는 내역에 대한 트랜잭션 및 쿼리 정보 확인

세부 에러 내역은 생략


------------------------------------
LATEST DETECTED DEADLOCK
------------------------------------           
최근 발생한 트랜잭션별 데드락내역 히스토리 : 가장 최근 발생한 트랜잭션간 데드락 이슈에 대한 처리내역 확인 (경합된 트랜잭션간의 내역 및 데드락 해결을 위한 트랜잭션 처리내역)

세부 데드락 내역은 생략


-------------------
TRANSACTIONS  
-------------------           
현재 트랜잭션별 락모니터링 정보 : 실제 수행되고 있는 트랜잭션별 작업내역에 대한 락 핸들링 정보 및 락 사용 세부쿼리 내역을 확인

세부 트랜잭션 내역은 생략


----------
FILE I/O    
----------         
다양한 I/O 연산에 대한 Innodb 스레드 실행내역 및 통계 : 내부적인 I/O 스레드의 현재 상태 및 전체 통계값 제공하며 만약 I/O상의 부하나 상태이상이 의심될 때 참조될 수 있음.

I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
---> 현재 Innodb엔진이 사용중인 I/O 스레드들의 현재 상태 (각 스레드의 역할에 대한 명칭은 각 줄 끝 괄호내역 확인)

Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
---> 대기하는 연산에 대한 정보  (aio 는 비동기 입출력을 의미)

21113936456 OS file reads, 7012874230 OS file writes, 5248276317 OS fsyncs
---> Innodb 엔진이 시작된 이후 전체통계 카운트

670.33 reads/s, 16384 avg bytes/read, 387.61 writes/s, 196.80 fsyncs/s
---> 마지막으로 통계를 출력한 이후의 전체통계 값에 대한 초단위 처리 카운트


------------------------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX      
------------------------------------------------------        
인서트 버퍼와 적응형 해시에 대한 정보 : 버퍼와 해시의 효율에 대한 통계정보 확인

Ibuf: size 38747, free list len 48247, seg size 86995, 183927359 merges
---> 페이지에 있는 삽입버퍼의 인덱스트리 사이즈 / 사용가능한 프리리스트의 길이 / 삽입버퍼트리와 헤더를 갖고 있는 파일에 할당된 페이지수 / 합병된 페이지수 를 의미

merged operations:
 insert 1037160756, delete mark 902047899, delete 260585507
---> 인덱스 페이지에 합병한 각 DML연산의 횟수를 의미

discarded operations:
 insert 110253, delete mark 5399, delete 2043
---> 테이블스페이스나 인덱스가 삭제되어 합병하지 않고 버려진 각 DML연산의 횟수를 의미

Hash table size 4425293, node heap has 1037 buffer(s)
---> 적응형 해시 인덱스 테이블에 있는 셀의 개수와 예약된 버퍼프레임의 개수를 의미

1057.94 hash searches/s, 1352.65 non-hash searches/s
---> 검색한 적응형 해시 인덱스 검색에 성공한 횟수 / 적응형 해시 인덱스를 사용할 수 없을때 B-tree 인덱스를 검색한 횟수를 의미


-------
LOG
-------
Innodb Log 활동에 대한 통계

Log sequence number 7804454235313     
---> 현재 로그 일련번호 (lsn)

Log flushed up to   7804454234099
---> 로그파일에서 플러시된 항목의 개수

Last checkpoint at  7804369829116
---> 가장 최근의 체크포인트된 lsn 정보

0 pending log writes, 0 pending chkp writes
4882215617 log i/o's done, 153.85 log i/o's/second

log switch 이슈와 관련
VIEW POINT : (Log flushed up to - Last checkpoint at) 값은 체크포인트가 얼마나 오래되었는지를 확인할 수 있음.
체크 포인트값이 (innodb_log_file_size * innodb_log_files_in_group) 77% 이상이 되지 않게 모니터링하고 유지되어야 함. (권장된 모니터링수치)
만약 이 비율에 가깝거나 큰 비율 값이 나온다면 Innodb엔진은 공격적으로 플러싱을 시도하게 되며 이로 인한 DB연산이 멈출 수 있음.


------------------------------------
BUFFER POOL AND MEMORY
------------------------------------            
Innodb 버퍼풀과 메모리 사용량에 대한 통계정보 : Innodb 버퍼에 대한 LRU 관리방법에 의한 할당내역 및 사용내역(byte단위)  버퍼사용율에 대한 세부통계수치 확인

Total memory allocated 2197815296; in additional pool allocated 0
---> 버퍼로 할당된 메모리 전체사이즈 / 추가풀에 할당된 메모리사이즈를 의미

Dictionary memory allocated 8409400
---> 데이터딕셔너리 테이블과 인덱스에 할당된 메모리사이즈를 의미

Buffer pool size   131072
Free buffers       21
---> 버퍼풀 사이즈를 페이지 단위로 알려주고 / 버퍼풀에 있는 해재된(free) 버퍼의 개수를 의미 : 프리버퍼가 없는 경우가 잦으면 버퍼사이즈를 늘려주는 것을 권장.

Database pages     130014
Old database pages 47973
Modified db pages  5660
---> 버퍼의 현재 LRU큐의 길이 / 과거 LRU큐의 길이 / 플러시해야할 페이지의 개수를 의미 : 기본적으로 Innodb는 버퍼풀을 LRU로 관리하며 할당과 해제에 대해서 페이지단위로 관리됨.

Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
---> 대기하고 있는 읽기연산의 개수 / LRU 관리방식에 따른 플러시하기 위해 대기하고 있는 페이지의 개수 / Buf_flush_list에서 플러시하기위해 기다리고 있는 페이지의 개수 / Buf_flush_single_page 리스트에서 플러시하기 위해 기다리고 있는 페이지의 개수를 의미

Pages made young 47722254403, not young 0
3258.74 youngs/s, 0.00 non-youngs/s
---> 최근에 접근한 페이지의 개수 / 최근에 접근하지 않은 페이지의 개수를 의미

Pages read 25295158134, created 95903681, written 2392506665
670.33 reads/s, 2.00 creates/s, 235.76 writes/s
---> 페이지의 읽기 연산 카운트 / 버퍼풀에 생성했지만 읽지않은 페이지의 개수 / 쓰기 연산 카운트를 의미

Buffer pool hit rate 997 / 1000, young-making rate 19 / 1000 not 0 / 1000
---> 획득한 버퍼풀 페이지 수와 비교하여 읽은 페이지 수의 비율 / 획득한 버퍼풀 페이지 수와 비교 및 접근한 페이지 수의 비율 / 획득한 버퍼풀 페이지 수와 비교 및 접근하지 않은 페이지 수의 비율을 의미

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
---> 미리 읽기 비율 / 접근하지 않아서 제거된 미리 읽기 페이지수의 비율 / 랜덤 미리 읽기 비율

LRU len: 130014, unzip_LRU len: 0
I/O sum[108645]:cur[907], unzip sum[0]:cur[0]


----------------------
ROW OPERATIONS
----------------------
메인 스레드의 행 연산에 대한 통계 정보

2 queries inside InnoDB, 0 queries in queue
5 read views open inside InnoDB
---> 현재 실행중인 쿼리 / innodb_thread_concurrency 큐에 있는 쿼리의 개수 / 읽은 뷰의 개수를 의미

Main thread process no. 16530, id 140226923562752, state: sleeping
---> 메인 스레드의 ID 및 상태정보를 의미 (첫번째 no. OS의 프로세스ID)

Number of rows inserted 3941662945, updated 2611269253, deleted 1052306048, read 11030869627676
39.96 inserts/s, 57.94 updates/s, 2.00 deletes/s, 908015.98 reads/s
---> innodb 엔진 시작된 이후의 각 DML연산의 총합계 카운트 / 초당 각 DML연산의 횟수 카운트를 의미

--------------------------------------------------------
END OF INNODB MONITOR OUTPUT
========================================================


출처 : http://dba-jadelee.blogspot.kr/2014/10/mysql-innodb-status-monitoring.html


반응형
반응형
1. 현재 DB상태 분석을 위한 사전정보들 및 권장사항

mysql 실행 이후 다음의 기본적인 사항을 염두에 두고 내용을 사전 분석해보길 바란다.


 
1.1 my.cnf(my.ini) 의 이해
 
 my.cnf는 MySQL 시작시 초기에 로딩하는 설정파일이다. 
 보통 기본 설치옵션대로 설치시 /etc/my.cnf 또는 /etc/mysql/my.cnf 등에 위치하며, 설정정보를 갱신할때는
 mysql을 재시작 해주면 된다.
 
재시작 할 수 없을때는 임시로 SET 명령을 통해 일부 변수들만 값을 바꿀수 있으나 이경우 MySQL 재시작시
매번 적용해줘야 하는 불편이 있으며 이를 피하기 위해서 my.cnf 내 init_connect 명령으로 
아래 예시와 같이 처리도 가능하다.
 ex) init_connect = "SET NAMES euckr"
 
 

1.2 환경변수와 상태변수의 차이
 
환경변수(show variables)는 수치를 조정해서 MySQL의 상태를 제어할 수 있는 변수값이며
상태변수(show status)는 현재 MySQL 가동 상태를 알 수 있는 변수값이다

 1.2.1 show variables 쿼리를통해 MySQL에서 사용되는 기본적인 환경변수의 값을 알 수 있다. 
 쿼리를 통해 볼 수 있는 변수는 mysqladmin 옵션형태로 적용 또는
 my.cnf 내에서 사용할변수=값 형태로 사용 가능하다.
 
 1.2.2 show status 쿼리를 통해 MySQL의 전체적인 상태를 알 수 있다.  
 쿼리를 통해 볼 수 있는 값들은 MySQL의 현재 상태들이며 이 문서에서 기본적으로 설명할 값들이다.
 튜닝할때 지속적으로 분석해봐야 하며 가장 효율적인 분석은 가장 부하량이 많을때와 평균 상태를 잘 파악해야
 효율적인 수치를 계산할 수 있으므로 바쁠때와 평균상태의 일정 주기를 정해서 분석해보는게 좋다.

 
 
1.3 서버 용도에 유의 해야 한다.
 
MySQL은 읽기(select)전용 DB서버와 쓰기(insert/delete/update)전용DB 서버의 기본적인 세팅을
틀리게 잡는게 유리하므로 서버가 초기 설계단계이거나 용도 변경이 가능 시 읽기/쓰기용 DB를
별도 분리시키면 세팅에 따라 높은 효과를 볼 수 있다.
 
참조 : 읽기전용 DB서버의 세팅시 RAID를 사용한다면 RAID1이 0보다 읽기속도가 더 빠르다.

 
 
1.4 하드웨어 Specification(이하 스펙)을 잘 파악해야 효율적인 세팅이 가능하다.
 
효율적인 세팅을 위해서는 가용가능한 메모리나 CPU등의 하드웨어 스펙을 미리 분석하고 있어야 한다.
MySQL은 기본적으로 한정된 메모리자원을 효율적으로 쓸수록 고성능을 발휘할 수 있게 된다.
주의할 사항으로 무조건적인 높은 수치가 고성능을 발생시키지 않는다.
 
 
 
2. show status를 통한 기초적인 분석방법 (MySQL 4.0 기반 설명)

기본 분석에 앞서 show status를 통해 볼 수 있는 상태변수들은 mysql 한글메뉴얼 부분을 참조하면 편합니다.
(4.0 기반 설명인데 링크 메뉴얼은 5.0이군요.. 죄송합니다.^^)

아래 링크에서도 MySQL 조율방법이 상세하게 나와있다.

일부 이해되지 않았던 내용은 서적 대용량 서버 구축을 위한 MySQL 성능 최적화 내 관련 사항 참조하였다. 
위 서적에서 이 글에서 표현하지 못한 많은 내용을 알 수 있으므로 강력히 추천한다.



2.1 Aborted_clients / Aborted_connects :  0에 가까울수록 좋은 수치 

네트워크 문제가 아닌이상 Aborted_clients가 올라가는 원인은 대부분 연결 프로그램에서 연결은 해놓고 
닫지 않았거나, 환경변수인 max_allowed_packet을 초과하는 쿼리가 발생 혹은 연결했는데 wait_timeout이 
경과할때까지 동작수행이 계속 되어 mysql자체에서 강제로 끊어버렸을 가능성이 가장 크다.

Aborted_connects 의 경우 최대 동시접속자(Max_used_connections)수치가 
설정보다 높아서 발생할 가능성이 가장크며 그외엔 거의 발생할 이유가 없다.



2.2 Bytes_received / Bytes_sent 

Bytes_sent가 높다면 이 서버는 읽기위주 작업(select) 
Bytes_received 가 높다면 이 서버는 쓰기 위주작업(insert 등) 서버임을 알 수 있다.

위의 Questions,Uptime과 함께 응용해보면 1개 쿼리당 평균 Byte, 시간당 처리Byte등을 계산 할 수 있어 
네트워크 트래픽등의 계산(예상 트래픽을 초과하는 쿼리가 있는지 등)에 유효하게 사용될 수 있다.



2.3 Questions / Uptime / Connections / Max_used_connections
 
Uptime 은 서버가 가동되고 나서 초를 의미하고, Questions는 서버가 가동되고 나서 수행된 쿼리의 수이다.
Connections는 서버 가동되고 나서 연결시도된 수치다.(현재 연결수는 Threads_connected)
Max_used_connections는 서버 가동 이후 최대 동시 연결 수치이다.

즉 환산해보면
Questions/Uptime = 초당 쿼리수를 나타낸다. 
Connections / Uptime = 초당 연결수를 알 수 있다.
Questions / Connections = 연결당 쿼리 처리수를 알 수 있다.

놀고 있는 시간과 바쁜시간의 차이를 알기위해 1분간격으로 측정한다면 다음과 같은 내용 확인이 가능하다.
1분간의 초당 쿼리 처리건수 = (현재의 Questions - 1분전의 Question) / (현재의 Uptime / 1분전의 Uptime)



2.4 Create_tmp_disk_tables / Create_tmp_files /Created_tmp_tables
 
이 수치는 생각보다 많은 고민을 안겨주는데 Create_tmp_disk_tables의 수치가 높다면 
물리디스크 엑세스를 자주 하고 있을것이므로  고속처리에서 문제를 가질 수 있다. 
즉 고속처리를 원한다면 Create_tmp_disk_tables 수치는 0에 가까운게 좋다.
 
주로 읽기전용 서버에서 Create_tmp_disk_tables의 수치가 높아지기 쉬우며 
쿼리가 BLOB또는 TEXT컬럼을 선택하는중에 임시테이블을 생성했다던지 할때 높아지기 쉽다.
이경우 메모리의 여유가 있다면 tmp_table_size 환경변수값이나 max_heap_table_size을 늘리면 
좀더 나은 효과를 기대 할 수 있다.
Created_tmp_tables(메모리내 임시테이블 생성) 수치가 의도보다 높을땐 쿼리최적화 이외에 해결책이 없다.



2.5 Com_ 상태변수(Com_insert, Com_update, Com_delete 등)
 
각 명령문이 실행된 수치를 알려주며, 대략적으로 서버의 용도나 가장 빈번히 일어나는 
쿼리의 형태를 알아낼 수 있다. 쿼리 타입과 관련된 사항이므로 의도하지 않은 쿼리가 발생하고 있다면 
면밀히 살펴보길 바란다.
 
예를들어 Com_drop_db 등이 발생하거나 Com_drop_table, Com_truncate 등의 수치가 올라가 있다면 
테이블이나 DB를 날린적이 있거나 종종 날린다는 소리이므로 의도한 동작인지를 확인해봐야 한다.



2.6 Delayed_errors / Delayed_insert_threads / Delayed_writes
 
insert delayed 를 별도로 사용하지 않는다면  올라갈 일이 없을 상태변수 
덤으로 MySQL INSERT 성능 향상을 위한 좋은 포스팅을 소개한다.

근원e 님의 블로그 : http://www.lovelgw.com/Blog/225

 
 
2.7 Handler_ 관련 상태변수(Handler_delete / Handler_update / Handler_write 등)
 
핸들러 관련 상태변수는 보통 쿼리최적화와 연관되어 있으며, 해당 수치의 높고 낮음으로 
DB에 연결되어 동작하는 쿼리문이 효율적으로 동작하는지 비효율적으로 동작하는지를 알아낼 수 있다.
예를들어 테이블 탐색 비율 = Handler_read_rnd_next / Com_select
인데 이 수치가 높을수록 인덱스를 비효율적으로 이용하는것으로 볼 수 있으며
단순 성능향상은 read_buffer_size 환경변수값의 조절을 통해 어느정도 가능하지만 근본적인 문제의
해결을 위해서는 쿼리문을 Explain으로 분석하여 효율적으로 인덱스를 활용해서 비율을 줄이는게 좋다.
(보통 4000:1 비율을 넘어가면 매우 비효율적으로 알려져있다.)
해당 핸들러 관련 상태변수는 아래 설명할 Key_관련 상태변수와도 연계되어 분석하는게 좋다.

 
 
2.8. Key_blocks_used / Key_read_requests / Key_reads / Key_write_requests / Key_writes
 
Key_read(초당 읽기 개수) 와 Key_writes(초당 쓰기 개수)는 높아질수록 
물리디스크의 읽고 쓰는 비중이 높아지므로 속도 저하의 원인이 된다. 
또한 읽기 관련 수치가 높아지는것은 캐시히트가 제대로 안되고 있을 가능성이 크다.
이경우 아래와 같은 식으로 캐시실패율을 구할 수 있으며, 캐시 실패율이 1% 이상인경우 
쿼리 분석을 통해 효율적으로 인덱스를 태우도록 개선이 필요하다. 
(임시방편으로 key_buffer_size 값을 늘리는 것도 가능하지만 근본적인 해결방법이 아니다!)
캐시실패율(%) = (Key_reads / Key_read_requests) * 100

또한 적당한 Key_buffer_size값을 구하려면 DB가 가장 바쁜시점에 
Key_blocks_used * key_cache_block_size(4.0에서는 해당 환경변수가 없으므로 1024로 계산)
수치가 key_buffer_size 환경변수보다 훨씬 작다면 메모리 낭비가 있다는 소리이므로 
Key_buffer_size의 값을 적당히 위값의 1.5~2배정도로 세팅하는게 좋다.



2.9 Open_files / Open_streams / Open_tables / Opened_tables
 
별다른 사항이 없다면 MyISAM 타입의 DB에서는 MYI(인덱스) MYD(데이터) 두개 파일을 열기 마련이므로 
Open_files = Open_tables * 2 정도의 수치를 일반적으로 보이게 된다.
평균적인 Open_files 값이 환경변수 table_cache값보다 더 큰경우 Opened_tables가 증가할 수 있다.
Open_files는 환경변수인 open_files_limit를 넘지 않도록 조정해야한다.

table_cache 수치는 Open_tables * 2 정도로 조정하면 넉넉한 편이다.
(Opened_files 수치가 증가하지 않을 정도로 조금씩 줄여보는게 좋다.)



2.10 Qcache_ 관련 상태변수 (Qcache_free_blocks / Qcache_hits / Qcache_not _cached 등)

쿼리 캐시 관련 내용은 성능에 많은 영향을 주면서도 세팅이 다소 복잡한 편이므로 주의를 요한다.
해당 내용은 "대용량 시스템 구축을 위한 MySQL 성능 최적화" 책내 237 Page  설명을 참조하였다.

쿼리캐시는 기본적으로 비활성화 상태이므로 환경변수값이 초기에 세팅되어 있어야 
사용가능하며, 이를통해 읽기작업이 빈번한 서버에서 효과적이다.
(query_cache_type / query_cache_size /query_cache_limit 등)

쿼리캐시는 데이터베이스를 이용시 동일한 쿼리가 여러번 반복되는 형태라면 효율적으로 동작 할 수 있으며
결과를 메모리에 저장해서 필요할때마다 찾아서 쓸 수 있어 성능을 높이는데 효과적이지만 과도한 쿼리캐시는
역시 역효과이므로 각각의 상태 변수값을 잘 확인해보는게 중요하다.

일반적으로 알려진 쿼리캐시 적중률은 다음과 같이 계산한다.
쿼리캐시적중률 = Qcache_hits / (Qcache_hits+Com_select)
캐시 적중률은 높은게 좋긴 하지만 높다고 무조건 좋은것은 아니며, 효율적인 튜닝을 위해서는 
다음과 같은 사항을 염두에 두고 처리한다.

 2.10.1 Qcache_lowmem_prunes 
 이 값이 높으면 메모리 부족때문에 무효화 된 쿼리가 있다는것이므로 쿼리캐시의 사이즈를 늘려본다.

 2.10.2 Qcache_free_memory 
평균적으로 이 수치가 높다면 활용되지 않고 있는 여유 메모리 공간이 있는것이므로 적당히 줄여본다.
 
 2.10.3 Qcache_not_cached 
 이 수치는 쿼리가 캐시불가일때 올라갈 수 있으며 이 수치가 과도하게 높다면 쿼리가 비확정요소로 인해 
 캐시저장이 제대로 안되고 있다는 소리이다 ( 즉 I/O 부하가 걸리기 쉽다.)
 예를들어 DATETIME형태에서 사용되는 NOW(),UNIX_TIMESTAMP() 등은 비확정요소로 취급되며 이도 저도 
 아닌경우에는 결과값이 너무 큰경우에도 비확정요소가 된다.
 최종적으로 쿼리 개선으로 해결해야 할 사항이며 비확정요소 개선이 안되는경우 쿼리캐시는 비효율적이다.
 
 2.10.4 Qcache_inserts
 일반적인 상황에서 Qcache_inserts는 Com_select보다 작은편이 좋다.

 2.10.5 그외 알아 둘 사항
 ● update가 많은 DB인 경우 쿼리캐시의 사용률 개선이 다소 어렵다.
 ● COUNT(*) 등의 집계형 쿼리가 자주 동작하면 쿼리캐시의 혜택을 받기 좋다.
 ● 복합적인 형태로 쿼리 캐시를 필요에 따라서 사용해야 한다면 환경변수 query_cache_type 을 조정한다
     (0, 사용안함 1. 사용 2. SQL_CACHE 힌트가 있을때만 사용)
 ● 쿼리캐시의 직접적인 혜택을 측정해보려면 쿼리캐시를 일단 꺼보고 나서 성능을 측정 후 다시 켜고 나서 
     일정시간 지난후 측정해보는게 좋다.
 ● 쿼리캐시는 반복되는 쿼리가 많을수록 효과적이므로 늘 새로운 쿼리가 발생하는 형태라면 
     거의 효율을 낼 수 없다. 



2.11 Select_관련 상태변수(Select_full_join / Select_full_range_join / Select_range 등)

Select관련 상태변수는 읽기 쿼리의 최적화가 되고 있는지를 파악하기 편하며, 쿼리최적화와 관련된 사항
이므로 위에 설명한 쿼리캐시 세팅과 맞물려 진행하면 나름대로 효과를 볼 수 있을것이다.

몇가지 중요한 부분만 체크해보면 아래와 같다.

 2.11.1 Select_full_join 
 이 수치가 올라간다는것은 인덱스가 없이 join이 일어나고 있다는 것이며 이경우 상당한 부하를 줄 수 있다.

 2.11.2 Select_full_range_join (join 상황) / Select_range(일반 상황)
 이 수치는 테이블 내에서 범위조회(예를들어 limit 100, 50) 을 많이 실행할때 증가하기 쉽다.
 Select_range_check 값이 증가한다면 쿼리가 사용하기 적합한 인덱스를 찾지 못하는 경우가 빈번한것으로 
 볼 수 있으며 Explain으로 쿼리를 분석해서 인덱스를 제대로 찾는지를 검토해보아야 한다.



2.12. Slow_launch_thread / Sort_merge_passes / Table_locks_wait

위 3개 상태변수는 한번 발생할때마다 심각한 지연을 줄 가능성이 크므로 꼼꼼히 살펴보는게 좋다.

 2.12.1 Slow_launch_thread 
 이값이 증가하면 연결할때마다 스레드지연이 발생한다는 소리이므로 
 서버 자체의 문제 또는 시스템 과부하가 걸리고 있을 가능성이 있다.

 2.12.2 Sort_merge_passes 
 파일로 정렬하는 행위가 발생할때 증가하므로 sort_buffer_size환경변수 값을 늘리거나, 쿼리를 개선한다. 
 예를들면 인덱스가 없는 필드를 기준으로 데이터를 order by할때 발생할 가능성이 있다.

 2.12.3 Table_locks_waited 
 Table locks_waited 는 테이블락이 걸린 총 시간이다. 모든 커넥션에서 락이 발생할경우 누적되며
 시간대별로 값을 측정후 이 값이 급격히 올라간다면 그 시간대에 지연이 발생하는 원인을 찾아야 할것이며
 측정 방식은 아래의 예시등 자신이 생각하는 수치를 추출하여 작업해본다.
 
구간 자료 샘플ABC
Uptime(서버 가동시간/초)224672287123145
Connection(연결)590764466761
Question(질의)572915634509749820
Table_locks_waited(잠금지연/초)372924646476449
 
 
구간별 산출값 샘플A~B구간B~C구간비고
경과시간(초)404274A~B구간은 6분44초 경과
 B~C구간은 4분 34초가 경과
연결수 (연결 / 경과시간)539315연결은 줄어듬 
쿼리수 (쿼리 / 경과시간)61594115311쿼리는 늘어남
잠금지연시간917229985구간별로 잠금지연이 급격히 
증가하는것을 알 수 있음
연결당 쿼리수(쿼리수 / 연결수)114.3366.1적은 연결에서 더많은 쿼리를 수행중
초당 쿼리수 - 이하 AA
(쿼리수/경과시간)
152.5420.81초에 평균적으로 처리하는 
쿼리 수는 152건/ 420건
초당 잠금지연시간 - 이하 BB
(잠금지연/경과시간)
22.7109.4짧은 지연이 지속적으로 발생하여 
성능에 악영향을 미치는것으로 예상됨
평균 쿼리별 잠금지연(AA/BB)6.73.8B~C구간보다는 A~B구간에서 
긴 잠금이 발생했을 가능성이 큼
 
 테이블 잠금은 동시간대 같은 테이블의 내용을 변경하여 데이터가 꼬이는것을 원천적으로 막기 위해 
 발생하는데 이를 개선하기 위해서는 테이블 분산 / 테이블 락 알고리즘 수동처리 혹은 필요에 따라 
 DB자체의 변경이 필요할 수 있다.
 (보통 MyISAM 타입에서 서버수준의 잠금이 일어나며, InnoDB의 경우 레코드수준 잠금이라 큰 영향이 없다.)
 
 단, 위 권장사항들은 사전계획을 제대로 세우고 하지 않으면 큰 재앙을 안길 수 있으니 주의할 것



2.13 Thread_cached / Threads_connected / Thread_created /Thread_running

스레드 관련 정보는 아래 재한님의 블로그중 관련 페이지를 일부 참조하였다. 

재한님의 블로그 : http://jaehan.tistory.com/110 

스레드는 CPU의 성능에 따라 적절한 조절이 필요하며, 아래의 경우에 
Thread_created의 수치가 초과한만큼 증가한다.
Thread_connected(현재 연결수) - Thread_cached > thread_cache_size(환경변수)

Thread_created가 증가하고 있다면 Thread_cache 환경변수의 값을 올려주는게 중요한데 
보통 CPU * 2 한도 내에서 조절을 권장한다.
(예를들어 쿼드코어 * 2CPU의 8 Core환경이라면 최대 16 이내에서 조절하는게 좋다)  



3. 여담 및 마무리

애매하거나 궁금한 자료는 쭉 찾아보면서 글을 쓰다보니 이 글을 완료하는데만 7시간은 작업한 것 같다.
MySQL을 처음 손대던때에는 멋모르고 이것저것 크게만 세팅 해서 그냥 돌아가긴 했지만
어느순간부터 비효율적으로 돌아간다는게 느껴져서 본격적으로 세팅을 다시 잡아보려고 써놓는 글이다.

이 글의 저작권은 CEnA에 있습니다. 퍼가실 때는 출처를 밝혀주세요.


반응형
반응형


tmux-1.6-1.el6.rf.x86_64.rpm




tmux 은, 한마디로 하나의 텔넷창에 여러 터미널을 실행할 수 있는 TTY 멀티플렉서 입니다.

 

tmux  에 대한 자세한 소개는 아래 두 블로거로 대신하구요

http://blog.outsider.ne.kr/699
http://nodeqa.com/nodejs_ref/99

 

간단한 명령어는 다음과 같습니다.  (기본키:Ctrl-b)

Ctrl-b  c : 새창 생성
Ctrl-b  d : 현재 클라이언트에서 떨어짐
Ctrl-b  l : 이전에 선택한 윈도우로 이동
Ctrl-b  n : 다음 윈도우로 이동
Ctrl-b  p : 이전 윈도우로 이동
Ctrl-b  w : 윈도우의 리스트를 보여주고 번호를 입력하면 이동
Ctrl-b  윈도우번호 : 해당 윈도우로 이동
Ctrl-b  & : 현재 윈도우를 종료
Ctrl-b  , : 현재 윈도우의 이름 변경

Ctrl-b  % : 세로로 2개 Pane으로 분할
Ctrl-b  " : 가로로 2개 Pane으로 분할
Ctrl-b  q : 팬 번호를 보여줌 (팬사이를 이동하는데 사용)

Ctrl-b  방향키 : 방향키 위치의 팬으로 이동
Ctrl-b  <alt>-방향키 : 현재 팬의 사이즈를 조정
Ctrl-b  <스페이스> : 팬의 레이아웃 변경

■ 적용사례

 



 

 

■ 설치

 

mkdir /usr1/mysql/dba/tools/tmux

cd /usr1/mysql/dba/tools/tmux

 

sudo su -

cd /usr1/mysql/dba/tools/tmux

wget http://pkgs.repoforge.org/tmux/tmux-1.6-1.el6.rf.x86_64.rpm

rpm -ivh tmux-1.6-1.el6.rf.x86_64.rpm

exit

 

 

■ 스크립트 샘플

 

cmd1_mon : 모니터링 (1)

cmd2_mon : 모니터링 (2)

cmd_list    : 커맨드라인

tmux_1by3 : 왼쪽1:오른쪽3 윈도우 실행 템플릿
tmux_3by3 : 왼쪽3:오른쪽3 윈도우 실행 템플릿

 

 

cd /usr1/mysql/dba/tools

 

vi cmd1_mon
========================================================
#!/bin/sh

TITLE="DB Monitoring"
L_TOP="sh /usr1/mysql/dba/tools/chk_qps.sh"
L_MID="iostat -dmx 1"
L_MID2="vmstat 1"
L_MID3="sh /usr1/mysql/dba/tools/chk_lock.sh"
L_BOT=""

R_TOP=""
R_MID="nmon"
R_BOT="vmstat 1"

tmux new-session  -d -s "${TITLE}" "${L_TOP}"
tmux split-window -v -p 80 "${L_MID}"

tmux selectp -t 0
tmux split-window -h -p 30 "${R_TOP}"

tmux selectp -t 2
tmux split-window -h -p 50 "${R_MID}"

tmux selectp -t 2
tmux split-window -v -p 70 "${L_MID2}"
tmux split-window -v -p 70 "${L_MID3}"
tmux split-window -v -p 50 "${L_BOT}"

tmux -2 attach-session -d
========================================================

 

 

vi cmd2_mon
========================================================
#!/bin/sh

TITLE="DB Monitoring"
L_TOP="sh /usr1/mysql/dba/tools/chk_pp.sh"
L_MID=""
L_MID2="vmstat 1"
L_MID3="sh /usr1/mysql/dba/tools/chk_lock.sh"
L_BOT=""

R_TOP=""
R_MID="vmstat 1"
R_BOT="iostat -dmx 1"

tmux new-session  -d -s "${TITLE}" "${L_TOP}"
tmux split-window -v -p 40 "${L_MID}"

tmux selectp -t 1
tmux split-window -h -p 50 "${R_MID}"
tmux split-window -v -p 50 "${R_BOT}"

tmux selectp -t 1

tmux -2 attach-session -d
========================================================


 

vi tmux_1by3
========================================================
#!/bin/sh

TITLE="[1by3]"
L_TOP=$1

R_TOP=$2
R_MID=$3
R_BOT=$4

tmux new-session  -d -s "${TITLE}" "${L_TOP}"
tmux split-window -h -p 50 "${R_TOP}"

tmux selectp -t 1
tmux split-window -v -p 60 "${R_MID}"
tmux split-window -v -p 50 "${R_BOT}"

tmux selectp -t 0

tmux -2 attach-session -d
========================================================

 


vi tmux_3by3
========================================================
#!/bin/sh

TITLE="[3x3]"
L_TOP=$1
L_MID=$2
L_BOT=$3

R_TOP=$4
R_MID=$5
R_BOT=$6

tmux new-session -d -s "${TITLE}" "${L_TOP}"
tmux split-window -h "${R_TOP}"
tmux selectp -t 0
tmux split-window -v -p 60 "${L_MID}"
tmux split-window -v -p 50 "${L_BOT}"
tmux selectp -t 3
tmux split-window -v -p 60 "${R_MID}"
tmux split-window -v -p 50 "${R_BOT}"

tmux selectp -t 0

tmux -2 attach-session -d
========================================================

 

 

vi cmd_list
========================================================
#!/bin/bash

function cmdList() {
echo "##########################################"
echo "###            Command List            ###"
echo "##########################################"
echo ""
echo "   1.Mon 1 (1by3 - Normal)"
echo "   2.Mon 2 (3by3 - Normal)"
echo "   3.Mon 2 (Processlist)"
echo "   4.Mon 3 (BMT)"
echo ""
echo "   0.exit"
echo ""
echo "##########################################"
}

source /usr1/mysql/dba/.env.ini

while true
do
   echo ;
   echo ;
   cmdList

   echo -n "[Input Number] : "
   read num

   case $num in
      1) /usr1/mysql/dba/tools/tmux/tmux_1by3 ""       "/usr1/mysql/dba/.cmd" "iostat -dmx 1" "vmstat 1"; exit; break;;
      2) /usr1/mysql/dba/tools/tmux/tmux_3by3 "" "" "" "/usr1/mysql/dba/.cmd" "iostat -dmx 1" "vmstat 1"; exit; break;;
      3) cmd="/usr1/mysql/dba/tools/tmux/cmd2_mon";                  break;;
      4) cmd="/usr1/mysql/dba/tools/tmux/cmd1_mon";                  break;;
      0) break;;
      *)
         echo "Wrong Number. Chekc Server Number.";;
   esac

done

#echo $cmd
$cmd
========================================================


출처 : http://cafe.naver.com/mysqlpg/667


반응형
반응형

임시 테이블이 필요한 쿼리

. ORDER BY 와 GROUP BY 에 명시된 컬럼이 다른 쿼리

. ORDER BY 나 GROUP BY 에 명시된 컬럼이 조인의 순서상 첫 번째 테이블이 아닌 경우

. DISTINCT 와 ORDER BY 가 동시에 쿼리에 존재하는 경우 또는 DISTINCT 가 인덱스로 처리되지 못하는 쿼리

. UNION 이나 UNION DISTINCT 가 사용된 쿼리 (select_type 컬럼이 UNION RESULT 인 경우)

. UNION ALL 이 사용된 쿼리 (select_type 컬럼이 UNION RESULT 인 경우)

. 쿼리의 실행 계획에서 select_type 이 DERIVED 인 쿼리

 

반응형
반응형

mysql 내에 dirty page가 생기게 되면

fuzzy checkpointing 메카니즘을 통해 자연스럽게 flush가 일어나게 되는데요.


과도한 update로 인해 dirty page의 증가가 빠르게 일어나고

innodb_max_dirty_pages_pct와 innodb_log_file_size 등에 설정된 

임계치를 넘어서게 되면 강제 flush 가 발생하게 됩니다.


문제는 강제 flush가 발생하게 되면 그 시점 이후의 query 실행을 지연시켜

slow가 발생하는 것인데요.

OLTP 성격의 DB에서는 치명적일 수 있습니다.


InnoDB에는 LRU flush, Flushlist flush의 두가지 강제 flush가 존재하는데

buffer pool에 남은 free page가 없는데 데이터 읽기를 시도할 때는 LRU list를 참조한 flush가 일어나고,

buffer pool에 남은 dirty page가 innodb_max_dirty_pages_pct에 설정해놓은 점유율을 넘어설때는 flush list를 참조한 flush가 일어납니다.

고로, 전자의 상황에서는 innodb_adaptive_flushing, innodb_max_dirty_pages_pct, innodb_io_capacity, innodb_log_file_size의 변경은 의미가 없는거죠.


확인 방법은

show engine innodb status;

...

Pending writes: LRU 0, flush list 0, single page 0

...


그러므로 LRU list를 참조하는 flush가 대다수인 경우는, memory를 증설하거나, 시스템의 I/O를 업그레이드 하는 것이 제일 큰 이득이 있을 것이고, flush list를 참조하는 flush가 대다수인 경우는, innodb_adaptive_flushing, innodb_max_dirty_pages_pct, innodb_io_capacity, innodb_log_file_size의 변경이 중요하게 작용합니다.

물론 이 상황에서도 memory를 증설하거나, 시스템의 I/O를 업그레이드 하는 것은 도움이 됩니다.


제 해석은 주관적이거나 오역이 있을 수 있기에 원문을 첨부합니다.

(원문: http://www.mysqlperformanceblog.com/2011/01/13/different-flavors-of-innodb-flushing/ )


innodb_log_file_size의 증가는 더 많은 dirty page를 받아들이게 하는데 확실한 효과가 있습니다. (테스트 결과)

다르게 말하면, 강제 flush가 일어나는 시점을 좀 더 뒤로 미루는데 도움(?)을 준다는 거죠.

그런데 과연 이게 제대로된 문제 해결 방법인지 의구심이 드네요.

결국 그 임계치를 넘어서는 update가 또 발생한다면 다시 문제가 생길테니까요.


과도한 dirty page 증가로 인한 slow query 발생을 해결하는 방법은 하드웨어의 업그레이드 말고는 없는 것일까요?


출처 : http://cafe.naver.com/mysqlpg/441

반응형
반응형


create table usp_multi_tab

as

select @rnum := @rnum + 1 as id, b.*

from (select @rnum := 0) a, information_schema.GLOBAL_STATUS b limit 10;


select replace(replace('1,3,5', ',', ''), ' ', '') regexp "[^0-9]+";


delimiter //

drop procedure if exists usp_multi //

create procedure usp_multi (

in pi_keylist text

)

begin

declare v_SQL text default '';

declare v_sqlstate varchar(5) default '00000';

declare v_err_no int;

declare exit handler for sqlexception, sqlwarning

begin

get diagnostics condition 1 v_sqlstate = RETURNED_SQLSTATE, v_err_no = MYSQL_ERRNO;

ROLLBACK;

SELECT v_sqlstate, v_err_no;

end;

if (replace(replace(pi_keylist, ',',''),' ', '') regexp "[^0-9]+") = 0 then

set v_SQL = CONCAT(v_SQL, 'SELECT *');

set v_SQL = CONCAT(v_SQL, '    FROM usp_multi_tab');

set v_SQL = CONCAT(v_SQL, '    WHERE id IN (', pi_keylist, ');');

-- select v_SQL;

set @vSQL := v_SQL;

PREPARE stmt FROM @vSQL;

EXECUTE stmt;

DEALLOCATE PREPARE stmt;

end if;

end //

delimiter ;


select * from usp_multi_tab;


call usp_multi('A');

call usp_multi('1,3,5');

반응형

'연구개발 > MYSQL' 카테고리의 다른 글

임시테이블이 필요한 쿼리 ( using temporary )  (0) 2015.03.09
innodb flush  (0) 2015.03.05
update 전/후 데이터 반환받기  (0) 2015.03.03
MRU LRU  (0) 2015.03.03
index hit  (0) 2015.03.02

+ Recent posts

반응형