0. 개요
AWS에서 RDS를 사용할 뿐만 아니라 로컬 서버에서 MySQL을 돌리는데
MySQL 전용 로컬 서버 용량이 100% 차서 뻗어버렸다.
새 하드를 박아서 이전하려고 했는데, 100% 차면 명령어도 안먹히더라.
이런 상황에서 MySQL 저장소 위치를 이전하는 방법을 알아보자.
1. 데이터 제거
일단 작동을 위해 필요없는 데이터 조금 지워보는 것 부터 시작하자.
MySQL에서 Delete는 용량을 줄여주지 않는다.
delete 를 commit한 뒤 optimize까지 해줘야 용량이 줄어드는데, TB 단위의 optimize는 진짜 한 세월이다.
DROP과 TRUNCATE를 이용해 전체 용량의 2%정도만 확보하자.
(1) DROP
테이블 자체를 삭제한다.
DROP TABLE 테이블명;
mysql 의 datadir 에서 테이블 폴더 자체가 사라진다.
당연히 용량이 확보된다.
(2) TRUNCATE
테이블에 있는 모든 데이터를 삭제한다.
TRUNCATE TABLE 테이블명;
일부 데이터만 삭제하기 위한 where, having 등은 사용할 수 없다.
테이블의 형식은 남겨놓기 때문에 추후 사용할 일 있으면 TRUNCATE 써야한다.
2. MySQL 의 datadir 확인
하드 교체 전 지금 MySQL 서버가 데이터를 어디에 저장하고 읽어오는지 알아야한다.
다음 SQL 문을 사용해 볼 수 있다.
SELECT @@datadir;
만약 mysql에 접속할 수 없으면 서버 쉘에서 다음과 같이 입력해서 볼 수 있다.
cat /etc/my.cnf | grep "datadir"
해당 결과 경로를 잘 기억해놓자.
율무의 경우 /mnt/storage_mysql_2019 다.
3. 새 디스크 인식
(1) 디스크 설치
서버를 잠깐 꺼놓고 하드를 끼운뒤 부팅한다.
(2) 정보 확인
df -h # 마운트 되어있는 디스크의 용량 정보를 보여준다.
fdisk -l # 마운트와 관계 없이 메인보드에 연결되어있는 디스크의 정보를 보여준다.
정상적인 경우 df -h 에는 정보가 나타나지 않고, fdisk -l 에는 정보가 나타날 것이다.
해당 디바이스 심볼릭 링크를 기록해놓자. 보통은 /dev/sdx (x는 알파벳) 이다.
율무의 경우 /dev/sdc 다.
(3) 디스크 설정, 포맷
디스크의 파티션, 파일시스템 형식 등을 설정한다.
1) 2TB 이하의 파티션을 설정하고자 하는 경우
fdisk /dev/sdc # (2) 에서 기록해놓은 디스크 디바이스
fdisk 명령어를 통해 디스크 파일시스템 설정에 들어간 뒤 다음 순서를 따라 파티션을 설정한다.
- d 옵션 : 기존 파티션 해제
- n 옵션 : 파티션 설정
- p : 파티션 개수 설정
- 1 : 파티션 1개
- enter : 시작 주소 (기본 : 0)
- enter : 끝 주소 (기본 : min(디스크 크기, 2TB))
- w : 설정 저장
다르게 설정하고 싶으면 각 명령어의 설명을 참고하면 된다. m을 입력하면 명령어 별 자세한 설명을 볼 수 있다.
2) 2TB 이상의 파티션을 설정하고자 하는 경우
HDD를 사용해서 DB서버를 만들면 보통 이 방식을 사용한다.
parted /dev/sdc # (2) 에서 기록해놓은 디스크 디바이스
mklabel gpt
unit TB
mkpart mysql 0.00TB 6.00TB
print
quit
parted 명령어를 통해 디스크 파일시스템 설정에 들어간 뒤 다음 순서를 따라 파티션을 설정한다.
- mklabel gpt : 파티션 형식(헤더)을 GPT 로 설정
- unit TB : 테라바이트 단위임을 나타냄
- mkpart my_disk 0.00TB 4.00TB : 0~4TB의 파티션 이름을 my_disk 로 설정
- print : 확인
- quit : 종료
(4) 포맷
1) 파티션 확인
lsblk 명령어를 통해 설정한 파티션 정보를 볼 수 있다.
위와 같이 설정한 경우 /dev/sdc 아래에 /dev/sdc1 노드가 생성된다.
아래 포맷은 파티션을 기준으로 해야한다.
2) 파티션 포맷
mkfs.ext4 /dev/sdc1
# mkfs -t ext4 /dev/sdc1
mkfs 명령어를 통해 ext4 형식으로 /dev/sdc1 파티션을 포맷하겠다는 말이다.
형식은 아주아주 많으나 대부분의 서버는 리눅스에서 돌아가므로 CentOS, Ubuntu 환경에서는 ext4 로 하면 된다.
(5) 마운트
위 파티션을 적당한 경로에 마운트한다
율무는 기존 datadir 과 비슷한 /mnt/storage_mysql_2020 에 마운트 하였다.
mount /dev/sdc1 /mnt/storage_mysql_2020
(6) 마운트 설정 저장
컴퓨터 재부팅시마다 디스크 디바이스의 이름(/dev/sdc) 이 바뀔 수 있다.
UUID를 이용하여 이런 경우를 방지하자.
1) /dev/sdc1 의 UUID 를 확인
ls -l /dev/disk/by-uuid
blkid
위 두 가지 명령어로 UUID를 확인할 수 있다. 둘 중 하나만 되면 된다.
2) fstab 수정
/etc/fstab 은 리눅스 부팅시마다 불러와져 파일 시스템을 mount 하는 설정을 기록한 곳이다.
CentOS 기준으로 아래와 같은 문구를 추가하면 된다.
UUID=(방금확인한UUID) /mnt/storage_mysql_2020 ext4 defaults 0 1
다른 OS(Fedora, Ubuntu 등)는 조금 다를 수 있으니 눈치껏 하자.
4. 데이터 복사
기존의 mysql 데이터를 옮기고 싶을 때 사용한다.
service mysqld stop
sudo cp -R /mnt/storage_mysql_2019/* /mnt/storage_mysql_2020
sudo chown -R mysql:mysql /mnt/storage_mysql_2020
mysql 데몬을 정지하고
기존 mysql의 datadir인 /mnt/storage_mysql_2019 에 있는 파일을
새로운 파티션을 마운트한 장소인 /mnt/storage_mysql_2020 으로 이동시킨다.
권한 역시 함께 이동시킨다.
데이터를 제외하고 .pem 같은 암호화 키만을 이동시키기 위해선 cp 대신 exclude 옵션을 가진 rsync 명령어를 사용하면 된다.
rsync -ah --info=progress2 --exclude Database/mysql/(Your Database Name) /mnt/storage_mysql_2019 /mnt/storage_mysql_2020
exclude 는 src directory에 대한 상대 경로이므로 주의해야한다.
데이터베이스 여러개를 제외시키고 싶으면 텍스트 파일을 하나 만들어 그 곳에 쓴 뒤 --exclude-from abc.txt 와 같이 쓰면 된다.
5. 기존 하드 데이터 백업
mysql 서버를 돌리는 하드였으므로 mysqldump를 이용해서 백업하면 된다.
# 모든 DB 백업
mysqldump --all-databases -u (username) -p (password) --default-character-set=utf-8 > (save path)/(dump file name).sql
# 단일 DB 백업
mysqldump -u (username) -p (password) (Database Name) > (save path)/(dump file name).sql
# 단일 테이블 백업
mysqldump -u (username) -p (password) (Database Name) (Table Name) > (save path)/(dump file name).sql
복원하고 싶을 경우 화살표 방향을 반대로 (<) 하면 된다.
6. Datadir 변경
새로운 하드를 포맷해서 마운트하고 데이터를 옮기는 작업을 끝냈으니, mysql이 새로운 장소에 데이터를 쌓도록 만든다.
(1) 설정 수정
vi /etc/my.cnf
...
datadir=/mnt/storage_mysql_2020/Database/mysql/
...
!wq
vi로 /etc/my.cnf 를 열어서 (mysql 시작 설정 파일)
datadir를 새로 마운트한 디스크 주소로 설정하고
!wq 로 덮어써서 종료한다.
(2) mysql 재시작 후 정상 작동 확인
보통 데몬으로 돌아가니 그냥 서버를 껐다 켜는 걸 추천한다.