newdwh2021/ecs/restore-dbdump/src/restore_backup.py
2024-02-26 18:57:42 +09:00

109 lines
4.1 KiB
Python

"""ダンプ復元スクリプト"""
import os
import subprocess
import textwrap
from src.logging.get_logger import get_logger
from src.system_var import constants, environment
logger = get_logger('ダンプ復元スクリプト')
def exec():
try:
logger.info('ダンプ復元スクリプト:開始')
# 事前処理(共通処理としては空振りする)
_pre_exec()
# メイン処理
# MySQL接続情報を作成する
my_cnf_file_content = f"""
[client]
user={environment.DB_USERNAME}
password={environment.DB_PASSWORD}
host={environment.DB_HOST}
"""
# my.cnfファイルのパス
my_cnf_path = os.path.join('my.cnf')
# my.cnfファイルを生成する
with open(my_cnf_path, 'w') as f:
f.write(textwrap.dedent(my_cnf_file_content)[1:-1])
os.chmod(my_cnf_path, 0o444)
# DBへの接続エラーを早期に検出するため、事前にMySQLサーバーに接続
mysql_pre_process = subprocess.Popen(
['mysql', f'--defaults-file={my_cnf_path}', '-P', f"{environment.DB_PORT}",
environment.DB_SCHEMA, '-N', '-e', 'SELECT 1;'],
stderr=subprocess.PIPE
)
_, error = mysql_pre_process.communicate()
if mysql_pre_process.returncode != 0:
logger.error(
f'MySQLサーバーへの接続に失敗しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
# 復元対象のダンプファイルを特定
s3_file_path = environment.DUMP_FILE_S3_PATH
# aws s3 cpコマンドを実行してdumpファイルをローカルにダウンロードする
s3_cp_process = subprocess.Popen(
['aws', 's3', 'cp', s3_file_path, './dump.gz'], stderr=subprocess.PIPE)
_, error = s3_cp_process.communicate()
if s3_cp_process.returncode != 0:
logger.error(
f'`aws s3 cp`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
# S3コマンドの標準エラーはクローズしておく
s3_cp_process.stderr.close()
# gzipコマンドを実行してdumpファイルを解凍する
gzip_process = subprocess.Popen(
['gunzip', '-c', './dump.gz'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# mysqlコマンドを実行し、dumpを復元する
mysql_process = subprocess.Popen(
['mysql', f'--defaults-file={my_cnf_path}', '-P',
f"{environment.DB_PORT}", environment.DB_SCHEMA],
stdin=gzip_process.stdout, stderr=subprocess.PIPE
)
# gzipの標準出力をmysqlに接続したため、標準出力をクローズする
gzip_process.stdout.close()
_, error = mysql_process.communicate()
if mysql_process.returncode != 0:
logger.error(
f'コマンド実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
# 事後処理(共通処理としては空振りする)
_post_exec()
logger.info('[NOTICE]ダンプ復元スクリプト:終了(正常終了)')
return constants.BATCH_EXIT_CODE_SUCCESS
except Exception as e:
logger.exception(f'ダンプ復元スクリプト中に想定外のエラーが発生しました :{e}')
return constants.BATCH_EXIT_CODE_SUCCESS
def _pre_exec():
"""
ダンプ復元 事前処理
共通機能としては事前処理を実装しない。
事前処理が必要なダンプ復元処理を実装する場合、当ロジックをコピーする。
"""
pass
def _post_exec():
"""
ダンプ復元 事後処理
共通機能としては事後処理を実装しない。
事後処理が必要なダンプ復元処理を実装する場合、当ロジックをコピーする。
"""
pass