はじめに
SQL Server のレプリケーションを検証するにあたってPCを2台準備できないので、Docker で完結する検証環境を作りました。
この記事では、プッシュサブスクリプションとプルサブスクリプションの両方を実際に動かしながら、その違いと使い分けをまとめます。
GitHub リポジトリ: https://github.com/hiro134103/master-update-proposal
この記事の内容
- ✅ SQL Server レプリケーションの基本
- ✅ プッシュ vs プル の違いと使い分け
- ✅ Docker だけで完結する実践的な検証環境
- ✅ 夜間停止するサーバーへの対応方法の検討
プッシュとプルの違い
| 項目 | プッシュ | プル |
|---|---|---|
| Distribution Agent の場所 | Publisher側 | Subscriber側 |
| 接続方向 | Publisher → Subscriber | Subscriber → Publisher |
| Subscriber 停止時 | 配信エラー | 次回起動時に自動取得 |
| 適用シーン | 常時稼働サーバー | 夜間停止する部門サーバー |
どっちを使えばいい?
プッシュサブスクリプション を選ぶべきケース:
- Subscriber が 24時間稼働している
- リアルタイム性を重視(5分間隔で即座に配信)
- 中央で一括管理したい
プルサブスクリプション を選ぶべきケース:
- Subscriber が夜間停止する(部門サーバーなど)
- 起動順序が不定(Subscriber が先に起動する可能性)
- Publisher の負荷を分散したい
データベース構成
-
ReplicationDB(業務データ)
- アプリケーションが使う実際のデータベース
-
distribution(レプリケーションキュー)
- Log Reader Agent が書き込む変更履歴
- デフォルト 72時間保持
- Subscriber が取得するまで待機
データの流れ(4ステップ)
[アプリ]
↓ INSERT/UPDATE/DELETE
[ReplicationDB]
↓ トランザクションログに記録
[Log Reader Agent] ← 常時監視(数秒以内)
↓ 変更を抽出
[distribution DB] ← 72時間保持
↓
[Distribution Agent] ← ここが Push/Pull で違う!
↓
[Subscriber の ReplicationDB]
プッシュの場合: Distribution Agent が Publisher 側で動作
プルの場合: Distribution Agent が Subscriber 側で動作
実際に動かしてみる
1. 環境を起動
git clone https://github.com/hiro134103/master-update-proposal.git
cd master-update-proposal
# Docker コンテナ起動
docker-compose up -d
# 起動確認
docker-compose ps
2. プッシュサブスクリプションを試す
詳細は push-replication/SETUP.md を参照。
# Publisher にデータ挿入
docker exec -it sqlpublisher /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P "YourStrong@Passw0rd" \
-d ReplicationDB \
-Q "INSERT INTO Products (ProductName, Price) VALUES ('Webcam', 59.99);" -C
# 数秒待って Subscriber で確認
docker exec -it sqlsubscriber /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P "YourStrong@Passw0rd" \
-d ReplicationDB \
-Q "SELECT * FROM Products WHERE ProductName = 'Webcam';" -C
3. プルサブスクリプションを試す
詳細は pull-replication/SETUP.md を参照。
プルの場合、Subscriber 側で Distribution Agent を手動実行するか、スケジュール設定します。
夜間停止シナリオ:
18:00 - 部門サーバー停止
18:00-翌9:00 - Publisher で変更が distribution に蓄積
08:30 - 部門サーバー起動
09:00 - Distribution Agent 実行 → 夜間の全変更を一括取得
実運用での設定を検討
夜間停止する部門サーバーの場合、以下のような設定で環境に合わせる。
@frequency_type = 4, -- 毎日実行
@active_start_time_of_day = 90000, -- 朝 9:00 開始
@frequency_subday_type = 4, -- 分単位
@frequency_subday_interval = 30 -- 30分間隔
動作:
- 毎朝 9:00 に最初の同期(夜間の変更をまとめて取得)
- その後 30分間隔で継続同期(9:30, 10:00, 10:30...)
更新頻度は業務要件に応じて調整:
| 更新頻度 | 設定値 | 用途 |
|---|---|---|
| 15分間隔 | @frequency_subday_interval = 15 |
高頻度更新が必要 |
| 30分間隔 | @frequency_subday_interval = 30 |
標準的な同期(推奨) |
| 1時間間隔 | @frequency_subday_interval = 60 |
低頻度で十分 |
よくあるトラブルと解決方法
Q1: Subscriber が先に起動したらどうなる?
プッシュの場合:
- Publisher の Distribution Agent が接続エラー
- Subscriber 起動後も自動で配信されない(要調査)
プルの場合:
- Subscriber の Distribution Agent が接続エラー
- 次回実行時に自動リトライ → 問題なく取得できる
Q2: distribution DB の保持期間 72時間を超えたら?
データロスが発生します。長期停止が想定される場合は保持期間を延長してください。
EXEC sp_changedistributiondb
@database = N'distribution',
@max_distretention = 168 -- 7日間(168時間)
Q3: レプリケーションが動かない
# SQL Server Agent の状態確認
docker exec sqlpublisher /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P "YourStrong@Passw0rd" \
-Q "SELECT CASE WHEN EXISTS(SELECT 1 FROM sys.dm_exec_sessions WHERE program_name LIKE 'SQLAgent%') THEN 'Running' ELSE 'Not Running' END AS AgentStatus;" -C
# エラー確認
docker exec sqlpublisher /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P "YourStrong@Passw0rd" \
-d distribution \
-Q "SELECT * FROM MSrepl_errors ORDER BY time DESC;" -C
実際の検証結果
プッシュサブスクリプション
- 初期データ: 5件レプリケーション成功
- リアルタイム追加: Webcam, USB Cable → 約10秒でレプリケーション ✅
- レイテンシ: 5-10秒
詳細: push-replication/VERIFICATION-RESULTS.md
プルサブスクリプション
- 初期データ: 5件レプリケーション成功
- リアルタイム追加: Tablet, Smartwatch → 約10-15秒でレプリケーション ✅
- 課題: Distribution Agent の手動実行が必要(スケジュール設定で解決)
詳細: pull-replication/VERIFICATION-RESULTS.md
リポジトリの構成
master-update-proposal/
├── docker-compose.yml # 環境定義
├── README.md # プロジェクト概要
├── REPLICATION-README.md # 詳細セットアップガイド
├── ARCHITECTURE.md # アーキテクチャ解説
├── push-replication/
│ ├── SETUP.md # プッシュのセットアップ
│ ├── VERIFICATION-RESULTS.md # 検証結果
│ ├── publisher-setup.sql
│ └── subscriber-setup.sql
└── pull-replication/
├── SETUP.md # プルのセットアップ
├── VERIFICATION-RESULTS.md # 検証結果
├── publisher-setup.sql
└── subscriber-setup.sql
各ファイルには詳細な手順とコマンドが記載されています。
まとめ
| 確認項目 | プッシュ | プル |
|---|---|---|
| 🚀 リアルタイム性 | ⭐⭐⭐ | ⭐⭐ |
| 💪 耐障害性 | ⭐ | ⭐⭐⭐ |
| 🎯 管理の簡単さ | ⭐⭐⭐ | ⭐⭐ |
| 🔄 間欠稼働対応 | ❌ | ✅ |
結論:
- 常時稼働 → プッシュサブスクリプション
- 夜間停止あり → プルサブスクリプション
Docker だけで両方試せるので、ぜひ実際に動かしてみてください!
参考リソース
- GitHub リポジトリ: https://github.com/hiro134103/master-update-proposal
- Microsoft Docs: SQL Server レプリケーション
- Microsoft Docs: プル サブスクリプションの作成
おわりに
PCが1台しかないけどどうしても実際に動かさないと納得できないので、エラーに苦しみながら環境を作ってみました。誤りの指摘や改善提案がございましたら、この記事へのコメントやGitHub の Issue でお待ちしています!
(感想でもなんでもフィードバックもらえたら嬉しいです!)