[과제] My SQL 설치 자동화 셸 스크립트(binary) 고도화

강세준·2023년 2월 7일
0

피드백


1. initialize-insecure vs skip-grant-tables

initialize-insecure

MySQL실행 시 루트 계정에 비밀번호 없이 접근 할 수 있는 initialize option이다.

skip-grant-tables

MySQL실행 시 모든 Client들이 인증 과정 없이 MySQL서버에 접근할 수 있다.

skip-grant-table는 모든 Client들이 인증 과정 없이 MySQL서버에 접근할 수 있도록 하는 파라미터이기 때문에 보안적 위험이 커 MySQL 공식 문서에서는 사용을 지양하고 있다.

따라서 현재 skip-grant-tables를 이용해 설치하는 방식을 initialize-insecure방식으로 수정할 필요가 있다.

echo `${user_path}/mysql/bin/mysqld --defaults-file=${user_path}/mysql/my.cnf --initialize-insecure`

2. MySQL 재설치시 Process가 살아 있을 경우 발생할 수 있는 문제

  • 현재 설치 과정에서는 Mysqld가 실행된 상태이기 때문에 종료하고 재 설치할 필요가 있다.
  • kill -9 [PID]를 사용하여 현재 실행되있는 mysqld를 종료하고 재설치를 수행한다.
# 실행중인 mysqld PID 및 mysql port 있는지 확인하고 kill하는 로직
mysql_process_number=`ps | grep mysqld | cut -d "p" -f1 | tr -d " "`
if [ -z ${mysql_process_number} ]; then
	echo "실행중인 mysql 서버가 없습니다."
else
	echo "실행중인 mysql 서버를 발견하여 종료합니다."
	echo `kill -9 ${mysql_process_number}`
fi

mysql_install_port_number=`cat ${user_path}/mysql/my.cnf | grep port | cut -d "=" -f2`
mysql_port_open_count=`netstat -ano | grep ${mysql_install_port_number} | wc -l`
if [ ${mysql_port_open_count} -ge 1 ]; then
	echo "현재 mysql이 설치 된 port를 닫습니다."
	echo `fuser -k ${mysql_install_port_number}/tcp`
    sleep 1 
fi
  • fuser : 지정된 파일 또는 파일 시스템 프로세스 식별을 위해 사용하는 명령어
    • -k : 지정한 파일,디렉토리,소켓의 프로세스를 kill하는 옵션 해당 명령어를 사용하여
      특정 네트워크 포트에 속한 프로세스를 kill할 수 있다. (단 데이터 손실, 오염은 주의해야한다)

3. MySQL 설치시 환경변수 count시 grep mysql은 조건 수정

현재 로직에서는 mysql이라는 단어를 .bashrc에서 검색하는 방식이기 때문에 조금 더 구체적인 조건을 주면 안정성이 올라간다.

  • 따라서 ${userpath}/mysql/bin으로 바꾸어 안정성을 높힌다.
if [ ${mysql_env_count} -gt 0 ]; then
        echo "이미 bashrc 환경변수가 지정되었습니다."
else
        echo `echo "export PATH="\\$"PATH:"${user_path}"/mysql/bin/" >> ${user_path}/.bashrc`
fi

4. 설치 시 포트 번호를 입력받아 설치

  • 다른 포트에서 설치 할 수 있게 끔 사용할 수 있는 포트 번호인지 검사하고 사용할 수 있으면 해당 포트에 설치한다.
# mysql 포트 인자를 입력했는지 확인 및 포트 연결 확인
if [ -z ${port_number} ]; then
	port_number="3306"
	echo "포트 정보를 입력하지 않았음으로 default 포트번호 3306으로 설치를 진행합니다."
fi

install_port_check=`nc -z localhost ${port_number} &>/dev/null && echo ${?}`
if [ -z ${install_port_check} ] || [ ${install_port_check} -ne 0 ]; then
	echo "사용가능한 포트입니다. ${port_number}포트로 설치를 진행합니다."
else
	echo "이미 사용중인 포트입니다. 다른포트를 입력해서 설치 해주세요. 프로그램을 종료합니다."
	exit 2
fi
  • nc(netcat) : TCP or UDP를 사용하여 네트워크 연결을 읽거나 기록하는 도구
    • -z : 데이터를 보내지 않고 스캔만 하는 옵션으로 특정포트가 열려 있는지 확인할 수 있다.
    • & : 명령어를 background에서 실행한다.
  • > /dev/null : /dev/null에 데이터를 리다이렉션 하면 데이터를 출력하지 않는다.
  • $? : 이전 명령어의 종료 상태를 의미한다.
    • 0 = no error happend로 성공했다는 의미이다.

5. 삭제 여부 확인하고 MySQL 삭제

  • MySQL을 재설치 할때 삭제를 할 것인지 물어보는 로직을 넣어두는 것이 안정성에 더욱 도움이 된다.
mysql_count=`find ${user_path}/mysql* | wc -l`
if [ ${mysql_count} -ge 1 ]; then
	# mysql 삭제 여부 확인
	read -p "설치된 MySQL을 삭제하시겠습니까?(y, n) : " delete_flag
	if [ ${delete_flag} == "y" ]; then
		echo `rm -rf ${user_path}/mysql*`
		echo "mysql binary install을 삭제했습니다."
	else
		echo "mysql을 삭제하지 않고 프로그램을 종료합니다."
		exit 3
	fi
fi

6. 값을 넣지 않으면 Default값으로 들어가 설치되게 끔 수정

# mysql 버전 인자를 입력했는지 확인 및 링크 정보 확인
if [ -z ${mysql_version} ]; then
	mysql_version="8.0.32"
	echo "버전 정보를 입력하지 않았음으로 최신 버전으로 설치를 진행합니다."
fi

# mysql 포트 인자를 입력했는지 확인 및 포트 연결 확인
if [ -z ${port_number} ]; then
	port_number="3306"
	echo "포트 정보를 입력하지 않았음으로 default 포트번호 3306으로 설치를 진행합니다."
fi

코드


#!/usr/bin/env bash

mysql_version=${1}
port_number=${2}
user_path="/home/centos"


# psmic library 설치(특정 port Close)
echo `sudo yum -y install psmisc`

# 실행중인 mysqld PID 및 mysql port 있는지 확인하고 kill하는 로직
mysql_process_number=`ps | grep mysqld | cut -d "p" -f1 | tr -d " "`
if [ -z ${mysql_process_number} ]; then
	echo "실행중인 mysql 서버가 없습니다."
else
	echo "실행중인 mysql 서버를 발견하여 종료합니다."
	echo `kill -9 ${mysql_process_number}`
fi

mysql_install_port_number=`cat ${user_path}/mysql/my.cnf | grep port | cut -d "=" -f2`
mysql_port_open_count=`netstat -ano | grep ${mysql_install_port_number} | wc -l`
if [ ${mysql_port_open_count} -ge 1 ]; then
	echo "현재 mysql이 설치 된 port를 닫습니다."
	echo `fuser -k ${mysql_install_port_number}/tcp`
	sleep 1
fi

# mysql 버전 인자를 입력했는지 확인 및 링크 정보 확인
if [ -z ${mysql_version} ]; then
	mysql_version="8.0.32"
	echo "버전 정보를 입력하지 않았음으로 최신 버전으로 설치를 진행합니다."
fi

mysql_folderName="mysql-${mysql_version}-el7-x86_64"

if [ ${mysql_version} != "8.0.32" ]; then
	mysql_connection=`wget --timeout=1 --tries=1 --spider https://downloads.mysql.com/archives/get/p/23/file/${mysql_folderName}.tar.gz 2>&1 | grep 'broken link' | wc -l`
	if [ ${mysql_connection} -ge 1 ]; then
		echo "잘못된 링크입니다. 프로그램을 종료합니다."
		exit 1
	fi
fi

# mysql 포트 인자를 입력했는지 확인 및 포트 연결 확인
if [ -z ${port_number} ]; then
	port_number="3306"
	echo "포트 정보를 입력하지 않았음으로 default 포트번호 3306으로 설치를 진행합니다."
fi

install_port_check=`nc -z localhost ${port_number} &>/dev/null && echo ${?}`
if [ -z ${install_port_check} ] || [ ${install_port_check} -ne 0 ]; then
	echo "사용가능한 포트입니다. ${port_number}포트로 설치를 진행합니다."
else
	echo "이미 사용중인 포트입니다. 다른포트를 입력해서 설치 해주세요. 프로그램을 종료합니다."
	exit 2
fi

# mysql 바이너리 설치 확인 및 삭제 로직
mysql_count=`find ${user_path}/mysql* | wc -l`
if [ ${mysql_count} -ge 1 ]; then
	# mysql 삭제 여부 확인
	read -p "설치된 MySQL을 삭제하시겠습니까?(y, n) : " delete_flag
	if [ ${delete_flag} == "y" ]; then
		echo `rm -rf ${user_path}/mysql*`
		echo "mysql binary install을 삭제했습니다."
	else
		echo "mysql을 삭제하지 않고 프로그램을 종료합니다."
		exit 3
	fi
fi

# MySQL 설치 로직
if [ ${mysql_version} == "8.0.32" ]; then
 # mysql 바이너리 최신버전 설치 로직
	echo `wget https://dev.mysql.com/get/Downloads/MySQL-8.0/${mysql_folderName}.tar.gz`
else
 # mysql 바이너리 구 버전 설치 로직 (아카이브에서 가져옴)
	echo `wget https://downloads.mysql.com/archives/get/p/23/file/${mysql_folderName}.tar.gz`
fi

# mysql 압축해제 및 권한 변경
echo `mv ${mysql_folderName}.tar.gz ${user_path}`
echo `tar -xvf ${user_path}/${mysql_folderName}.tar.gz -C ${user_path}`
echo `sudo yum install -y libaio`
echo `ln -s ${user_path}/${mysql_folderName} ${user_path}/mysql`

# my.cnf parameter 설정
mycnf_parameter=$(cat << EOF
[client]
socket=${user_path}/mysql/mysql.sock
[mysqld]
port=${port_number}
user=centos
socket=${user_path}/mysql/mysql.sock
basedir=${user_path}/mysql
datadir=${user_path}/mysql/data
pid-file=${user_path}/mysql/mysqld.pid
log-error=${user_path}/mysql/mysql-logs/mysqld.log
EOF
)

echo `echo "${mycnf_parameter}" >> ${user_path}/mysql/my.cnf`
echo `mkdir ${user_path}/mysql/data`
echo `mkdir ${user_path}/mysql/mysql-logs`
echo `touch ${user_path}/mysql/mysql-logs/mysqld.log`
echo `ln -s ${user_path}/mysql/mysql.sock /tmp/mysql.sock`

#권한 변경
echo `sudo chown -R centos:centos ${user_path}/${mysql_folderName}`
echo `sudo chown -h centos:centos ${user_path}/mysql`

mysql_env_count=`cat ${user_path}/.bashrc | grep 'mysql' | wc -l`

if [ ${mysql_env_count} -gt 0 ]; then
        echo "이미 bashrc 환경변수가 지정되었습니다."
else
        echo `echo "export PATH="\\$"PATH:"${user_path}"/mysql/bin/" >> ${user_path}/.bashrc`
fi

echo `${user_path}/mysql/bin/mysqld --defaults-file=${user_path}/mysql/my.cnf --initialize-insecure`
echo `${user_path}/mysql/bin/mysqld --defaults-file=${user_path}/mysql/my.cnf &`

결과


profile
데이터를 탐구하는 개발자

0개의 댓글