MariaDBのBackupファイルをrsyncでリモートサーバーへ転送して世代保管する手順|shell活用

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxtips > データーベース管理 > MariaDBのBackupファイルをrsyncでリモートサーバーへ転送して世代保管する手順|shell活用
MariaDBのバックアップファイルを「サーバーのローカルにだけ保存している」という構成は、ディスク障害・物理損傷・誤削除で一瞬にして全データを失うリスクをはらんでいます。
さらに、バックアップが1世代しかない場合は、意図せぬDELETE文やDROPによるデータ消失に気づいた時点でリカバリが困難になります。

この記事では、MariaDBのバックアップファイルをrsyncでリモートサーバーへ転送し、シェルスクリプトで世代管理を自動化する手順を解説します。
mysqldumpによるダンプ取得・SSH鍵認証の設定・rsync転送コマンド・7世代ローテーション設計・cronによる定期実行まで、実際のサーバー出力付きで解説します。

この記事のポイント

・mysqldump --single-transaction でInnoDB無停止バックアップができる
・SSH鍵認証+rsync -azでパスワード不要の自動転送を実現できる
・find -mtime +N -deleteで古い世代を自動削除して保管容量を管理できる
・cronとシェルスクリプトを組み合わせて毎日深夜に自動実行できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

ローカルだけのMariaDBバックアップが抱えるリスク

バックアップをDBサーバーのローカルのみに保存している場合、以下のリスクがすべてデータ喪失に直結します。

・ディスク障害:バックアップとDBデータが同一ディスクにあれば、障害発生時に両方を失います
・誤削除・ランサムウェア:1世代しかない場合、発見前の時点まで遡れません
・サーバー障害時の全損:バックアップがサーバー内にある限り、サーバーごと復元できない障害ではリカバリ不可です

リモートサーバーへ毎日rsync転送し、複数世代を保管することで、これらのリスクを分散させます。
なお、本記事ではセルフホストのLinuxサーバー上でのMariaDB運用を対象とします。RDS・Cloud SQL等のマネージドDBサービスには別の手法が適切です。

実行環境と前提条件

本記事の手順はRocky Linux 9.4(MariaDB 10.11 LTS)で動作確認済みです。Ubuntu 24.04 LTSでも同様に動作します。

・転送元サーバー:MariaDBが稼働しているLinuxサーバー(Rocky Linux 9.4)
・転送先(リモート)サーバー:SSH接続可能なLinuxサーバー(バックアップ専用または別用途兼用)
・使用ツール:mysqldump、rsync、OpenSSH、cron
・必要権限:転送元でのrootまたはsudo権限、MariaDBのバックアップ実行権限

# バージョン確認 [root@db-server ~]# mariadb --version mariadb Ver 15.1 Distrib 10.11.9-MariaDB, for Linux (x86_64) using EditLine wrapper [root@db-server ~]# rsync --version | head -1 rsync version 3.2.7 protocol version 31

mysqldumpでMariaDBのバックアップファイルを作成する

1. パスワードをスクリプトに平文で書かない(.my.cnf)

mysqldumpをシェルスクリプトから実行する際、パスワードをスクリプトに直書きすると ps aux コマンドで他のユーザーに見られてしまいます。
rootのホームディレクトリに ~/.my.cnf を作成し、認証情報を格納します。

# /root/.my.cnf を作成 [root@db-server ~]# cat > /root/.my.cnf << 'EOF' [mysqldump] user=root password=your_mariadb_password EOF # rootだけが読めるようにパーミッションを制限 [root@db-server ~]# chmod 600 /root/.my.cnf [root@db-server ~]# ls -la /root/.my.cnf -rw------- 1 root root 52 Oct 7 02:30 /root/.my.cnf

2. 全データベースをgzip圧縮してダンプする

--single-transaction オプションを指定すると、InnoDBテーブルをロックせずにバックアップを取得できます。MyISAMテーブルが混在する場合は、別途 --lock-tables の必要性を検討してください。
バックアップファイルの圧縮はgzipパイプ直結方式が一般的ですが、tar コマンドの実用例で解説するtarアーカイブで日付ディレクトリごとまとめる方式も現場では使われます。今回はgzipパイプ直結で実装します。

# バックアップディレクトリを作成 [root@db-server ~]# mkdir -p /backup/mariadb # 全データベースをgzip圧縮してダンプ(InnoDB無停止) [root@db-server ~]# mysqldump --all-databases --single-transaction --flush-logs | gzip > /backup/mariadb/all-databases-$(date +%Y%m%d).sql.gz # 確認 [root@db-server ~]# ls -lh /backup/mariadb/ total 284M -rw-r--r-- 1 root root 284M Oct 7 03:01 all-databases-20261007.sql.gz

SSH鍵認証でrsyncの無人転送を実現する

rsyncはSSH経由でデータを転送します。cronから無人実行するためにはパスワード入力が不要なSSH鍵認証の設定が必須です。

1. 転送元サーバーでSSH鍵ペアを生成する

# Ed25519鍵ペアを生成(パスフレーズなし=cron自動実行に対応) [root@db-server ~]# ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519_backup -N "" Generating public/private ed25519 key pair. Your identification has been saved in /root/.ssh/id_ed25519_backup Your public key has been saved in /root/.ssh/id_ed25519_backup.pub The key fingerprint is: SHA256:xKj8mP3rT1qL9nVy7wZa2eDs4fRuXcBh root@db-server

2. 公開鍵をリモートサーバーへ登録する

# リモートサーバーのbackup-userに公開鍵をコピー [root@db-server ~]# ssh-copy-id -i /root/.ssh/id_ed25519_backup.pub backup-user@192.168.1.10 /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s) Number of key(s) added: 1 Now try logging into the machine: backup-user@192.168.1.10 # 接続確認(パスワードなしでログインできることを確認) [root@db-server ~]# ssh -i /root/.ssh/id_ed25519_backup backup-user@192.168.1.10 hostname backup-server

3. rsyncの動作確認

# 転送テスト(--dry-runで実際には送らず確認のみ) [root@db-server ~]# rsync -avz --dry-run -e "ssh -i /root/.ssh/id_ed25519_backup" /backup/mariadb/ backup-user@192.168.1.10:/remote-backup/mariadb/ sending incremental file list ./ all-databases-20261007.sql.gz sent 156 bytes received 19 bytes 116.67 bytes/sec total size is 297,791,488 speedup is 1,706,147.63 (DRY RUN)

シェルスクリプトで世代管理と自動転送を実装する

1. 完成スクリプト

以下のスクリプトは、ダンプ取得・rsync転送・世代削除を一括で行います。
パイプの片方が失敗しても無言で成功扱いになるのを防ぐため、PIPESTATUS でダンプとgzip両方の終了コードを検査しています。

#!/bin/bash # /usr/local/sbin/mariadb-backup-rsync.sh # MariaDB バックアップ + rsync リモート転送スクリプト # --- 設定項目 --- BACKUP_DIR="/backup/mariadb" REMOTE_HOST="backup-user@192.168.1.10" REMOTE_DIR="/remote-backup/mariadb" SSH_KEY="/root/.ssh/id_ed25519_backup" KEEP_DAYS=7 LOG_FILE="/var/log/mariadb-backup.log" DATE=$(date +%Y%m%d) BACKUP_FILE="${BACKUP_DIR}/all-databases-${DATE}.sql.gz" # --- ログ関数 --- log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "${LOG_FILE}" } # --- バックアップ取得 --- log "INFO: バックアップ開始" mkdir -p "${BACKUP_DIR}" mysqldump --all-databases --single-transaction --flush-logs | gzip > "${BACKUP_FILE}" DUMP_STATUS=("${PIPESTATUS[@]}") if [ "${DUMP_STATUS[0]}" -ne 0 ] || [ "${DUMP_STATUS[1]}" -ne 0 ]; then log "ERROR: mysqldump/gzip失敗 (mysqldump=${DUMP_STATUS[0]}, gzip=${DUMP_STATUS[1]})" exit 1 fi log "INFO: ダンプ完了 $(ls -lh ${BACKUP_FILE} | awk '{print $5}')" # --- rsync転送 --- log "INFO: rsync転送開始" if ! rsync -az -e "ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no" "${BACKUP_DIR}/" "${REMOTE_HOST}:${REMOTE_DIR}/"; then log "ERROR: rsync転送失敗" exit 1 fi log "INFO: rsync転送完了" # --- ローカル世代削除(KEEP_DAYS日より古いファイルを削除)--- find "${BACKUP_DIR}" -name "all-databases-*.sql.gz" -mtime +"${KEEP_DAYS}" -delete log "INFO: ローカル世代削除完了(${KEEP_DAYS}日超のファイルを削除)" log "INFO: バックアップ処理正常終了"

2. パーミッション設定と動作確認

# スクリプトに実行権限を付与(rootのみ実行可) [root@db-server ~]# chmod 700 /usr/local/sbin/mariadb-backup-rsync.sh # 動作確認(初回実行) [root@db-server ~]# /usr/local/sbin/mariadb-backup-rsync.sh 2026-10-07 03:01:00 INFO: バックアップ開始 2026-10-07 03:04:23 INFO: ダンプ完了 284M 2026-10-07 03:04:23 INFO: rsync転送開始 2026-10-07 03:07:55 INFO: rsync転送完了 2026-10-07 03:07:55 INFO: ローカル世代削除完了(7日超のファイルを削除) 2026-10-07 03:07:55 INFO: バックアップ処理正常終了 # リモートサーバーでの確認 [root@db-server ~]# ssh -i /root/.ssh/id_ed25519_backup backup-user@192.168.1.10 ls -lh /remote-backup/mariadb/ total 284M -rw-r--r-- 1 backup-user backup-user 284M Oct 7 03:01 all-databases-20261007.sql.gz

3. 7世代ローテーションの動作確認(8日分が溜まった状態)

# 8日目の実行後(7日分だけ残り、最も古いファイルが削除される) [root@db-server ~]# ls -lh /backup/mariadb/ total 1.9G -rw-r--r-- 1 root root 284M Oct 1 03:01 all-databases-20261001.sql.gz -rw-r--r-- 1 root root 284M Oct 2 03:01 all-databases-20261002.sql.gz -rw-r--r-- 1 root root 284M Oct 3 03:01 all-databases-20261003.sql.gz -rw-r--r-- 1 root root 284M Oct 4 03:01 all-databases-20261004.sql.gz -rw-r--r-- 1 root root 284M Oct 5 03:01 all-databases-20261005.sql.gz -rw-r--r-- 1 root root 284M Oct 6 03:01 all-databases-20261006.sql.gz -rw-r--r-- 1 root root 284M Oct 7 03:01 all-databases-20261007.sql.gz

cronで毎日3時に自動実行する

Linux Master Pro Seminarのカリキュラムでも毎回触れているように、バックアップ自動化はcronの最も重要なユースケースの一つです。

# rootのcrontabを編集 [root@db-server ~]# crontab -e # 毎日3時00分にバックアップ+rsync転送を実行 0 3 * * * /usr/local/sbin/mariadb-backup-rsync.sh >> /var/log/mariadb-backup.log 2>&1 # 設定確認 [root@db-server ~]# crontab -l 0 3 * * * /usr/local/sbin/mariadb-backup-rsync.sh >> /var/log/mariadb-backup.log 2>&1

翌朝にログを確認して「INFO: バックアップ処理正常終了」が出力されていることを確認してください。エラーが出た場合は即座に対処します。

よくあるエラーと対処法

「rsync: [sender] change_dir "/backup/mariadb" failed」が出る

転送元のバックアップディレクトリが存在しないか、パーミッションが不足しています。

# ディレクトリの存在と権限を確認 [root@db-server ~]# ls -ld /backup/mariadb ls: cannot access '/backup/mariadb': No such file or directory # ディレクトリを作成 [root@db-server ~]# mkdir -p /backup/mariadb [root@db-server ~]# ls -ld /backup/mariadb drwxr-xr-x 2 root root 6 Oct 7 03:00 /backup/mariadb

「Got error: 1044: Access denied for user 'root'」が出る

MariaDBの認証情報に問題があります。~/.my.cnf のパスワードが正しいか確認し、rootでの接続が通るかを先に検証します。

# .my.cnfを使わずに直接接続テスト [root@db-server ~]# mariadb -u root -p -e "SHOW DATABASES;" | head -5 Enter password: +--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ # .my.cnfを使った接続テスト(パスワードプロンプトが出なければOK) [root@db-server ~]# mariadb -e "SHOW DATABASES;" | head -3 +--------------------+ | Database | +--------------------+

rsync転送後にリモートに古いファイルが残り続ける

rsyncの --delete オプションを使うと、転送元に存在しないファイルを転送先からも削除できます。ただし、転送先での独立した長期保管を目的とする場合は --delete を外し、転送先でも別途 find -mtime で世代削除する運用にします。

# リモートでの世代削除(転送先サーバー上で実行、または sshコマンドで遠隔実行) [root@backup-server ~]# find /remote-backup/mariadb -name "all-databases-*.sql.gz" -mtime +14 -delete

まとめ

MariaDBのバックアップファイルをrsyncでリモートサーバーへ転送して世代保管する手順をまとめます。

やりたいこと コマンド・設定
mysqldump認証情報を安全に格納する cat > ~/.my.cnf << EOF ... EOF && chmod 600 ~/.my.cnf
全DBをgzip圧縮でダンプする mysqldump --all-databases --single-transaction | gzip > dump-$(date +%Y%m%d).sql.gz
SSH鍵ペアを生成する(パスフレーズなし) ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_backup -N ""
公開鍵をリモートサーバーへ登録する ssh-copy-id -i ~/.ssh/id_ed25519_backup.pub backup-user@リモートIP
rsyncでリモート転送する rsync -az -e "ssh -i ~/.ssh/id_ed25519_backup" /backup/mariadb/ user@host:/remote-backup/mariadb/
7日より古いファイルを削除する find /backup/mariadb -name "*.sql.gz" -mtime +7 -delete
cronで毎日3時に定期実行する 0 3 * * * /usr/local/sbin/mariadb-backup-rsync.sh
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、
MariaDB・MySQL運用からバックアップ設計・自動化スクリプトまで、現場で通じる実践スキルを2日間のハンズオンで体得できる「Linux Master Pro Seminar」を開催しています。
>> Linux Master Pro Seminar の詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。