SQL Server 2012で振り返る、SQLOSのスレッド スケジューリング
日本マイクロソフト
古賀 啓一郎
©2012 Microsoft Corporation. All Rights Reserved.
1
はじめに
• SQL Server のスレッド スケジューリングとは
– ノンプリエンプティブなスレッドスケジューリング
– プリエンプティブ or ノンプリエンプティブ
©2012 Microsoft Corporation. All Rights Reserved.
2
Agenda
• SQL Server スケジューリングの歴史 (5分)
• SQL Serverのスレッド スケジューリング(25分)
• SQLOS スケジューリング関連コンポーネント(15分)
• 質疑応答 (5分)
©2012 Microsoft Corporation. All Rights Reserved.
3
©2012 Microsoft Corporation. All Rights Reserved.
4
SQL Server スケジューリングの歴史
SQL Server Schedulingの歴史
• SQL Server 6.x
Preemptive Thread
• SQL Server 7/2000
Non-Preemptive Thread (UMS)
• SQL Server 2005/2008/2012
Non-Preemptive Thread (SQLOS)
©2012 Microsoft Corporation. All Rights Reserved.
5
Why non-preemptive scheduling
“RDBMSエンジンに関する調査研究によると、パフォーマンスとスケーラビリティの要件をみたすためには、non-preemptiveスケジューリングの効用が必要だということがわかった。”
“As adequate research shows for RDBMS engine to meet performance and scalability requirements it needs to leverage non-preemptive scheduling.”
From
http://blogs.msdn.com/b/slavao/archive/2005/02/05/367816.aspx
©2012 Microsoft Corporation. All Rights
Reserved. 6
©2012 Microsoft Corporation. All Rights Reserved.
7
SQL Serverのスレッド スケジューリング
PreemptiveとNon-Preemptive
• Preemptive (Windows)
システム (OS) が、CPUを使用するスレッドを決定する。
• Non-Preemptive (SQL Server)
ユーザープログラム(スレッド自身)が、 CPUを使用するスレッドを決定する。
©2012 Microsoft Corporation. All Rights Reserved.
8
Non-Preemptive実現性
• システムの観点から見て、完全なNon-Preemptiveスケジューリングを実装することはできない
• ただし、プロセスという閉じた観点であれば、Non-Preemptiveスケジューリングは実装可能
©2012 Microsoft Corporation. All Rights Reserved.
9
Windowsのスケジューリング
CPUを使用するスレッドが切り替わるタイミング
• クォンタムの終了
実行中のスレッドが割り当てられたクォンタムを使い切った(CPU時間を使い切った)
• 自発的な待機
イベント、セマフォなどの同期オブジェクト上で待機が発生
• プリエンプション
より高い優先度のスレッドによる横取り
©2012 Microsoft Corporation. All Rights Reserved.
10
SQL Server(SQLOS)のスケジューリング
CPUを使用するスレッドが切り替わるタイミング
• SQLOS Yield APIの呼び出し
スレッドが任意のタイミングで自らCPUの使用権を放棄する
• 自発的な待機
同期オブジェクト上での待機が発生
©2012 Microsoft Corporation. All Rights Reserved.
11
SQL Server(SQLOS)のスレッド管理
©2012 Microsoft Corporation. All Rights Reserved.
• Running状態
CPUを使用しているスレッド
• Runnable状態
CPUの使用権を待機しているスレッド (Runnable Queueに存在している)
• Waiting状態
同期オブジェクト上で待機しているスレッド (Wait Queueに存在している)
SQL Server(SQLOS)のスレッド管理
©2012 Microsoft Corporation. All Rights Reserved.
• 具体例の紹介
– SQLOS Yield APIの呼び出し
– 同期オブジェクトの待機とは
SQLOS Yield APIの処理
©2012 Microsoft Corporation. All Rights Reserved.
14
1. コールしたスレッド(自分)をRunnable Queueに追加する
SOS上Runnable, Windows OS上はRunning
2. Runnable Queueで待機している先頭のスレッド
をRunning状態にする
3. 別のスレッドがRunning状態してくれるのを待機する
Windows OS上は待機状態
Preemptiveの世界 (Code Sample)
©2012 Microsoft Corporation. All Rights Reserved.
15
CSample::Execute() { Compile(); Optimize(); Execute(); }
SQLOSの世界 (Code Sample)
©2012 Microsoft Corporation. All Rights Reserved.
16
CSample::Execute() { Compile(); Yield(); Optimize(); Yield(); Execute(); }
Quiz
©2012 Microsoft Corporation. All Rights Reserved.
17
VOID WaitForLockResource (HANDLE hlockEvent) { // // ロックリソースが解放されるまで待機する // WaitForSingleObject(hlockEvent, LOCK_TIMEOUT); }
SQLOSの世界において、次のコードはどこが問題か?
Answer
©2012 Microsoft Corporation. All Rights Reserved.
18
• Running状態(SQLOS上)のまま待機に入っている (CPUを使用しない状態)
• SQLOSの世界では、Windows APIの待機系関数(同期オブジェクト)を直接使用することができない
• SQLOSが提供する同期オブジェクトを使用しなければならない
SQLOS待機系 APIの処理
©2012 Microsoft Corporation. All Rights Reserved.
19
Waitメソッド 1. コールしたスレッド(自分)をWait Queueに追加する
2. Runnable Queueで待機している先頭のスレッドをRunning状態に
する
3. 待機状態に入る(シグナル化待ち) Signalメソッド 1. 同オブジェクトで待機しているスレッドをWait Queueからとりだす
2. 取り出したスレッドを、Runnable Queueに追加する (Runnable状
態にする)
まとめ:SQLOSスレッド状態の遷移
©2012 Microsoft Corporation. All Rights Reserved.
20
• Yield API 呼び出し
Running ---> Runnable (Runnable Queue)
• SOS 待機系 API 呼び出し
Running ---> Waiting (Wait Queue) ---> 同期オブジェクトのシグナル化 ---> Runnable (Runnable Queue)
©2012 Microsoft Corporation. All Rights Reserved.
21
SQLOS スケジューリング コンポーネント
SOS Schedulers
©2012 Microsoft Corporation. All Rights Reserved.
22
• スレッドのスケジューリングを管理しているクラス
インスタンスはDMV sys.dm_os_schedulersで確認できる CPU or Coreを表現するクラス Runnable キューを保持している Yield APIやSOS 待機系 API は最終的に、SOS SchedulerクラスのAPIを呼び出して、スレッドを操作している (SOS上のContextSwitch)
• SOS Schedulerには2つのタイプがある Hidden Scheduler
システム スレッドが所属するスケジューラ
Visible Scheduler
ユーザーリクエストを実行するスレッドが所属するスケジューラ 1 CPU or Core 毎に 1インスタンス生成される
SystemThread and Worker
©2012 Microsoft Corporation. All Rights Reserved.
23
• SystemThread OSのスレッドを表現するクラス
DMV sys.dm_os_threadsで確認できる
スレッドのスレッドローカルストレージ(TLS)に保存されている
• Worker ワーカースレッドを表現するクラス
SystemThreadとバインドされて初めて使用可能となる
DMV sys.dm_os_workersで確認できる
Thread Mode
©2012 Microsoft Corporation. All Rights Reserved.
24
• Non-Preemptive Mode
– SOS Schedulerで管理されているスレッド モード • これまでに説明してきたスレッド、自身でスレッドスケジュー
リングしなければならない
• SQL Serverのほとんどのスレッドは、Non-Preemptiveスレッド
• Preemptive Mode – SOS Schedulerの管理下にないスレッド モード
• SOS 待機系関数を呼び出さないで待機状態となる可能性がある場合
e.g Windows APIコール (GetGroupMember)
SQL Server2012 Preemptive スレッド
©2012 Microsoft Corporation. All Rights Reserved.
25
• ヘルスチェック スレッド
sp_server_diagnosticsスレッド
Lease HandShake スレッド
など
• Preemptiveの必要性
ユーザーリクエストに干渉されないため
Scheduler Monitor
©2012 Microsoft Corporation. All Rights Reserved.
26
• Preemptiveスレッド
• 5秒間隔で各スケジューラを監視
e.g Non-Yielding Scheduler監視 15 秒間 スケジューラを解放しないスレッドがいる (エラーログ17833, mini-dump) How To Diagnose and Correct Errors 17883, 17884, 17887, and 17888 http://msdn.microsoft.com/en-us/library/cc917684.aspx
まとめ
• SQL Server はNon-Preemptiveなスレッドスケジューリングを実装している
• Non-Preemptiveなスレッドは、自身でCPU時間を管理する
• CPU時間の管理(CPUの解放)はSQLOSが提供するAPIを使用している
• 一部のスレッドは、Preemptiveモードで動作する
©2012 Microsoft Corporation. All Rights Reserved.
27
©2012 Microsoft Corporation. All Rights Reserved.
28
質疑応答
©2012 Microsoft Corporation. All Rights Reserved.
29
最後に