0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

本番Webアプリの自動メンテナンスとDB変更をどう運用するか

0
Posted at

Webアプリを本番へ出したあとも、システム内部では継続的な処理が必要になります。

例えば、

  • 期限に応じた状態更新
  • 不要データの整理
  • 定期的なメンテナンス
  • DBテーブルやカラムの追加・変更
  • 不要になった構造の整理
  • 開発・テスト用データの安全な準備

などです。

これらは利用者向けの機能とは違いますが、本番システムを維持するためには欠かせません。

今回、自分で運用しているWebアプリでも、これまでのシステム開発で使ってきた考え方をもとに、

定期処理・DB変更・安全なデータ処理を、通常のアプリ機能とは別の運用処理として整理

しました。

この記事では、その設計と運用上の考え方をまとめます。


この記事で公開しないもの

この記事は、実際に本番運用しているシステムを題材にしています。

そのため、

  • 実際のテーブル名・カラム名
  • 定期処理の具体的な実行時刻や条件
  • 本番環境の内部URL
  • サーバー構成
  • バックアップ・復旧の具体的な経路
  • 本番データのマスク対象や具体的な変換方式
  • 本番環境へのアクセス方法

など、内部構成や運用条件の推測につながる情報は公開しません。

この記事で扱うのは、どのような責務に分け、どのような失敗を想定して設計するかです。


1. 定期処理は「時間になったらSQLを実行する」だけではない

定期処理そのものは単純に見えます。

指定時刻
↓
処理開始
↓
対象データを取得
↓
更新
↓
終了

しかし、本番運用ではこれだけでは足りません。

考える必要があるのは、

すでに実行中ではないか
対象条件は正しいか
同じデータを二重処理しないか
途中で失敗したらどうなるか
次回実行時に再処理してよいか
何件処理したか確認できるか

といったことです。

つまり、

「起動する仕組み」と「安全に処理する仕組み」は別

です。

cronなどのスケジューラは、処理を起動してくれます。

しかし、その処理が二重実行や途中失敗に耐えられるかどうかは、アプリケーション側で設計する必要があります。


2. 定期処理は冪等性を意識する

定期処理では、

同じ処理がもう一度実行されても壊れないか

を考えます。

例えば、

対象:期限切れのレコード
処理:状態をEXPIREDへ変更

だったとします。

理想は、

1回目
ACTIVE → EXPIRED

2回目
すでにEXPIREDなので何もしない

です。

危険なのは、

1回目
処理する

2回目
もう一度別の副作用が発生する

状態です。

そのため、

if current_status != TARGET_STATUS:
    update()
else:
    skip()

のように、現在の状態を確認してから処理する考え方が重要になります。


3. 二重実行を前提に考える

スケジュール上は1回しか起動しないつもりでも、運用上は二重実行の可能性があります。

例えば、

  • 前回処理がまだ終わっていない
  • 手動実行と定期実行が重なった
  • 障害対応中に再実行した
  • スケジューラ側で再起動された

といったケースです。

概念的には、

Job A ────────────────
        Job B ────────────────

のように重なる可能性があります。

そこで、

処理開始
↓
現在実行中か確認
↓
実行可能なら開始
↓
処理状態を記録
↓
終了

という制御を考えます。

具体的なロック方式はシステムによって異なりますが、

「二重には動かないはず」と期待するのではなく、二重に来ても問題にならないようにする

方が安全です。


4. 途中失敗をどう扱うか

定期処理で難しいのは、完全成功と完全失敗だけではありません。

例えば100件を処理するとします。

1〜40件:成功
41件目:失敗
42〜100件:未処理

という状態が起こり得ます。

このとき、

  • 全体をロールバックするのか
  • 成功した40件は確定するのか
  • 次回41件目から再開するのか
  • 全件を再処理しても問題ないのか

を決める必要があります。

処理によって正解は違います。

だから定期処理は、

正常系だけでなく「どこまで進んだ状態で失敗するか」まで設計対象

になります。


5. 自動処理にもログを残す

人が操作する管理画面だけでなく、自動処理にも履歴が必要です。

例えば概念的には、

job_name
started_at
finished_at
result
processed_count
error_count
status

などです。

必要なのは、

いつ動いたか
成功したか
何を処理したか
どこで失敗したか

を後から追えることです。

自動化すると人の操作履歴がなくなるため、

システム自身の行動履歴がより重要になる

と考えています。


6. DB変更はアプリ変更とは別の工程として扱う

アプリコードなら、

コード変更
↓
テスト
↓
反映

という流れになります。

DB変更では、それに加えて、

既存データへの影響
既存SQLへの影響
既存コードへの影響
制約への影響
反映順序
戻し方

を考える必要があります。

特に本番DBでは、

SQLが正しいことと、安全に実行できることは別

です。


7. CREATE・ALTER・DROPで危険度は同じではない

SQLのDDLとしては、

CREATE
ALTER
DROP

があります。

しかし、本番運用上の重さは同じではありません。

CREATE

新しいテーブルなどを追加する処理です。

既存構造を直接変更しないため、比較的影響範囲を限定しやすい操作です。

ただし、

新テーブルを参照するコード
既存データとの関係
権限
制約

などは確認します。

ALTER

すでに利用中の構造を変更します。

例えば、

カラム追加
型変更
DEFAULT変更
制約追加

などです。

ここでは既存データとの整合性が重要になります。

例えば新しいNOT NULLカラムを追加するなら、

既存レコードには何が入るのか

を考えなければなりません。

DROP

削除です。

カラム削除
テーブル削除

は特に慎重に扱います。

問題はSQLが実行できるかではありません。

本当に誰も使っていないか

です。


8. DB変更前に「参照されていないか」を確認する

使っていないと思っているカラムでも、

  • PHPコード
  • SQL
  • 帳票
  • バッチ
  • テスト
  • 管理処理
  • 古い処理

から参照されている可能性があります。

そのため削除前には、

コード検索
↓
SQL検索
↓
定期処理確認
↓
テスト確認
↓
本当に不要か判断

という確認が必要になります。

ここでも、

消せることと、消してよいことは別

です。


9. 開発環境で成功しても本番実行は別に考える

DB変更はまず開発環境で確認します。

しかし、

開発環境で成功
=
本番でもそのまま実行

ではありません。

本番では、

  • データ量
  • データ内容
  • 利用状況
  • 同時アクセス
  • 実行時間
  • 関連処理

が違います。

そのため本番反映前には、

変更前状態確認
↓
影響範囲確認
↓
必要な退避
↓
変更実行
↓
構造確認
↓
データ確認
↓
アプリ動作確認

までを一つの作業として扱います。


10. DB変更は「戻し方」を先に考える

本番変更では、

うまくいくか

だけではなく、

失敗したらどう戻すか

を先に考えます。

例えば、

  • 変更前の状態を確認する
  • 必要なバックアップを用意する
  • 変更内容を限定する
  • 反映後に確認する項目を決める
  • 問題時の復旧方法を決める

といった準備です。

特に削除系変更では、実行後に簡単には戻せない場合があります。

ロールバック可能性そのものを設計条件にする

ことが重要です。


11. アプリとDBの反映順序も設計する

DB変更とアプリ変更が同時に必要な場合があります。

例えば、

新しいカラムを追加
↓
アプリがそのカラムを使う

場合です。

このとき、

アプリを先に反映
↓
まだカラムがない
↓
エラー

となる可能性があります。

逆にDB変更を先に入れても、旧アプリがその構造で動けるか確認が必要です。

理想的には、

旧アプリでも動くDB変更
↓
DB反映
↓
確認
↓
新アプリ反映

のように、途中状態でも成立する変更を考えます。

一度に全部切り替えるより、

途中段階でも壊れない反映順序

を作る方が安全です。


12. 本番データを開発で使うとき、人が生データを扱わない

開発やテストでは、本番に近いデータが必要になる場合があります。

しかし、

本番DBから人がデータ取得
↓
手元で加工
↓
開発DBへ投入

という運用では、人が本番データを直接扱う工程が増えます。

そこで考えたのが、

人が生の本番データを直接扱わなくて済む流れ

です。

概念的には、

本番データ
↓
対象限定
↓
マスク処理
↓
安全性確認
↓
開発・テスト環境

です。

重要なのは、

本番データを持ち出してからマスクする

のではなく、

人が扱う前にマスクする

という順番です。

具体的な対象や方式は公開しませんが、設計思想としては、

安全性を人の注意力だけに頼らない

ことを重視します。


13. 自動化は効率化だけではない

定期処理というと、

人の作業を減らす

というメリットが最初に浮かびます。

もちろんそれもあります。

しかし、

人が直接本番データを扱わない
人が毎回同じ危険な操作をしない
処理方法を統一する
履歴を自動的に残す

という安全面にも意味があります。

つまり、

自動化は「早くする仕組み」だけではなく、「危険な人手作業を減らす仕組み」でもある

と考えています。


14. メンテナンス処理もテストする

定期処理は本番で勝手に動くため、通常の画面処理以上にテストが重要になる場合があります。

例えば、

対象データが0件
対象データが1件
大量に存在する
すでに処理済み
途中状態
不正な状態
二重実行
途中失敗
再実行

などです。

DB変更についても、

既存データあり
NULLあり
境界値あり
旧コードとの共存
変更後の制約
ロールバック

を確認します。

正常系だけでなく、

失敗しても壊れないこと

を確認する必要があります。


15. AIにSQLを書かせる前に決めること

今回も、SQL作成や定期処理の実装にはAIを使っています。

例えばAIは、

  • CREATE文
  • ALTER文
  • 定期処理
  • データ更新SQL
  • テスト項目
  • 影響箇所の候補

などを作れます。

しかし、

このカラムを削除して

と指示する前に、

本当に不要なのか
どこから参照されているのか
データを残す必要はないのか
戻せるのか
どの順序で反映するのか

を確認する必要があります。

同じように、

毎日この処理を実行して

と頼む前に、

二重実行されたらどうなるか
途中失敗したらどうなるか
再実行できるか
履歴をどう残すか

を決めます。

AIはSQLを書けます。

AIは定期処理も書けます。

でも、

本番でその処理を実行してよいかを決める責任は別

です。


まとめ

本番Webアプリの保守というと、

不具合が出た
↓
修正する

だけに見えるかもしれません。

実際には、

定期処理
↓
状態維持
↓
DB構造変更
↓
影響確認
↓
安全なデータ処理
↓
履歴
↓
復旧準備

まで含まれます。

今回のシステムでも、

定期処理・DB変更・安全なデータ処理を、本番システムを維持するための別の仕組み

として扱っています。

自動化する。

変更する。

削除する。

本番データを利用する。

どれも技術的に実行できること自体は難しくありません。

難しいのは、

本番で安全に実行し、失敗しても原因を追えて、必要なら戻せる状態にすること

です。

本番システムは、公開した時点で完成するものではありません。

運用しながら変わり続ける以上、

維持する仕組みまで含めてシステム

だと考えています。


関連記事

noteでは、技術実装よりも、

なぜ本番システムに自動メンテナンスやDB変更の運用が必要なのか

という視点から整理しています。

本番システムは、作ったあとも勝手には維持されない。

また、関連データの削除については、こちらの記事でも扱っています。

テストは、失敗したあとまで設計する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?