mariabackup 을 이용한 MariaDB 10.6.9 Replication 구성하기

리눅스/MySQL|2022. 9. 19. 10:10
반응형

percona-xtrabackup 패키지는 MySQL 또는 MariaDB 서버의 서비스 중지 없이 Replication 을 구성하기 위한 명령어 입니다.

아래 내용은 CentOS 8 환경에서 MariaDB 10.6.9 버전으로 테스트 하였습니다.

사용자 계정이나 패스워드, 디렉토리 등은 사용자 환경에 따라 다르므로 명령 실행시 확인 후 실행하시기 바랍니다.

- master 서버 : 192.168.10.2

- slave 서버 : 192.168.10.3

- 참고1 : percona-xtrabackup 패키지는 MySQL 과 MariaDB 둘 다 가능합니다. 다만 설치 버전에 따라 지원가능한 DB 버전이 다르며 MySQL 은 xtrabackup, MariaDB 는 mariabackup 이라는 명령을 사용하는것이 큰 차이점 입니다.

(redo 로그를 기록하는 파일이 다름)

 

- LINK : xtrabackup 을 이용한 MySQL 8.0.28 Replication 구성하기

 

1. 설치

 

(인터넷 연결 가능할 경우)

master 서버와 slave 서버에 xtrabackup 을 설치 합니다.

# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

# yum -y install percona-xtrabackup-24

 

(인터넷 연결 불가의 경우)

사설망에서 DB를 운영할 경우 서버에 없는 패키지는 설치 파일을 다운 받아 복사하여 설치하면 됩니다.

서버 환경에 따라 필요한 패키지가 다를 수 있으며 이는 아래 rpm 명령으로 의존성 확인이 가능합니다.

 

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/libev-4.24-6.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/perl-DBI-1.641-1.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/rsync-3.1.3-12.el8.x86_64.rpm

# wget https://repo.percona.com/yum/release/8/RPMS/x86_64/percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm 

 

필요한 패키지를 다운로드 한 후 DB 서버로 옮깁니다. (scp 또는 rsync 등으로 복사하면 됩니다. 방법은 생략)

그리고 아래 순서에 따라 설치합니다.

 

# rpm -ivh libev-4.24-6.el8.x86_64.rpm

# rpm -ivh perl-DBI-1.641-1.el8.x86_64.rpm

# rpm -ivh perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# rpm -ivh rsync-3.1.3-12.el8.x86_64.rpm

# rpm -ivh percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm

 

2. 원본 데이터 백업

 

(master 서버에서)

# mariabackup --defaults-file=/etc/my.cnf --backup --user=root --password=12345678 --target-dir=/mariabackup --no-lock --port=3306 --socket=/tmp/mysql.sock

 

백업이 완료되면 /mariabackup 디렉토리가 생성되며 하단에 백업 파일들이 존재하게 됩니다.

data 디렉토리 내 파일들과 mariabackup 관련된 로그가 있습니다.

 

3. 데이터 이전

 

(master 서버에서)

master 서버에 백업된 데이터를 slave 서버로 복사합니다.

# rsync -avzPog /mariabackup root@192.168.10.3:/

 

4. 데이터 복원

 

(slave 서버에서)

mysqld 데몬을 중지하고 기존 data 디렉토리를 삭제 합니다. (mv 명령으로 디렉토리 이름 변경 권장)

가져온 데이터를 복구하는 과정에서 기존 data 디렉토리내 파일이 있으면 실행이 되지 않기 때문입니다.

 

백업중 작성된 redo 로그를 데이터에 적용합니다.

# mariabackup --prepare --target-dir=/mariabackup

 

> --use-memory=10G 와 같이 본 작업에 사용할 시스템 메모리양을 어느정도 할당 해주면 빠른처리가 가능합니다.

> redo 로그 적용 도중에 아래와 같은 에러 메세지가 출력 될 경우 --innodb_force_recovery=1 옵션을 추가 합니다.

2022-10-14  8:47:54 0 [Note] InnoDB: Set innodb_force_recovery=1 to ignore corrupted pages.
2022-10-14  8:47:54 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
[00] FATAL ERROR: 2022-10-14 08:47:54 mariabackup: innodb_init() returned 11 (Generic error).

하지만 백업 과정에서 문제가 생겼을 수 있으므로 master 서버에서 몇 번 더 백업을 반복 시도해 보는것도 좋습니다.

 

백업 파일을 이동합니다. (--copy-back 를 사용하면 복사)
# mariabackup --move-back --datadir=/usr/local/mysql/data --target-dir=/mariabackup

 

root 로 복원하였기 때문에 복원된 파일의 권한이 root 로 되어 있습니다.

mysql 가동을 위해 data 디렉토리의 권한을 설정을 합니다.

# chmod 755 /usr/local/mysql/data
# chown mysql.mysql -R /usr/local/mysql/data

# systemctl start mysqld

 

5. 로그 포지션 설정 및 동기화 시작

 

백업본의 xtrabackup_binlog_info 에 있는 mysql-bin 파일명과 position 값 참고하여
replication 을 적용합니다.

 

(slave 서버에서)

# cat /usr/local/mysql/data/xtrabackup_info |grep binlog_pos

binlog_pos = filename 'binlog.000002', position '943'    // 출력된 내용을 참고

 

# mysql -p

mysql> stop slave;

mysql> reset slave;

mysql> change master to master_host='192.168.10.2', master_user='repl',
master_password='12345678', master_log_file='binlog.000002',
master_log_pos=943;

mysql> start slave;

 

정상적으로 동기화 된 것을 확인할 수 있습니다.

mysql> show slave status \G;

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

 

반응형

댓글()

[에러] Too many open files 조치하는 방법 (ulimit 명령어)

리눅스/OS 일반|2022. 9. 14. 16:59
반응형

OS 내에서 작업중 어디에선가 아래와 같은 메세지가 출력될 경우 ulimit 를 활용해보도록 합니다.

 

에러 : 'Too many open files'

조치 : ulimit 명령어 사용

 

우선 많은 파일을 열기 위해서는 ulimit 에서 오픈가능한 파일의 최대 수를 조정해주어야 합니다.

OS 기본값은 1024 입니다.

동시에 여는 파일이 많을 수록 더 많은 메모리 양을 필요로 한다는 것을 참고 하고, 필요한 값으로 조정을 합니다.

예제에서는 50000으로 조정하는 내용을 담았습니다.

 

1. 현재 설정값 확인

 

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 256092
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 256092
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

 

2. 설정값 변경 (일시적)

 

# ulimit -n 50000

 

(변경 내용 확인)

# ulimit -a |grep 'open files'
open files                      (-n) 50000

 

변경이 되었습니다. 하지만 재로그인 또는 리부팅의 작업을 거치면 다시 원래의 1024 값으로 돌아가므로

변경값이 기본으로 셋팅 되도록 해봅니다.

 

3. 설정값 변경 (영구적)

 

설정파일의 맨 아래에 아래 4줄 내용을 추가 하면 재로그인 또는 리부팅 후에도 변경된 값을 유지하게 됩니다.

설정 내용중 * 표시는 root 를 제외한 모든 계정을 의미합니다.

 

# vi /etc/security/limits.conf

 

root     soft nofile 50000

root     hard nofile 50000

*        soft nofile 50000

*        hard nofile 50000

 

 

반응형

댓글()

Rocky Linux 8.6 에서 MariaDB 10.9.2 소스 설치하기 (with InnoDB 이노디비 설정)

리눅스/MySQL|2022. 9. 13. 10:25
반응형

1. 필수 패키지 설치

 

# dnf -y update
# dnf -y install cmake ncurses-devel openssl openssl-devel

 

작업이 잘 수행 되도록 아래 명령 실행 하고, 서버 부팅시에도 selinux 비활성화를 위해 설정을 수정해 줍니다.

# setenforce 0

# vi /etc/selinux/config

SELINUX=disabled

 

 

2. MariaDB 계정 추가

 

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

 


3. MariaDB 설치

 

# cd /usr/local/src
# wget https://mirror-mariadb.nzbilisim.net/mariadb/pub/mariadb/mariadb-10.9.2/source/mariadb-10.9.2.tar.gz
# tar xvfz mariadb-10.9.2.tar.gz
# cd mariadb-10.9.2
# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_INNOBASE_STORAGE_ENGINE=1 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=1
# make
# make install

 

 

4. MariaDB 환경 설정

 

환경 설정 파일이 없어도 아래 '5번 항목' 에서 기본 DB 생성 후 MariaDB 구동은 가능하지만

my.cnf 파일을 생성하면 서버 사양 및 운영 방식에 알맞게 환경을 조정할 수 있습니다.

아래는 InnoDB 구성을 위한 예 입니다.


# vi /etc/my.cnf

[client]
default-character-set = utf8


[mysqld]
#################### 일반 서버 설정 ####################
# 서버 순번
server-id = 1
# 기본 엔진 설정
default-storage-engine = InnoDB
# 역 DNS 검색 비활성
skip-name-resolve
# 최대 클라이언트 연결 개수
max_connections = 1024
# 다쓴 쓰레드를 스레드풀에 저장할 갯수
thread_cache_size = 50
# 커넥션 최대 대기시간(초)
wait_timeout = 28800
# 정렬에 필요한 버퍼의 크기 ORDER BY 또는 GROUP BY 연산 속도와 관련
sort_buffer_size = 512K
# 캐릭터셋
collation-server = utf8_unicode_ci
character-set-server = utf8
skip-character-set-client-handshake

############# InnoDB 설정 (메모리 8G 기준) #############
# 테이블 단위로 테이블스페이스 할당, 활성시 확장자 .ibd 파일이 생성됨
innodb_file_per_table = 1
# innodb 홈디렉터리 경로
innodb_data_home_dir = /usr/local/mysql/data
# 파일명 : 초기용량 : 자동증가 : 최대사이즈 (파일 재생성 할때 사용)
#innodb_data_file_path = ibdata1:1024M:autoextend
# 테이블 스페이스 자동 확장시 크기
innodb_autoextend_increment = 100
innodb_log_group_home_dir = /usr/local/mysql/data
# 데이터와 인덱스를 캐시하기 위해 사용하는 메모리 버퍼크기
# 서버에 MySQL만 실행한다면, 물리메모리의 50~80%를 지정
innodb_buffer_pool_size = 5G
# Redo 로그 버퍼크기
innodb_log_buffer_size = 16M

# 로그 파일 한 개의 크기로 보통 buffer_pool 사이즈의 10%를 지정
# 크기가 클 수록 체크포인트가 덜 발생해 디스크 I/O를 줄이지만,
# 디비가 크래시 났을 경우 복구 타임이 길어진다.
innodb_log_file_size = 512M

# 커밋 로그 옵션으로 성능 최적화에 사용
# 1 : 트랜젝션 실행할때마다 redo 로그 파일에 기록되고 디스크 플러시가 실행 (default 값)
# 2 : 트랜젝션의 양은 상관없이 flush 가 1초에 한번씩만 수행되기 때문에 매번 flush 되는 기본값보다 IO 성능이 월등히 좋아지지만
#     단점은 데이터를 유실할 가능성이 있다는 점 (예: flush 되기 전 1초 이내 셧다운)
# 0 : 2와 동일하나 OS buffer 를 거치는 부분이 제외되어 더 빠름. 데이터 유실 가능성은 동일.
# 설명 : 서버가 죽었을때 1~2초 정도의 데이터를 버릴수 있을 정도의 상황이라면 0 또는 2 를 선택
#        커밋된 데이터는 무조건 살려야만 한다면 반드시 1 을 선택
innodb_flush_log_at_trx_commit = 1

# 롤백이 진행되기 전에 LOCK을 대기하는 시간(초)
innodb_lock_wait_timeout = 20
# 크래시 복구 모드 설정
innodb_force_recovery = 0
# 성능을 위해 메모리에서 직접 액세스 하도록 설정
innodb_flush_method = O_DSYNC

# O_DIRECT=운영체제의 버퍼를 사용 않고 IO 실행, RAID 컨트롤러(캐시메모리 장착된)가 없거나 SAN 사용시 O_DIRECT를 사용 하지 않음
# 이중 쓰기 버퍼 비활성
innodb_doublewrite = 0
# 쓰레드가 지연되기 전에 (suspended) 풀어 주기 위해 InnoDB 뮤텍스 (mutex) 를 기다리는 쓰레드의 대기 시간
innodb_sync_spin_loops = 20
# LOCK TABLES 은 AUTOCOMMIT=0 경우에, InnoDB로 하여금 내부적으로 테이블을 잠금
innodb_table_locks = 1
# 퍼지 연산 (purge operation)이 래깅 (lagging) 될 때 INSERT, UPDATE 및 DELETE 연산을 지연 시키는 방법을 제어
# 디폴트값 0 일시 지연 없음
innodb_max_purge_lag = 0
# innodb 에 만들 수 없는 데이블이나 들어갈 수 없는 길이의 데이터를 허용
#innodb_strict_mode = 0

#################### 바이너리 로그 #####################
# 바이너리 로그 파일 (binlog.xxxx 형태의 파일 생성. 경로 추가 가능)
#skip-log-bin
log-bin = binlog
# 파일당 최대 사이즈
max_binlog_size = 1G

##################### 제네럴 로그 ######################
# 제네럴 로그 사용 여부 (0: 비활성, 1: 활성)
general_log = 1
# 제네럴 로그 파일
general_log_file = /usr/local/mysql/data/general_query.log


################### 슬로우 쿼리 로그 ###################
# 슬로우 로그 사용 여부 (0: 비활성, 1: 활성)
slow-query-log = 1
# 슬로우 쿼리를 구분하는 소요 시간 (초)
long_query_time = 10
# 슬로우 로그 파일
slow_query_log_file = /usr/local/mysql/data/slow_query.log


[mysqldump]
default-character-set = utf8


[mysql]
default-character-set = utf8

* 옵션 설명은 아래 URL 참고

https://yakolla.tistory.com/61

https://bae9086.tistory.com/175 

https://systemv.tistory.com/48

 

 

5. MariaDB 초기 데이터 베이스 생성

 

생성해두었던 my.cnf 파일을 읽어 환경에 맞게 기본 DB 를 생성합니다.

MariaDB 는 10.4 버전부터 새로운 암호화 방식이 추가 되었습니다. (MySQL 5.7 이후 버전과 동일)

그 이전 버전과 같은 암호화 방식을 사용하려는 경우 --auth-root-authentication-method=normal 옵션을 추가하여 data 디렉토리를 생성하면 됩니다.

(예 : 계정 패스워드 변경시)

- 구버전 : update user set...

- 신버전 : alter user...

# ./scripts/mysql_install_db --user=mysql --datadir=/usr/local/mysql/data --basedir=/usr/local/mysql

 

DB 생성시 아래와 같은 메세지가 출력된 경우

 

chown: cannot access '/auth_pam_tool_dir': 그런 파일이나 디렉터리가 없습니다
Cannot change ownership of the '/auth_pam_tool_dir' directory
to the 'mysql' user. Check that you have the necessary permissions and try again.

 

다음과 같이 조치하고, data 디렉토리 삭제 및 mysql_install_db 명령을 다시 실행합니다.

# mkdir /auth_pam_tool_dir
# touch /auth_pam_tool_dir/auth_pam_tool
# chown mysql.mysql /auth_pam_tool_dir -R
# chmod 770 /auth_pam_tool_dir -R

 

 

6. MariaDB 구동

 

데몬 구동을 쉽게 하기 위해 명령어를 복사하고, 서버 부팅시 자동으로 데몬이 구동 되도록 설정합니다.

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

# /etc/init.d/mysqld start

 

 

* 이후 작업 (필요에 따라 설정)

 

1) mysql 명령을 경로에 상관없이 사용하도록 설정 추가

# vi /etc/profile

PATH="$PATH:/usr/local/mysql/bin"

# source /etc/profile

 

2) firewalld 방화벽 설정 (서버 외부에서 DB 바로 접근 필요시)

# firewall-cmd --zone=public --add-port=3306/tcp

 

3) MySQL root 패스워드 업데이트

mysql> use mysql;

mysql> alter user root@localhost identified by 'NEWPASSWD';

mysql> flush privileges;

 

 

반응형

댓글()

[Shell Script] MySQL 테이블 별로 백업 하기

프로그래밍/BASH SHELL|2022. 9. 8. 08:17
반응형

쉘스크립트를 이용하여 모든 데이터베이스를 테이블 별로 백업하는 방법 입니다.

파일명은 {DB명}.{테이블명}.sql 형식으로 남게 됩니다.

 

# vi mysql_backup_by_table.sh

 

#!/bin/bash

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

# 백업 디렉토리
mkdir -p /backup/${today}
cd /backup/${today}

# MySQL root 패스워드
root_pw='12345678'

# 1) 모든 DB 백업
list=`echo "show databases;" |mysql -uroot -p"$root_pw"`

# 2) 선택한 DB 만 백업 (개행 \n 으로 구분)
#list=`echo -e "mysql\nmonitor\nsysdocu"`

for db in $list;
do
    table_list=`echo "show tables" |mysql -uroot -p"$root_pw" $db`
    for table in $table_list;
    do
        mysqldump -uroot -p"$root_pw" $db $table > ${db}.${table}.sql
        #tar cvzf ${db}.${table}.tar.gz ${db}.${table}.sql --remove-files # 압축 보관 및 원본 삭제
    done
done

 

# chmod 700 mysql_backup_by_table.sh

 

실행

# sh mysql_backup_by_table.sh

 

 

반응형

댓글()

Rocky Linux 8.x 에서 dnf 를 이용한 APM 설치

리눅스/APACHE|2022. 9. 6. 09:37
반응형

1. APM 설치

 

1) 아파치 설치

# dnf -y install httpd

 

2) MySQL 설치

# dnf -y install mysql mysql-server

 

3) PHP 설치

 

설치 가능한 PHP 버전 출력

# dnf module list php

 

원하는 버전으로 모듈 활성화

# dnf module enable php:7.4

 

설치

# dnf -y install php php-mysqlnd

 

 

2. 기본 설정

 

# vi /etc/httpd/conf/httpd.conf

ServerName 127.0.0.1

DirectoryIndex index.html index.htm index.php

AddType application/x-httpd-php .html .htm .php
AddType application/x-httpd-php-source .phps

 

# vi /etc/php.ini

short_open_tag = On
date.timezone = "Asia/Seoul"

 

html 확장자 파일에서 사용된 php 코드도 인식할 수 있게 아래 내용을 수정합니다.

 

# vi /etc/httpd/conf.d/php.conf

<FilesMatch \.(php|phar|html|htm)$> // 두 군데

 

# vi /etc/php-fpm.d/www.conf

security.limit_extensions = // 주석 해제하고 뒤에 .htm .html 추가

 

변경 내용을 적용합니다.

 

# systemctl restart php-fpm

# systemctl restart httpd

 

반응형

댓글()

Rocky Linux 8.x 에서 Let's encrypt 설치 및 SSL 발급받기

리눅스/APACHE|2022. 9. 6. 08:58
반응형

OS 종류 및 버전에 따라 설치방법이 조금씩 다릅니다.

본 내용은 Rocky Linux 8.x 에서 설치하는 방법을 다루었습니다.

 

1. 패키지 다운로드

# dnf -y install epel-release mod_ssl

# dnf -y install certbot python3-certbot-apache

 

2. 발급

# certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): (이메일 주소 입력)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017-w-v1.3-notice.pdf.
You must agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.sysdocu.com
2: sub.sysdocu.com

3: test.sysdocu.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1 2  // virtualhost 설정을 가져와 도메인을 출력합니다. 발급 원하는 도메인을 공백으로 구분하여 입력합니다. 통합 인증서가 아닌, 개별 인증서로 발급 받게 됩니다.
Requesting a certificate for www.sysdocu.com and sub.sysdocu.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.sysdocu.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/www.sysdocu.com/privkey.pem
This certificate expires on 2022-12-04.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for www.sysdocu.com to /etc/httpd/conf/httpd-le-ssl.conf
Successfully deployed certificate for sub.sysdocu.com to /etc/httpd/conf/httpd-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://www.sysdocu.com and https://sub.sysdocu.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 

아래 파일이 생성되면서 아파치 SSL 설정이 자동으로 이루어졌습니다.

> /etc/httpd/conf/httpd-le-ssl.conf

 

설정에 이상이 없는지 확인 후 아파치를 재시작 해줍니다.

# apachectl configtest

Syntax OK

 

# systemctl restart httpd

 

이제 https:// 프로토콜을 이용해 웹페이지 접근이 가능해졌습니다.

 

3. 자동 갱신 설정

 

발급된 인증서 유효기간은 3개월이며, 만료 1개월 전부터 갱신이 가능합니다.

자동으로 발급받아질 수 있게 crontab 에 등록해 줍니다. (2개월에 한번씩 1일, 16일에 체크하여 갱신)

 

# vi /etc/crontab

01 00 01,16 */2 * root /usr/sbin/certbot renew

 

 

반응형

댓글()

sysbench 1.0.20 를 이용한 MySQL 성능 (performance) 테스트

리눅스/MySQL|2022. 9. 1. 09:21
반응형

sysbench 는 설치된 MySQL DB 서버의 성능을 확인하는 도구 입니다.

아래는 Rocky Linux 8.6 환경에서 테스트 하였습니다.

 

 

1. 설치

 

# yum -y install sysbench


2. 테스트 DB 생성

 

데이터를 쓰고 읽을 테스트용 DB 를 하나 만들어 줍니다.
mysql> create database test;
Query OK, 0 rows affected (0.01 sec)

 


3. 테스트 데이터 준비

 

# sysbench \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-socket=/tmp/mysql.sock \
--mysql-user=root \
--mysql-password=12345678 \
--mysql-db=test \
--table-size=1000000 \
--tables=5 \
/usr/share/sysbench/oltp_read_only.lua \
prepare

(결과)
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Creating table 'sbtest1'...
Inserting 1000000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...
Creating table 'sbtest2'...
Inserting 1000000 records into 'sbtest2'
Creating a secondary index on 'sbtest2'...
Creating table 'sbtest3'...
Inserting 1000000 records into 'sbtest3'
Creating a secondary index on 'sbtest3'...
Creating table 'sbtest4'...
Inserting 1000000 records into 'sbtest4'
Creating a secondary index on 'sbtest4'...
Creating table 'sbtest5'...
Inserting 1000000 records into 'sbtest5'
Creating a secondary index on 'sbtest5'...

* 참고1

명령 실행시 마지막줄 prepare 는 sysbench 에서 지원하는 명령어이며 사용 가능한 명령어 종류는 아래와 같습니다.
prepare, prewarm, run, cleanup, help

주로 사용하는 옵션
- prepare : 테스트를 준비합니다. test 데이터베이스에 테스트할 임시 데이터를 넣어 놓습니다.
- run : 실제적인 퍼포먼스 테스트를 진행 합니다.
- cleanup : 테스트 하면서 생성된 테이블 및 레코드를 삭제합니다.

 

* 참고2

/usr/share/sysbench 디렉토리에는 데이터 insert, read, delete 등의 테스트를 할 수 있는 파일이 준비되어 있습니다.

아래에서 순차적으로 실행해 보도록 하겠습니다.


(확인)
테스트 DB 에 테이블 생성 및 데이터 입력이 확인되었습니다.

mysql> show tables;
+--------------------+
| Tables_in_sysbench |
+--------------------+
| sbtest1            |
| sbtest2            |
| sbtest3            |
| sbtest4            |
| sbtest5            |
+--------------------+
5 rows in set (0.00 sec)

mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.75 sec)


4. 테스트 실행

 

# sysbench \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-socket=/tmp/mysql.sock \
--mysql-user=root \
--mysql-password=12345678 \
--mysql-db=test \
--table-size=1000000 \
--tables=5 \
/usr/share/sysbench/oltp_read_only.lua \
run

(결과)
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Running the test with following options:
Number of threads: 1
Initializing random number generator from current time


Initializing worker threads...

Threads started!

SQL statistics:
    queries performed:
        read:                            145838
        write:                           0
        other:                           20834
        total:                           166672
    transactions:                        10417  (1041.42 per sec.)
    queries:                             166672 (16662.68 per sec.)  // 초당 16,662 개의 read 쿼리가 실행되었습니다.
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          10.0010s
    total number of events:              10417

Latency (ms):
         min:                                    0.91
         avg:                                    0.96
         max:                                    1.87
         95th percentile:                        1.01
         sum:                                 9995.05

Threads fairness:
    events (avg/stddev):           10417.0000/0.00
    execution time (avg/stddev):   9.9950/0.00

(결과2)

oltp_insert.lua 파일로 쓰기 테스트를 한 경우는 아래와 같은 결과가 나왔습니다.

    transactions:                        56036  (5602.54 per sec.)
    queries:                             56036  (5602.54 per sec.)  // 초당 5,602 개의 write 쿼리가 실행되었습니다.

 

(결과3)

oltp_delete.lua 파일로 삭제 테스트를 한 경우는 아래와 같은 결과가 나왔습니다.

    transactions:                        87458  (8744.05 per sec.)
    queries:                             87458  (8744.05 per sec.)  // 초당 8,744 개의 records 를 삭제 하였습니다.

 


5. 테스트 데이터 삭제

테스트를 마쳤으면 용량 확보를 위해 테스트 데이터를 삭제 합니다.

# sysbench \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-socket=/tmp/mysql.sock \
--mysql-user=root \
--mysql-password=12345678 \
--mysql-db=test \
--table-size=1000000 \
--tables=5 \
/usr/share/sysbench/oltp_read_only.lua \
cleanup

(결과)
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Dropping table 'sbtest1'...
Dropping table 'sbtest2'...
Dropping table 'sbtest3'...
Dropping table 'sbtest4'...
Dropping table 'sbtest5'...

테스트 DB 도 같이 삭제해 줍니다.

 

mysql> drop database test;
Query OK, 0 rows affected (0.01 sec)

 

 

반응형

댓글()

PHP 에서 SQL Injection 방지 쿼리 사용법 두가지 (bind_param, PDO)

프로그래밍/PHP|2022. 8. 30. 11:25
반응형

PHP 에서는 MySQL DB 데이터 입력 또는 조회시 SQL Injection 공격을 막기 위한 방법으로

bind_param 또는 PDO 방식을 사용 할 수 있습니다.

 

 

1. bind_param 사용하기

 

1) INSERT, UPDATE, DELETE

값을 출력하지 않아도 되는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$conn = mysqli_connect($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_NAME);

// 쿼리 준비
$stmt = $conn->prepare("INSERT INTO item (id, itemA, itemB) VALUES (?, ?, ?)");

// 데이터 준비
$id = "hero";
$itemA = "sword";
$itemB = "shield";

// 데이터 바인딩
$stmt->bind_param('sss', $id, $itemA, $itemB); // 대체될 데이터 세개 (하단 '참고' 확인)

// 쿼리 실행
$stmt->execute();

// 연결 종료
$stmt->close();
$conn->close();
?>

* 참고 : 바인딩 할때 변수 데이터 형식을 정의 하게 되는데, 아래 네가지 종료가 있습니다.

i : 정수

s : 문자열

d : double

b : BLOB

 

2) SELECT

값을 출력하는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$conn = mysqli_connect($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_NAME);

// 쿼리 준비
$stmt = $conn->prepare("SELECT * FROM item WHERE id=? or id=?");

// 데이터 준비
$var1 = "hero";
$var2 = "hero2";

// 데이터 바인딩
$stmt->bind_param('ss', $var1, $var2); // 대체될 데이터 두개

// 쿼리 실행
$stmt->execute();

// 모든 행의 결과를 출력
$result = $stmt->get_result();
while ($data = $result->fetch_assoc()) {
    echo $data['id'] . " / " . $data['itemA'] . " / " . $data['itemB'] . "<br>";
}

// 연결 종료
$stmt->close();
$conn->close();
?>

 

 

2. PDO 사용하기

 

1) INSERT, UPDATE, DELETE

값을 출력하지 않아도 되는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME", $DB_USER, $DB_PASSWORD);

//쿼리 준비
$stmt = $pdo->prepare("INSERT INTO item (id, itemA, itemB) VALUES (:id, :itemA, :itemB)");

// 데이터 바인딩
$stmt->bindValue(":id", "hero");
$stmt->bindValue(":itemA", "sword");
$stmt->bindValue(":itemB", "shield");

// 쿼리 실행
$stmt->execute();

// 연결 종료
$stmt->close();
$pdo->close();
?>

 

2) SELECT

값을 출력하는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME", $DB_USER, $DB_PASSWORD);

//쿼리 준비
$stmt = $pdo->prepare("SELECT * FROM item WHERE id=:id");

// 데이터 바인딩
$stmt->bindValue(":id", "hero");

// 쿼리 실행
$stmt->execute();

// 모든 행의 결과를 출력 (한개의 행 또는 한개의 컬럼 등 가져오는 방식은 추가 검색 권고)
$stmt->setFetchMode(PDO::FETCH_ASSOC);  // 추가 설명 아래 '참고' 확인
while ($row = $stmt->fetch()) {
    echo $data['id'] . " / " . $data['itemA'] . " / " . $data['itemB'] . "<br>";
}

// 연결 종료
$stmt->close();
$pdo->close();
?>

* 참고 : 데이터 출력 방식

fetch(PDO::FETCH_BOTH) - 숫자 인덱스와 명명된 인덱스가 있는 배열 입니다.
fetch(PDO::FETCH_ASSOC) - 행은 명명된 인덱스가 있는 배열입니다. ex) $row['itemA']
fetch(PDO::FETCH_NUM) - 행은 숫자 인덱스가 있는 배열입니다. ex) $row[0]

 

 

반응형

댓글()

Rocky Linux 8.6 에서 MySQL 8.0.30 소스 설치하기 (with InnoDB 이노디비 설정)

리눅스/MySQL|2022. 8. 11. 13:09
반응형

1. 필수 패키지 설치

 

# dnf -y update
# dnf -y install cmake ncurses-devel gcc* openssl openssl-devel libtirpc-devel
# dnf -y install epel-release
# dnf config-manager --set-enabled powertools
# dnf -y install rpcgen

 

작업이 잘 수행 되도록 아래 명령 실행 하고, 서버 부팅시에도 selinux 비활성화를 위해 설정을 수정해 줍니다.

# setenforce 0

# vi /etc/selinux/config

SELINUX=disabled 

 

 

2. MySQL 계정 추가

 

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

 


3. MySQL 설치

 

# cd /usr/local/src
# wget https://ftp.kaist.ac.kr/mysql/Downloads/MySQL-8.0/mysql-8.0.30.tar.gz
# tar xvfz mysql-8.0.30.tar.gz
# cd mysql-8.0.30
# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 -DWITH_SSL=system -DMYSQL_TCP_PORT=3306 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_COLLATION=utf8_general_ci -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/include/boost -DFORCE_INSOURCE_BUILD=1
# make
# make install

 

 

4. MySQL 환경 설정

 

환경 설정 파일이 없어도 아래 '5번 항목' 에서 기본 DB 생성 후 MySQL 구동은 가능하지만

my.cnf 파일을 생성하면 서버 사양 및 운영 방식에 알맞게 환경을 조정할 수 있습니다.

아래는 InnoDB 구성을 위한 예 입니다.


# vi /etc/my.cnf

[client]
default-character-set = utf8


[mysqld]
#################### 일반 서버 설정 ####################
# 서버 순번
server-id = 1
# 기본 엔진 설정
default-storage-engine = InnoDB
# 역 DNS 검색 비활성
skip-name-resolve
# 최대 클라이언트 연결 개수
max_connections = 1024
# 다쓴 쓰레드를 스레드풀에 저장할 갯수
thread_cache_size = 50
# 커넥션 최대 대기시간(초)
wait_timeout = 28800
# 정렬에 필요한 버퍼의 크기 ORDER BY 또는 GROUP BY 연산 속도와 관련
sort_buffer_size = 512K
# 캐릭터셋
collation-server = utf8_unicode_ci
character-set-server = utf8
skip-character-set-client-handshake

############# InnoDB 설정 (메모리 8G 기준) #############
# 테이블 단위로 테이블스페이스 할당, 활성시 확장자 .ibd 파일이 생성됨
innodb_file_per_table = 1
# innodb 홈디렉터리 경로
innodb_data_home_dir = /usr/local/mysql/data
# 파일명 : 초기용량 : 자동증가 : 최대사이즈 (파일 재생성 할때 사용)
#innodb_data_file_path = ibdata1:1024M:autoextend
# 테이블 스페이스 자동 확장시 크기
innodb_autoextend_increment = 100
innodb_log_group_home_dir = /usr/local/mysql/data
# 데이터와 인덱스를 캐시하기 위해 사용하는 메모리 버퍼크기
# 서버에 MySQL만 실행한다면, 물리메모리의 50~80%를 지정
innodb_buffer_pool_size = 5G
# Redo 로그 버퍼크기
innodb_log_buffer_size = 16M

# 로그 파일 한 개의 크기로 보통 buffer_pool 사이즈의 10%를 지정
# 크기가 클 수록 체크포인트가 덜 발생해 디스크 I/O를 줄이지만,
# 디비가 크래시 났을 경우 복구 타임이 길어진다.
innodb_log_file_size = 512M

# 커밋 로그 옵션으로 성능 최적화에 사용
# 1 : 트랜젝션 실행할때마다 redo 로그 파일에 기록되고 디스크 플러시가 실행 (default 값)
# 2 : 트랜젝션의 양은 상관없이 flush 가 1초에 한번씩만 수행되기 때문에 매번 flush 되는 기본값보다 IO 성능이 월등히 좋아지지만
#     단점은 데이터를 유실할 가능성이 있다는 점 (예: flush 되기 전 1초 이내 셧다운)
# 0 : 2와 동일하나 OS buffer 를 거치는 부분이 제외되어 더 빠름. 데이터 유실 가능성은 동일.
# 설명 : 서버가 죽었을때 1~2초 정도의 데이터를 버릴수 있을 정도의 상황이라면 0 또는 2 를 선택
#        커밋된 데이터는 무조건 살려야만 한다면 반드시 1 을 선택
innodb_flush_log_at_trx_commit = 1

# InooDB내에 쓰레드 갯수, 변수 0은 쓰레드간 동시성 비활성화
innodb_thread_concurrency = 0
# 롤백이 진행되기 전에 LOCK을 대기하는 시간(초)
innodb_lock_wait_timeout = 20
# 크래시 복구 모드 설정
innodb_force_recovery = 0
# 성능을 위해 메모리에서 직접 액세스 하도록 설정
innodb_flush_method = O_DSYNC

# O_DIRECT=운영체제의 버퍼를 사용 않고 IO 실행, RAID 컨트롤러(캐시메모리 장착된)가 없거나 SAN 사용시 O_DIRECT를 사용 하지 않음
# 이중 쓰기 버퍼 비활성
innodb_doublewrite = 0
# 쓰레드가 지연되기 전에 (suspended) 풀어 주기 위해 InnoDB 뮤텍스 (mutex) 를 기다리는 쓰레드의 대기 시간
innodb_sync_spin_loops = 20
# LOCK TABLES 은 AUTOCOMMIT=0 경우에, InnoDB로 하여금 내부적으로 테이블을 잠금
innodb_table_locks = 1
# InnoDB 큐를 조이닝 (joining) 하기 전에 InnoDB 쓰레드가 일시 정지 (sleep) 하는 시간
innodb_thread_sleep_delay = 1000
# 퍼지 연산 (purge operation)이 래깅 (lagging) 될 때 INSERT, UPDATE 및 DELETE 연산을 지연 시키는 방법을 제어
# 디폴트값 0 일시 지연 없음
innodb_max_purge_lag = 0
# 동시에 실행되는 쓰레드의 숫자. 이 값이 0이 되면 동시성 제어 (concurrency control) 가 비활성화
innodb_commit_concurrency = 0
# InnoDB에 동시에 들어갈 수 있는 쓰레드의 숫자는 innodb_thread_concurrency 변수로 알아볼 수가 있다.
# 여러 개의 쓰레드가 이미 컨커런시 한계에 도달하였다면, 하나의 쓰레드만이 큐에 들어갈 수 있다.
# 하나의 쓰레드가 InnoDB에 들어가게 되면, innodb_concurrency_tickets의 값과 일치하는 "자유 티켓"의 숫자가 주어지고
# 쓰레드가 자신의 티켓을 사용하기 전 까지는 자유롭게 InnoDB에 들어가고 나올 수가 있다.
# 이런 후에는, 쓰레드는 다시금 일관성 검사를 하고 InnoDB에 다시 들어가려고 시도하게 된다
innodb_concurrency_tickets = 500
# 개발 방식에 따라 sql_mode 적용. MySQL 8 기본값 : ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
#sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION


#################### 바이너리 로그 #####################
# 바이너리 로그 파일 (binlog.xxxx 형태의 파일 생성. 경로 추가 가능)
#skip-log-bin
log-bin = binlog
# 파일당 최대 사이즈
max_binlog_size = 1G

##################### 제네럴 로그 ######################
# 제네럴 로그 사용 여부 (0: 비활성, 1: 활성)
general_log = 1
# 제네럴 로그 파일
general_log_file = /usr/local/mysql/data/general_query.log


################### 슬로우 쿼리 로그 ###################
# 슬로우 로그 사용 여부 (0: 비활성, 1: 활성)
slow-query-log = 1
# 슬로우 쿼리를 구분하는 소요 시간 (초)
long_query_time = 10
# 슬로우 로그 파일
slow_query_log_file = /usr/local/mysql/data/slow_query.log


[mysqldump]
default-character-set = utf8


[mysql]
default-character-set = utf8

* 옵션 설명은 아래 URL 참고

https://yakolla.tistory.com/61

https://bae9086.tistory.com/175 

https://systemv.tistory.com/48

 

 

5. MySQL 초기 데이터 베이스 생성 및 권한 설정

 

생성해두었던 my.cnf 파일을 읽어 환경에 맞게 기본 DB 를 생성합니다.

 

# /usr/local/mysql/bin/mysqld --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql
# chown -R mysql.mysql /usr/local/mysql/
# chmod 711 /usr/local/mysql
# chmod 700 /usr/local/mysql/data
# chmod 751 /usr/local/mysql/bin/
# chmod 750 /usr/local/mysql/bin/*
# chmod 755 /usr/local/mysql/bin/mysql
# chmod 755 /usr/local/mysql/bin/mysqldump

 


6. MySQL 구동

 

데몬 구동을 쉽게 하기 위해 명령어를 복사하고, 서버 부팅시 자동으로 데몬이 구동 되도록 설정합니다.

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

# /etc/init.d/mysqld start

 


* 이후 작업 (필요에 따라 설정)

 

1) mysql 명령을 경로에 상관없이 사용하도록 설정 추가

# vi /etc/profile

PATH="$PATH:/usr/local/mysql/bin"

# source /etc/profile

 

2) firewalld 방화벽 설정 (서버 외부에서 DB 바로 접근 필요시)

# firewall-cmd --zone=public --add-port=3306/tcp

 

3) MySQL root 패스워드 업데이트

mysql> use mysql;

mysql> alter user root@localhost identified by 'NEWPASSWD';

mysql> flush privileges; 

 

4) 새 계정 추가

mysql> create database sysdocudb;

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

 

반응형

댓글()

MySQL 테이블별 용량 및 레코드 수 조회하기

리눅스/MySQL|2022. 8. 9. 09:16
반응형

아래와 같은 쿼리로 특정 DB 의 테이블별 용량 및 레코드 수를 조회할 수 있습니다.

모든 DB 의 테이블별로 조회를 하고자 할 경우 아래 파란색 부분을 제외하면 됩니다.

 

mysql> SELECT table_name, (data_length + index_length)/1024/1024 AS total_mb, table_rows FROM information_schema.TABLES WHERE table_schema='sysdocu';

 

[결과]

+------------+------------+------------+
| table_name | total_mb   | table_rows |
+------------+------------+------------+
| contents   | 0.50000000 |       4126 |
| sites      | 0.01562500 |         10 |
+------------+------------+------------+
3 rows in set (0.001 sec)

 

반응형

댓글()

xtrabackup 을 이용한 MySQL 8.0.28 Replication 구성하기

리눅스/MySQL|2022. 7. 28. 09:39
반응형

percona-xtrabackup 패키지는 MySQL 또는 MariaDB 서버의 서비스 중지 없이 Replication 을 구성하기 위한 명령어 입니다.

아래 내용은 CentOS 8 환경에서 MySQL 8.0.28 버전으로 테스트 하였습니다.

사용자 계정이나 패스워드, 디렉토리 등은 사용자 환경에 따라 다르므로 명령 실행시 확인 후 실행하시기 바랍니다.

- master 서버 : 192.168.10.2

- slave 서버 : 192.168.10.3

- 참고1 : xtrabackup 8.0 미만 버전에서는 innobackupex 라는 명령이 있었으나

              xtrabackup 8.0 버전부터 xtrabackup 명령으로 통합되었습니다.

- 참고2 : 설치된 패키지 버전을 자세히 보면 지원하는 DB 버전을 알 수 있습니다.

              percona-xtrabackup-80-8.0.28 은 MySQL 8.0.28 버전까지 백업이 가능합니다.

- 참고3: percona-xtrabackup 패키지는 MySQL 과 MariaDB 둘 다 가능합니다. 다만 설치 버전에 따라 지원가능한 DB 버전이 다르며 MySQL 은 xtrabackup, MariaDB 는 mariabackup 이라는 명령을 사용하는것이 큰 차이점 입니다.

(redo 로그를 기록하는 파일이 다름)

 

- LINK : mariabackup 을 이용한 MariaDB 10.6.9 Replication 구성하기

 

1. 설치

 

(인터넷 연결 가능할 경우)

master 서버와 slave 서버에 xtrabackup 을 설치 합니다.

# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

# yum -y install percona-xtrabackup-80

 

(인터넷 연결 불가의 경우)

사설망에서 DB를 운영할 경우 서버에 없는 패키지는 설치 파일을 다운 받아 복사하여 설치하면 됩니다.

서버 환경에 따라 필요한 패키지가 다를 수 있으며 이는 아래 rpm 명령으로 의존성 확인이 가능합니다.

 

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/libev-4.24-6.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/perl-DBI-1.641-1.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/rsync-3.1.3-12.el8.x86_64.rpm

# wget https://repo.percona.com/yum/release/8/RPMS/x86_64/percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm 

 

필요한 패키지를 다운로드 한 후 DB 서버로 옮깁니다. (scp 또는 rsync 등으로 복사하면 됩니다. 방법은 생략)

그리고 아래 순서에 따라 설치합니다.

 

# rpm -ivh libev-4.24-6.el8.x86_64.rpm

# rpm -ivh perl-DBI-1.641-1.el8.x86_64.rpm

# rpm -ivh perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# rpm -ivh rsync-3.1.3-12.el8.x86_64.rpm

# rpm -ivh percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm

 

2. 원본 데이터 백업

 

(master 서버에서)

# xtrabackup --defaults-file=/etc/my.cnf --user=root --password=12345678 --backup --target-dir=/xtrabackup --no-lock --port=3306 --socket=/tmp/mysql.sock

 

백업이 완료되면 /xtrabackup 디렉토리가 생성되며 하단에 백업 파일들이 존재하게 됩니다.

data 디렉토리 내 파일들과 xtrabackup 관련된 로그가 있습니다.

 

3. 데이터 이전

 

(master 서버에서)

master 서버에 백업된 데이터를 slave 서버로 복사합니다.

# rsync -avzPog /xtrabackup root@192.168.10.3:/

 

4. 데이터 복원

 

(slave 서버에서)

mysqld 데몬을 중지하고 기존 data 디렉토리를 삭제 합니다. (mv 명령으로 디렉토리 이름 변경 권장)

가져온 데이터를 복구하는 과정에서 기존 data 디렉토리내 파일이 있으면 실행이 되지 않기 때문입니다.

 

백업중 작성된 redo 로그를 데이터에 적용합니다.

# xtrabackup --prepare --target-dir=/xtrabackup

 

> --use-memory=10G 와 같이 본 작업에 사용할 시스템 메모리양을 어느정도 할당 해주면 빠른처리가 가능합니다.

> redo 로그 적용 도중에 아래와 같은 에러 메세지가 출력 될 경우 --innodb_force_recovery=1 옵션을 추가 합니다.

2022-10-14  8:47:54 0 [Note] InnoDB: Set innodb_force_recovery=1 to ignore corrupted pages.
2022-10-14  8:47:54 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
[00] FATAL ERROR: 2022-10-14 08:47:54 xtrabackup: innodb_init() returned 11 (Generic error).

하지만 백업 과정에서 문제가 생겼을 수 있으므로 master 서버에서 몇 번 더 백업을 반복 시도해 보는것도 좋습니다.

 

백업 파일을 이동합니다. (--copy-back 를 사용하면 복사)
# xtrabackup --move-back --datadir=/usr/local/mysql/data --target-dir=/xtrabackup

 

root 로 복원하였기 때문에 복원된 파일의 권한이 root 로 되어 있습니다.

mysql 가동을 위해 data 디렉토리의 권한을 설정을 합니다.

# chmod 755 /usr/local/mysql/data
# chown mysql.mysql -R /usr/local/mysql/data

# systemctl start mysqld

 

5. 로그 포지션 설정 및 동기화 시작

 

백업본의 xtrabackup_binlog_info 에 있는 mysql-bin 파일명과 position 값 참고하여
replication 을 적용합니다.

 

(slave 서버에서)

# cat /usr/local/mysql/data/xtrabackup_info |grep binlog_pos

binlog_pos = filename 'binlog.000004', position '156'    // 출력된 내용을 참고

 

# mysql -p

mysql> stop slave;

mysql> reset slave;

mysql> change master to master_host='192.168.10.2', master_user='repl',
master_password='12345678', master_log_file='binlog.000004',
master_log_pos=156;

mysql> start slave;

 

정상적으로 동기화 된 것을 확인할 수 있습니다.

mysql> show slave status \G;

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

 

6. 과정 테스트

 

서비스 사용중 (무정지) 데이터 유실 없이 리플리케이션이 되는지 확인하기 위해 테스트를 진행했습니다.

1) master 서버 테이블에 1,000개의 레코드를 넣은 상태에서

2) 추가로 1,000개의 레코드를 입력하는 스크립트를 가동하고

3) 레코드가 입력되는 중에 xtrabackup 을 수행했습니다.

4) 1,000개의 레코드 입력이 완료되면 (계속 진행되어도 상관없음) slave 로 데이터를 넘겨서

5) --prepare 옵션으로 실행해주면 로그가 데이터에 적용되는것이 백분율로 보였고

6) 그 데이터를 --copy-back 하여 서비스할 위치로 복사하고 replication 포지션을 맞추고 연동하니

7) slave 서버에도 최종 2,000개의 레코드가 확인되었습니다.

 

반응형

댓글()