#08 MySQLデータベースを使ってみよう

バックアップとユーザー管理

最終回: 運用の基本を押さえる

データベースの学習の締めくくりとして、実際の運用で欠かせないバックアップユーザー管理を学びます。どんなに完璧なアプリでも、バックアップなしでは安心して運用できません。また、適切なユーザー管理はセキュリティの基本です。

mysqldump によるバックアップと復元フロー バックアップ(Backup) MySQL DB myapp_db users / orders products ... 本番データ mysqldump コマンド mysqldump \ -u root -p \ myapp_db \ > backup.sql backup.sql ファイル -- MySQL dump 8.0.38 CREATE TABLE users (...); INSERT INTO users VALUES (1,'田中',...), (2,'佐藤',...); | gzip で圧縮可能 → backup.sql.gz 復元(Restore) backup.sql ファイル CREATE TABLE users (...); INSERT INTO users VALUES (1,'田中',...),(2,'佐藤',...); mysql コマンドで復元 mysql \ -u root -p \ myapp_db \ < backup.sql 復元された DB myapp_db データ復元完了 --single-transaction オプションを付けるとトランザクション整合性を保ちながらバックアップできる 本番環境では cron で自動化し、古いバックアップは定期削除する
図1: mysqldumpによるバックアップと復元のフロー

mysqldump でバックアップ

mysqldump はMySQLに付属するバックアップツールです。データベースの構造とデータをSQLファイルとして出力します。

特定のデータベースをバックアップ

# 基本的なバックアップ
mysqldump -u root -p myapp_db > backup_myapp_db.sql

# タイムスタンプ付きのファイル名にする
mysqldump -u root -p myapp_db > myapp_db_$(date +%Y%m%d_%H%M%S).sql

# 圧縮してバックアップ(容量節約)
mysqldump -u root -p myapp_db | gzip > myapp_db_$(date +%Y%m%d).sql.gz

全データベースをバックアップ

# --all-databases ですべてのDBをバックアップ
mysqldump -u root -p --all-databases > all_databases.sql

特定のテーブルだけバックアップ

# myapp_db の users テーブルだけ
mysqldump -u root -p myapp_db users > backup_users.sql

# 複数テーブル
mysqldump -u root -p myapp_db users orders products > backup_tables.sql

よく使うオプション

mysqldump \
  --single-transaction \   # トランザクション整合性を保つ(InnoDB推奨)
  --no-data \              # スキーマのみ(データなし)
  --no-create-info \       # データのみ(DDLなし)
  -u root -p myapp_db > backup.sql

バックアップを復元する

# データベースに復元
mysql -u root -p myapp_db < backup_myapp_db.sql

# 圧縮ファイルから復元
gunzip < myapp_db_20260410.sql.gz | mysql -u root -p myapp_db

# 新しいデータベースに復元する場合
mysql -u root -p -e "CREATE DATABASE myapp_db_restored;"
mysql -u root -p myapp_db_restored < backup_myapp_db.sql

ポイント: 本番環境への復元前には、必ず別環境でテスト復元して内容を確認してください。


定期バックアップの自動化

# /etc/cron.d/mysql-backup などに記述
# 毎日深夜2時に自動バックアップ
0 2 * * * root mysqldump -u backup_user -pPASSWORD myapp_db \
  | gzip > /var/backups/mysql/myapp_db_$(date +\%Y\%m\%d).sql.gz

# 30日以上前のバックアップを削除
0 3 * * * root find /var/backups/mysql/ -name "*.sql.gz" -mtime +30 -delete

ユーザーを作成・管理する

MySQLユーザー・ホスト・権限の構造 ユーザー定義 'root'@'localhost' 管理者ユーザー ⚠ アプリには使わない 'appuser'@'localhost' アプリ用ユーザー 最小権限の原則を適用 'readuser'@'%' 読み取り専用ユーザー 任意ホストから接続可能 GRANT 権限(GRANT) GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'; 全DB・全テーブルへの完全な権限 SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ... GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'appuser'@'localhost'; myapp_dbのみ: 読み書き可能 CREATE/DROP/他DBへのアクセスは不可 GRANT SELECT ON myapp_db.* TO 'readuser'@'%'; myapp_dbのみ: 読み取り専用 INSERT/UPDATE/DELETE は不可 ホスト制限 'localhost' 自分自身のみ '127.0.0.1' ループバックのみ '192.168.1.%' 特定サブネットのみ '%' 任意ホスト ⚠注意 ユーザー名@ホストが ユーザーの識別子 権限確認・削除コマンド SHOW GRANTS FOR 'appuser'@'localhost'; REVOKE DELETE ON myapp_db.* FROM 'appuser'@'localhost';
図2: MySQLユーザー・ホスト・権限の構造

CREATE USER — ユーザーを作成する

-- localhost からのみアクセスできるユーザー
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';

-- 任意のホストからアクセスできるユーザー(セキュリティ注意)
CREATE USER 'readuser'@'%' IDENTIFIED BY 'AnotherPassword456!';

-- 特定IPからのみ許可
CREATE USER 'dbadmin'@'192.168.1.100' IDENTIFIED BY 'AdminPass789!';

'ユーザー名'@'ホスト' がMySQLのユーザー識別子です。同じユーザー名でも接続元ホストが違えば別ユーザーとして扱われます。


GRANT — 権限を付与する

-- 特定DBへの全権限を付与
GRANT ALL PRIVILEGES ON myapp_db.* TO 'appuser'@'localhost';

-- 読み取り専用権限のみ付与
GRANT SELECT ON myapp_db.* TO 'readuser'@'%';

-- 特定の操作だけ許可
GRANT SELECT, INSERT, UPDATE ON myapp_db.* TO 'writeuser'@'localhost';

-- 特定テーブルだけ許可
GRANT SELECT ON myapp_db.users TO 'support'@'localhost';

-- 権限を即時反映
FLUSH PRIVILEGES;

権限の種類

権限説明
ALL PRIVILEGESすべての権限
SELECTデータの参照
INSERTデータの追加
UPDATEデータの更新
DELETEデータの削除
CREATEDB・テーブルの作成
DROPDB・テーブルの削除
GRANT OPTION他ユーザーへの権限付与

権限を確認・削除する

-- ユーザーの権限を確認
SHOW GRANTS FOR 'appuser'@'localhost';
+-------------------------------------------------------------------+
| Grants for appuser@localhost                                      |
+-------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `appuser`@`localhost`                      |
| GRANT ALL PRIVILEGES ON `myapp_db`.* TO `appuser`@`localhost`    |
+-------------------------------------------------------------------+
-- 権限を剥奪する
REVOKE DELETE ON myapp_db.* FROM 'appuser'@'localhost';

-- ユーザーを削除する
DROP USER 'appuser'@'localhost';

パスワードの変更

-- 自分自身のパスワードを変更
ALTER USER USER() IDENTIFIED BY 'NewPassword!';

-- 他ユーザーのパスワード変更(管理者権限が必要)
ALTER USER 'appuser'@'localhost' IDENTIFIED BY 'NewSecurePass!';

本番環境のセキュリティ基本

やってはいけないこと

-- ❌ アプリからrootユーザーで接続しない
-- ❌ 全ホスト許可ユーザーに強力な権限を付与しない
-- ❌ パスワードなしのユーザーを作成しない
CREATE USER 'no_pass'@'%';  -- 危険

推奨プラクティス

-- ✅ アプリ用ユーザーは最小権限で作成
CREATE USER 'myapp'@'localhost' IDENTIFIED BY '十分に長いランダムパスワード';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'myapp'@'localhost';

-- ✅ バックアップ用ユーザーはSELECTのみ
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'BackupPassword!';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT ON myapp_db.* TO 'backup_user'@'localhost';

設定ファイルでのパスワード管理

本番環境ではコマンドラインにパスワードを書かず、設定ファイルを使います。

# ~/.my.cnf (権限を 600 に設定: chmod 600 ~/.my.cnf)
[mysqldump]
user=backup_user
password=BackupPassword!
# 設定ファイルを使えばパスワード不要
mysqldump myapp_db > backup.sql

シリーズのまとめ

このシリーズでは以下を学びました。

エピソード内容
Ep.01インストールと接続
Ep.02データベースとテーブルの作成
Ep.03INSERT と SELECT
Ep.04UPDATE と DELETE
Ep.05WHERE 句の詳細
Ep.06JOIN(テーブル結合)
Ep.07GROUP BY(集計)
Ep.08バックアップとユーザー管理

MySQLの基礎を一通り押さえたら、次のステップとしてインデックス最適化ストアドプロシージャレプリケーションなども探求してみてください。データベースのスキルは実践を重ねることで磨かれます。実際のプロジェクトでどんどん試してみましょう!