データにまつわるシステムトラブル事例(1)〜情報システム編〜
以前の投稿「DXにおけるデータとシステムの役割」でシステムとデータの役割を書きました。今回は、ソフトウェアシステムを構築、運用する際によく起きるデータにまつわるトラブルの話を書いていきます。
ソフトウェアシステムのトラブルは、必ずしもソフトウェアだけの問題で起きるわけではなく、データの問題によるものも多くあります。単純なソフトウェアの問題であれば、局所的な対処で解決できることが多く、解決のための人や時間もさほどかかりません。しかし、データが関係した問題はその影響範囲が非常に広く、解決のために人と時間がかかり、システム開発プロジェクトへのダメージは大きくなる傾向があります。私の感覚では、「データ設計、データの取扱い方、データの品質の問題」は、大幅納期遅延や大幅コストオーバーランを伴う「大問題プロジェクト」の原因の1、2位を争っているように思っています。(ちなみに、もう一つは「要件定義までの段階で何を作るかがうまく定義できていない問題」です)
そこで、実際によく見られる、典型的なトラブルを10個あげてみました。これから、大規模なソフトウェアプロジェクトを手掛ける方には、ぜひ参考にしていただければと思います。まず、今回はリレーショナルデータベースを使った情報システムでよく見られる「古典的」なトラブルについて解説します。
1. 間違った結果を表示してしまう
症状
格納されているデータやそれを計算した結果を画面や帳票に出力する際に、間違った値を表示してしまう機能障害が発生するケースです。例えば以下のようなことが起きます。
- 表示されている各項目の値と合計値が合っていない
- 表示される画面によって、同じ意味の値が違う値になっている
- 表示されるべきものがされない
このような機能障害は、ソフトウェアの規模が多く、多くのソフトウェアエンジニアが関わるプロジェクトで多く見られます。多くはシステム試験で検出できますが、余計な手戻りや試験工数が発生してしまいます。
原因
データ設計時の考慮不足が原因です。具体的には以下のようなケースが考えられます。
- 同じ意味のデータが、別テーブルの別カラムに存在する
- 各カラムの意味が曖昧であり、ソフトウェア設計者ごとに違う解釈をしてしまう
- カラム名が理解できない。あるいは意味を持たない名前になっている(例:“Atr1”, “Atr2”…)
- そもそも、ソフトウェアに必要なデータカラムがない
結果として、多数の人が分担してアプリケーションソフトウェアを作る場合に、人によって別々の値を使ったり、同じ値に対して違う解釈をしてしまったり、場合によってはアプリケーションごとに勝手にデータを定義するため、間違いが起きます。
防止策
このようなことは、以下のような原因で起きます。
- システムとして一貫したデータベース設計をしていない。結果としてアプリケーションソフトウェアごとにバラバラにデータを定義してしまう。
- 設計情報がうまく展開されていない。どういうデータがどこに格納されるのかなど、設計チーム全体でのデータに対する認識が共通化されてない。データ構造は共通化されていても、格納するデータの意味が共通化されていなかったり曖昧だったりする。
- 運用開始後のシステム改修時に、データベース設計の意図を理解せずに、誤った改造をしてしまう。当初の設計ドキュメントが十分に残っていない場合によく起きる。
トラブル発生を防止するためには、アプリケーションソフトウェアを作り出す前に、チームを組んでデータベース設計(データモデリング)をしっかり行い、その結果をドキュメント化しソフトウェアを設計するチームと共有することが必要です。また、データベースを設計するチームとソフトウェアを設計するチームがコミュニケーションを取る機会を設けることも重要です。
2. 関係のないものが表示される
症状
本来表示すべきものとは関係のないものが表示されてしまうような機能障害が発生するケースです。例えば、電話番号が表示されるべきところに住所が表示されるなどです。システム試験で検出できますが、データ設計を見直さなければならないこともあり対処には時間がかかってしまいます。
原因
データベース設計時に、以下のようなことをやってしまっていることが考えられます。
- 一つのカラムに複数の意味を持たせてしまっている
- 一つのレコードに同じ意味の属性が複数存在する(例:電話番号1、電話番号2、電話番号3….)「マルチカラムアトリビュート」をやってしまっている
これらは、データベース設計の「アンチパターン」としてよく知られている、やってはいけない設計パターンです。
防止策
このような問題は、データベース設計者の基本的な知識の欠如により起きます。防止策としては、やはり教育、育成です。リレーショナルデータベースの設計は、体系的な方法論が確立されていますので、少なくともこのような間違いを防止するための教育は比較的容易にできますが、このような教育が体系的になされている組織は、なぜかあまり多くないように思います。データベース設計者を計画的に育成することが重要です。
3. 性能が出ない
症状
リレーショナルデータベースを使ったシステムの場合、ユーザー数が少ないうちはうまく動くが、ユーザが多くなってくると、データの処理に非常に時間がかかってしまい使い物にならなくなるというケースがよく見られ ます。また、しばらく運用を続けていくうちに徐々にシステムの動作が遅くなっていくこともよくあります。最終的には使い物にならないほどに動作が遅くなってしまいます。
原因
元々リレーショナルデータベースは、その仕組み上、高速にデータを検索することができる反面、データ生成と削除には時間がかかります。従って、頻繁にデータの生成と削除を繰り返すことが必要なシステムには、あまり向いていません。また、一つのテーブルに頻繁に挿入、消去を繰り返すことで、性能が劣化していくことがあります。これについて少し詳しく説明していきます。
リレーショナルデータベースは単なるデータテーブルの集合ではなく、検索性能を高速化したり、データの整合性を保証するために、その内部に以下の仕組みを備えています。
インデックス テーブルの中の目的のレコードを効率よく取得するための「索引」に相当するものです。テーブル内の特定のレコードを識別できる値(キー値)と、レコードのデータが格納されている位置を示すポインタで構成され、高速に検索するために「Bツリー」「B+ツリー」などの木構造になっています。
トランザクションログ トランザクションというのは、一連の操作を一つの論理的な処理単位としてまとめ、処理の完了を保証する仕組みのことです。処理が完了する前に、どこかのステップで一つでも失敗すると、全ての操作を全て元に戻しデータの整合をとることができ、これを「ロールバック」と呼びます。このロールバック処理や障害発生時にバックアップからのリストアを行う際に利用するために、発生したトランザクションと変更内容を記録したものがトランザクションログです
データの挿入や削除が行われると、その度にインデックスの更新とトランザクションログへの記録が行われる仕組みとなっており、その際にディスクI/Oが発生します。ディスクI/OにはメモリへのI/Oの約千倍近くの時間がかかりますので、メモリ上で処理ができる参照の処理に比べると、データ挿入、更新時、削除の処理には圧倒的に時間がかかり、頻繁に行われると性能が落ちます。
さらに、挿入、更新時、削除の処理が頻繁に行われると、以下の理由で徐々に性能が劣化していきます。
インデックスのバランスが崩れる 更新処理の多くなると,時間の経過と共にインデックスのノードのバランスが崩れ,ノードの深さが深くなってしまうことがあります。インデックスのノードが深くなるとディスクI/Oの回数が増え,性能が劣化します。
データが断片化する 更新処理の多いと、時間の経過と共にレコードの格納状態が悪化し、データの断片化(フラグメンテーション)が進行します。データの断片化が進行すれば,テーブルのレコード数が変わらなくてもブロック数が増えることがあり、ブロック数が増えればディスクI/Oが増え、これにより性能が劣化します。
防止策
ディスクI/Oの性能はかなり向上していますが、それでも極力ディスクI/Oが発生しないように設計するのがセオリーです。
- 一つのテーブルに多数のインデックスを つけないようにする。(検索を早くするために色々なカラムに安易にインデックスをつけてしまうと、その分ディスクI/Oが多く発生する。)
- データの挿入、更新、削除はできるだけまとめて行い、同じレコードを何度も挿入、削除するようなことは避けるようにする。
性能劣化への運用時の対策としては、インデックスや、データテーブルを定期的に再構築(再編成)することが挙げられます。これにより、インデックス崩れやデータの断片化が解消できますが、通常再構築をするためにはその間データベースシステムを停止させる必要があります。その間システムが使えなくなりますので計画的な運用が必要です。最近のハイエンドなデータベースシステムの中には、システム停止せずに再編成できるものもありますが、全てのテーブルの再編成できるわけではなく、それなりに制約がありますので注意が必要です。
4. データ移行に失敗する
症状
データ移行とは、古いシステムに変わる、新しいシステムを構築して運用を開始する際に、これまで別で蓄積してきたデータを新しいシステムに入れる作業のことです。こう書くと簡単に見えますが、実は難易度が高い作業で、よく考えて実行しないと大抵失敗します。
新しいシステム用に自分でテストデータを作ってテストをしている分には問題なく動いていたシステムが、古いシステムの実際のデータを入れた途端に動かなくなったり、色々な間違いが発見されたりします。システムの運用が始まる直前に発覚することが多く、システム運用開始が大幅にずれ込むなど、大きな問題になることが多いトラブルです。
原因
ほとんどの場合、データベースに格納するデータが、新しいシステムの設計時に想定したものと違ったり、制約などを見落としていたりすることが原因です。様々なパターンがあります。
- 重複したレコードがある
- データ型、データ長が想定していたものと違う
- 値が入っていることが必須のカラムに値が入っていない
- データが想定していた値の範囲に入っていない
- データ移行対象範囲の見落としにより、必要なデータが入っていない
- 移行したデータに漏れがある
例えば、データを更新する際に、何らかの理由で元のデータを残しておきたい場合、「無効フラグ」を設け、新しいレコードにはフラグを立てず、古いレコードにフラグの立て、処理するソフトウェア側で、フラグが立っているものは除外するということがよくあります。意図的に重複レコードにしているのですが、データ移行の際にこれを見落とすと、重複したレコードのある移行データを作ってしまい、新しいシステムではうまく動かないということが起こり得ます。
また、新旧のシステムでデータ構造やデータ形式が異なる場合、データを変換するアプリケーションソフトウェアを作成することになりますが、これの不備によりデータがうまく整備できないということもよく起きます。
防止策
古いシステムでは、データに関するドキュメントが整備されていないことも多く、実際のデータベーススキーマを運用時に思いもしていないような使い方をされている場合もあります。このため、システムでデータがどう使われているかの把握は難しく、必然的に漏れや見落としが起きやすくなります。しっかりと時間をかけて把握を行う必要があります。
また、データ移行を行う場合、一定の期間既存のシステムを停止し、その間に新システムへとデータを切り替える必要があります。業務継続のためには、このような停止期間を頻繁に取ることは困難ですので、限られた期間で作業を完結させなければなりません。
事前にやっておかなければいけないことは多く、データ移行に際して事前に計画を立てて実行していくことが重要です。特にシステムの規模が大きい場合は、専門のデータ移行チームを作り、以下のようなことを計画的に行うことが必要です。
- 古いシステムのデータ構造の把握
- 新しいシステムのデータ構造の把握
- 移行が必要な範囲の特定とボリュームの把握
- 移行のためのデータ変換ソフトの設計と制作
- 実データを使ったテスト
- 移行実行時の方法、手順の策定
(続く)
“データにまつわるシステムトラブル事例(1)〜情報システム編〜” に対して2件のコメントがあります。