달빛궁전/테슬라(차량)

TeslaMate (테슬라메이트) 데이터 복원 스크립트

달빛궁전- 2025. 11. 6. 10:30

TeslaMate는 DB로 PostgreSQL을 사용합니다. 이전 포스팅에서는 Teslamate에서 사용되는 PostgreSQL 데이터베이스의 백업을 원하는 시간에 자동으로 백업받고, Gmail을 통해 원하는 메일로 전송하는 스크립트를 작성했습니다. 이번에는 위의 스크립트로 백업받은 파일을 복원하는 스크립트를 작성하였습니다.

 

 

자동 데이터 백업 스크립트는 아래링크를 참조하세요.
 
 
  • 사용방법
본 문서에 첨부된 쉘스크립트 파일을 다운 받아 업로드 하거나, 아래 소스코드를 복사하여 테슬라메이트가 설치된 서버에 접속하여 파일을 붙여넣기 합니다.
 
실행은 “bash 스크립트명.sh “ 와 같이 할 수 있습니다.
 

 
도커를 검색하여, database 이름이 있는 도커를 추천해줍니다.
다른이름으로 헀다면, 직접입력합니다.
이후 사용자 이름과, 데이터베이스이름, 비밀번호를 입력해줍니다.
처음 기본스크립트로 실행했다면, 기본 값으로 실행해도 무방합니다.
마지막으로 중요한 백업파일을 입력해줍니다.
쉘스크립트 파일이 있는 디렉토리에 백업파일이 있다면 “백업파일 이름"만 지정해주면 되며
다른경로에 존재한다면 절대경로 (예시 : /home/user/backup.sql.gz)를 입력해야합니다.
 

이후 기존 데이터베이스를 삭제하고, 신규로 생성합니다.
나오는 메시지들은 무시하셔도 됩니다. 
화면에 안보이게 할려다가.. 음 잔잔바리 일이 많아져서 그냥 냅뒀습니다 ㅎㅎ
 

 
복원이 끝나면 아래와 같은 안내메시지가 나옵니다.
Web (그라파나)은 패스워드 복원이 안되서, 기본 값인 admin/admin으로 접속해야 됩니다.
 
아래 소스코드를 다운받거나, 아래를 소스코드를 복사, 붙여넣기 하여 사용하시면 됩니다.

 

restore_teslamate.sh
0.01MB

소스코드

#!/bin/bash
================================================================
# 도커 PostgreSQL 데이터 복원 스크립트 (자동 감지 & DROP/CREATE 방식 적용)# 
# 작성자: Choi Seonggi <linux1547@hanmail.net>
# 블로그: https://seonggi.kr
# 버전: 1.0
# 설명글 : https://seonggi.kr/293
# 설명: Teslamate에서 사용되는 PostgreSQL 데이터베이스의 백업을 받은 후 복원하는 스크립트 입니다.
# 
# 실행 방법: bash restore_teslamate.sh
# ================================================================
===============================================================
# 1. 초기 설정 및 로깅
# ===============================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() {
    printf "${GREEN}[INFO]${NC} %s\n" "$1"
}
log_error() {
    printf "${RED}[ERROR]${NC} %s\n" "$1"
}
log_warn() {
    printf "${YELLOW}[WARN]${NC} %s\n" "$1"
}

# SQL 명령을 컨테이너에서 실행하는 헬퍼 함수
run_sql_command() {
    local SQL_COMMAND="$1"
    local DB_TO_CONNECT="postgres" # 관리 명령은 보통 postgres DB에 연결하여 실행

    docker exec -i --user postgres -e PGPASSWORD="$PG_PASSWORD" "$PG_CONTAINER_NAME" \
        psql -U "$PG_USER" -d "$DB_TO_CONNECT" -c "$SQL_COMMAND" 2>> /dev/null
    
    return $?
}

# ===============================================================
# 2. 사용자 입력 받기 (컨테이너 자동 감지)
# ===============================================================
echo "--- PostgreSQL 데이터 복원 스크립트 시작 ---"

# 2.1. Docker 컨테이너 이름 자동 감지 및 입력
echo "--- Docker 컨테이너 확인 ---"

# 'postgres', 'database', 'db' 등을 포함하는 실행 중인 컨테이너 이름 목록 추출
RECOMMENDED_CONTAINER=$(docker ps --format "{{.Names}}" | grep -E 'postgres|database|db|pgsql' | head -n 1)

if [ -n "$RECOMMENDED_CONTAINER" ]; then
    log_info "💡 추천 컨테이너 이름: [$RECOMMENDED_CONTAINER]"
    read -p "복원할 DB 도커 컨테이너 이름 (추천값으로 Enter): " PG_CONTAINER_NAME_INPUT
    PG_CONTAINER_NAME=${PG_CONTAINER_NAME_INPUT:-$RECOMMENDED_CONTAINER}
else
    log_warn " PostgreSQL 관련 컨테이너를 찾을 수 없습니다."
    read -p "복원할 DB 도커 컨테이너 이름을 수동으로 입력하세요: " PG_CONTAINER_NAME
fi

# 2.2. DB 접속 정보 입력
DEFAULT_DB_USER="teslamate"
read -p "PostgreSQL 사용자 이름 (기본값: $DEFAULT_DB_USER): " PG_USER_INPUT
PG_USER=${PG_USER_INPUT:-$DEFAULT_DB_USER}

DEFAULT_DB_NAME="teslamate"
read -p "복원할 데이터베이스 이름 (기본값: $DEFAULT_DB_NAME): " PG_DB_NAME_INPUT
PG_DB=${PG_DB_NAME_INPUT:-$DEFAULT_DB_NAME}

echo "PostgreSQL 사용자 비밀번호를 입력해주세요."
read -s -p "비밀번호: " PG_PASSWORD
echo

# 2.3. 백업 파일 전체 경로 입력
echo "--- 복원 파일 경로 입력 ---"
read -p "복원할 .sql.gz 파일의 전체 경로를 입력하세요: " FULL_PATH

if [ -z "$FULL_PATH" ]; then
    log_error "파일 경로를 입력해야 합니다. 복원을 취소합니다."
    exit 1
fi

# 파일 존재 여부 확인
if [ ! -f "$FULL_PATH" ]; then
    log_error "지정된 경로에 파일을 찾을 수 없습니다: $FULL_PATH"
    exit 1
fi

# 요약 정보 출력
echo "-----------------------------------"
log_info "복원 대상 컨테이너: $PG_CONTAINER_NAME"
log_info "복원 대상 DB: $PG_DB (사용자: $PG_USER)"
log_info "복원 파일 경로: $FULL_PATH"
echo "-----------------------------------"

# 사용자에게 최종 확인
printf "${RED} 경고: ${PG_DB} 데이터베이스가 완전히 삭제되고 새 데이터로 덮어쓰여집니다. 계속하시겠습니까? (y/N): ${NC}"
read CONFIRM

if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then
    log_warn "사용자가 복원을 취소했습니다."
    exit 0
fi

# ===============================================================
# 3. 데이터베이스 초기화 (DROP & CREATE) - 연결 강제 종료
# ===============================================================
log_warn "기존 ${PG_DB} 데이터베이스를 삭제하기 위해 활성 연결을 종료합니다..."

# 1. 활성 연결 종료 (DROPDB가 실패하지 않도록 보장)
TERMINATE_SQL="SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$PG_DB' AND pid <> pg_backend_pid();"

if run_sql_command "$TERMINATE_SQL"; then
    log_info "활성 연결이 성공적으로 종료되었습니다."
else
    log_warn "활성 연결 종료 중 오류가 발생했습니다. (DB가 존재하지 않을 수 있음)."
fi

# 2. DB 삭제 (dropdb)
log_info "기존 데이터베이스 (${PG_DB}) 삭제 중..."
docker exec -i --user postgres -e PGPASSWORD="$PG_PASSWORD" "$PG_CONTAINER_NAME" \
    dropdb -U "$PG_USER" "$PG_DB" 2>/dev/null

DROP_STATUS=$?
if [ $DROP_STATUS -ne 0 ]; then
    log_warn "DROPDB가 오류를 반환했습니다. (DB가 이미 삭제되었거나 컨테이너 문제). 계속 진행합니다."
fi

# 3. DB 재생성 (createdb)
log_info "데이터베이스 (${PG_DB}) 재생성 중..."
docker exec -i --user postgres -e PGPASSWORD="$PG_PASSWORD" "$PG_CONTAINER_NAME" \
    createdb -U "$PG_USER" "$PG_DB"

CREATE_STATUS=$?
if [ $CREATE_STATUS -ne 0 ]; then
    log_error " 데이터베이스 재생성에 실패했습니다. 접속 정보 및 권한을 확인하세요."
    exit 1
fi
log_info "데이터베이스 (${PG_DB}) 재생성 완료."

# ===============================================================
# 4. 데이터 복원 실행
# ===============================================================

log_info "데이터 복원 시작 (압축 해제 후 파이프 전달)..."
log_warn "복원 중... 완료 후 결과가 나타납니다."

gunzip -c "$FULL_PATH" | \
docker exec -i --user postgres -e PGPASSWORD="$PG_PASSWORD" "$PG_CONTAINER_NAME" \
    psql -U "$PG_USER" -d "$PG_DB" -f -

RESTORE_STATUS=$?

# ===============================================================
# 5. 결과 확인 및 정리
# ===============================================================

if [ $RESTORE_STATUS -eq 0 ]; then
echo "=========================================================="
echo "데이터베이스 복원 성공"
echo "Web (그라파나) 접속의 ID/Password는 기본인 admin/admin 으로 접속가능합니다."
echo "로그인 후 필히 ID, Password를 변경하세요."
echo "# 문의사항이나 개선사항은 linux1547@hanmail.net을 통해 연락 주세요. "
echo " 제작자 : 최성기 ( https://seonggi.kr ) "
echo "=========================================================="

else
    log_error "==============================================="
    log_error " 데이터베이스 복원 실패 (Status: $RESTORE_STATUS)"
    log_error "백업 파일에 문제가 있거나 DB 연결에 오류가 발생했습니다."
    log_error "컨테이너 로그를 확인하세요: docker logs $PG_CONTAINER_NAME"
    log_error "==============================================="
fi

echo "--- 스크립트 종료 ---"

 

 
반응형