【入門編】 スキーマ更新プロセス – Cloud Spanner

こんにちは!Cloud Spannerの世界へようこそ。
チーフアーキテクトの私です。

「データベースの構造(スキーマ)を変えるとき、システムを一度止めなければならない」
――これは、長年エンジニアを悩ませてきた古い常識です。新しいカラム(列)を追加するだけで、夜中にメンテナンスウィンドウを設け、サービスを数分間停止させる。そんな経験はありませんか?

しかし、Cloud Spannerはこの常識を根本から破壊しました。
世界中にデータを分散させながら、システムを1秒たりとも止めずに、裏側でこっそり、かつ安全にデータベースの構造を書き換える。

今回は、この魔法のような「オンラインスキーマ更新」の裏側で何が起きているのか? 初学者の方にもスッと腹落ちするように、身近な例えを交えながら解き明かしていきましょう。
ここをクリアすれば、Cloud Spannerの分散データベースとしての本質がバッチリマスターできますよ!

—

1. 例え話:営業中の「巨大レストランのメニュー改定」

想像してください。世界中に何百店舗も展開している、超巨大なファミリーレストランチェーンがあるとします。
今、このレストランでは「新しいデザート(新しいカラム)」を全店のメニューに追加しようとしています。

  • 古いデータベースの場合:

夜中にお店を一旦「全店閉店」にして、一斉に新しいメニュー表を配り、朝になったら開店します。もし全店で足並みが揃わないと、お客様が混乱してしまいますよね。

  • Cloud Spanner(オンラインスキーマ更新)の場合:

お店を営業したまま、スタッフ同士がこっそり合意を取りながら、お客様の注文を邪魔しないように、少しずつ新しいメニューを追加していきます。

Spannerがやっているのは、まさにこれです。止まらないシステムの中で、どうやって安全にこれを実現しているのでしょうか? その秘密が「Paxos(パクソス)」と「段階的適用」です。

—

2. 秘密兵器①:Paxos(パクソス)による「全会一致の合意」

Cloud Spannerは、データを世界中の複数のサーバー(ノードのグループ)にコピーして持っています。データを安全に保つために、サーバー同士は「Paxos(パクソス)」という厳格な合意形成アルゴリズムを使って会話しています。

スキーマ変更(DDL)を行うときも、このPaxosが主役になります。

1. 提案のフェーズ
あなたが「このテーブルに新しい列を追加したい!」とSpannerに命令を出します。
2. 会議のフェーズ
データを管理しているリーダーサーバーが、「こういう新しい構造に変えようと思うけど、みんな異存はないかい?」と、グループ内の他のサーバーたちに問いかけます。
3. 合意のフェーズ
過半数のサーバーが「OK!」と返事をすると、「よし、この瞬間からこのスキーマのバージョンを『v2』に引き上げよう!」ということが全員の間でカチッと決まります。

この決議がなされた瞬間から、Spannerの内部では「時間(タイムスタンプ)」を基準にした厳密な管理が始まります。これが次の「段階的適用」のキモになります。

—

3. 秘密兵器②:安全を担保する「段階的適用プロセス」

スキーマのバージョンが「v2」に決まったからといって、世界中にある数ペタバイトのデータを一瞬で書き換えることは物理的に不可能です。そんなことをすれば、データベースが重くなってお客様のアクセスが止まってしまいます。

そこでSpannerは、「段階的(フェーズごと)」にこっそりと変更を適用していきます。

ステップ 1: スキーマバージョンの伝播

まず、すべてのサーバーに「新しいスキーマ(v2)があるよ」という情報が行き渡ります。この時点では、まだ実際のデータは書き換えられていません。

ステップ 2: 読み取りと書き込みの調停(ここが一番スマート!)

Spannerには「TrueTime」という超高精度な時計機能があり、すべてのトランザクションに正確なタイムスタンプが振られます。

  • 過去の時間を読むトランザクション: 「スキーマ変更前のデータを見たい」というリクエストには、古い構造(v1)のままデータを返します。
  • 新しい書き込み: 新しい構造(v2)に合わせてデータを記録します。

これにより、システムが動いている最中でも、データの矛盾が絶対に起きないようになっています。

ステップ 3: バックグラウンドでのデータ整理(ガベージコレクション的な動き)

すべてのサーバーが新しいスキーマの適用を安全に行える状態になったことを確認すると、裏側のバックグラウンド処理(スレッド)が、古い形式で残っていたデータをこつこつと新しい形式に整形・更新していきます。
ユーザーからは、この苦労は見えません。気づいたときには、何事もなかったかのように新しい列が使えるようになっているのです。

—

4. コードで見る!本当に止まらないDDLの実行

百聞は一見にしかず。実際にCloud Spannerでスキーマを変更するコード(DDL)を見てみましょう。Pythonを使った例です。

from google.cloud import spanner

def update_schema_online(instance_id, database_id):
“””
Cloud Spannerのオンラインスキーマ更新(DDL実行)の例
システムを止めずに、安全にカラムを追加します。
“””
client = spanner.Client()
instance = client.instance(instance_id)
database = instance.database(database_id)

# 追加するDDL(Data Definition Language)文
# 例: Singers テーブルに ‘MarketingNotes’ という文字列型の列を追加する
ddl_statements = [
“””
ALTER TABLE Singers
ADD COLUMN MarketingNotes STRING(MAX)
“””
]

# update_ddl メソッドを呼び出す
# この処理を実行している最中も、アプリケーションからの読み書きは
# 一切停止することなく継続されます。
operation = database.update_ddl(ddl_statements)

print(“スキーマ変更のバックグラウンド処理を開始しました…”)

# 処理が完了するまでブロックしますが、
# この間もSpannerの他の機能やトランザクションは動き続けています
operation.result(timeout=120)

print(“✨ スキーマ変更が無事に完了しました!システムは一度も停止していません。”)

実行例の呼び出し(実際のエンドポイントやIDに置き換えてください)
update_schema_online(“my-instance”, “my-database”)

このスクリプトを実行した瞬間から、Spannerの内部では先ほど解説した「Paxosによる合意」と「段階的適用」が走り出し、アプリケーションを止めることなく安全にスキーマが拡張されます。

—

チーフアーキテクトからのまとめ

いかがでしたでしょうか?
Cloud Spannerのオンラインスキーマ更新は、単なる「便利な機能」ではありません。「分散合意アルゴリズム(Paxos)」と「正確な時間管理(TrueTime)」という、Spannerの根幹をなす技術の結晶によって支えられています。

  • 変更はサーバー間の合意(Paxos)で安全にバージョン管理される
  • システムを止めず、データの矛盾を防ぎながら段階的に適用される

この仕組みを知っていれば、将来どれほど巨大なシステムを任されても、「データベースの変更が怖い」なんて悩む必要はもうありません。

ここをクリアしたあなたなら、もうSpannerのコアアーキテクチャの半分以上を理解したも同然です。
自信を持って、次のステップへ進みましょう!

コメント

タイトルとURLをコピーしました