SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server 2008 R2 November CTP の UCP について

leave a comment

SQL Server 2008 R2 November CTP の UCP を少し触っているのですが、このバージョンでも、
SQL 2000 ~ 2008 のサポートはされていないみたいです。

UCP を使用するためには以下のクエリで、実行結果として [2] が取得できないといけないようです。

DECLARE @sqlbootvalue int?
EXEC @sqlbootvalue = master.dbo.xp_qv ‘3090395820’, @@SERVICENAME?
SELECT @sqlbootvalue

SQL Server 2008 R2 では実行結果が [2] となるため、有効なエディションとして認識されるのですが、
それ以外のバージョンですと [-1] (VALUE_ERROR) となってしまい、エディションのチェックではじかれます。

[3090395820] が何についての値を取得するための設定値なのかがつかめていないのですが、
現在は、SQL Server 2008 R2 でのみ有効な設定として値が返ってくるようです。

値が [2] 以外の場合は、以下のメッセージを返すようですので、エディションのチェックのような気がしますが、
UCP で管理可能なエディションは制限があるのでしょうか??
Tech Ed では特にエディションの指定については言及していなかった気もするのですが。

メッセージ 37005、レベル 16、状態 1、行 1
ローカル インスタンスをユーティリティ コントロール ポイントで管理できません。
‘xxxxx’ エディションではこの機能は有効ではありません。

?

xp_qv という拡張ストアドプロシージャの存在は今回知りました。
といってもどのように使うものなのかがピンと来ていませんが…。

ドキュメントとしては以下のものに少し記載がされています。

Guidance Addendum
Guidance Addendum / Installation / Startup

xp_qv でのチェックに至るまでには SQL Server 2008 の msdb に UCP で必要となるストアド等を
手動で登録してあげないといけませんでしたが。かなり無理やりこの状態まで持っていっています。
xp_qv のリターン値を無視するように細工して、UCP の管理対象として追加することはできたのですが、
情報のアップロードはうまくいきませんでした。

?

UCP に関しては TechNet Forum でも投稿があったみたいですね。
Can SQL Server 2008 (non-R2) instances by managed by a UCP?

CTP2 の時は R2 のみ追加できるということだったようですが、CTP3 でも同様のようです。
現状の仕組みでは、管理対象の msdb を拡張しないと情報は取得できないようですので、
簡単に統合管理できるというわけでもなさそうですね。

UCP 用のデータアップロードのステップは Power Shell のステップとして登録されているので、
2000 / 2005 では Active X スクリプトタスクあたりになるのでしょうか?

使えるようになる場合は何かしらのアップデートモジュールが提供されるのではないでしょうか。

今回、調べている中で、[xp_msver] という拡張ストアドプロシージャの存在を知りました。
実行すると以下のような情報が取得できます。

Index Name Internal_Value Character_Value
1 ProductName NULL Microsoft SQL Server
2 ProductVersion 655410 10.50.1352.12
3 Language 1041 日本語 (日本)
4 Platform NULL NT x64
5 Comments NULL SQL
6 CompanyName NULL Microsoft Corporation
7 FileDescription NULL SQL Server Windows NT – 64 Bit
8 FileVersion NULL 2009.0100.1352.012 ((KJ_PreRelease).091030-1757 )
9 InternalName NULL SQLSERVR
10 LegalCopyright NULL Microsoft Corp. All rights reserved.
11 LegalTrademarks NULL Microsoft SQL Server is a registered trademark of Microsoft Corporation.
12 OriginalFilename NULL SQLSERVR.EXE
13 PrivateBuild NULL NULL
14 SpecialBuild 88604684 NULL
15 WindowsVersion 393281542 6.0 (6001)
16 ProcessorCount 4 4
17 ProcessorActiveMask NULL f
18 ProcessorType 8664 NULL
19 PhysicalMemory 2047 2047 (2146058240)
20 Product ID NULL NULL

?

環境情報を一括で取得するものとして便利そうです。
[FileVersion] に [KJ] と出力されているところ [Kilimanjaro] のコードネームが見受けられますね。
SQL Server 2008 で実行すると [Katmai] が出力されたりします。

Written by Masayuki.Ozawa

11月 11th, 2009 at 3:32 pm

Posted in SQL Server

SQL Server 2008 R2 November CTP をインストール

leave a comment

DBCC IND の再構成 / 再構築その 2 は明日以降に書くとして、その前に R2 の最新の CTP を
インストールしてみたいと思います。

現在、SQL Server の検証で使用している、2005 / 2008 がインストールされている環境に
名前付きインスタンスとしてインストールしたいと思います。
OS はまだバージョンアップしていないので Windows Server 2008 を使用しています。

  1. インストールメディアをいれてインストーラーを起動します。
  2. [インストール] → [新規インストールを実行するか~] をクリックします。
    ?image
  3. [OK] をクリックします。
    image
  4. [次へ] をクリックします。
    選択できるエディションは、[Enterprise Evaluation] [Express] [Express with Advanced Services] の
    3 種類となっています。
    今回は [Enterprise Evaluation] で。
    image
  5. [使用許諾契約書に同意する] を有効にして、[次へ] をクリックします。
    image?
  6. [インストール] をクリックします。
    image
  7. [OK] をクリックし、手動で再起動します。
    image
  8. 再起動後、再度インストーラーを起動して、セットアップを継続します。
  9. [次へ] をクリックします。
    image
  10. エディションを選択して、[次へ] をクリックします。
  11. [使用許諾契約書に同意する] を有効にして、[次へ] をクリックします。
  12. [SQL Server 機能のインストール] を選択して、[次へ] をクリックします。
    image
  13. インストールする機能を選択して、[次へ] をクリックします。
    ?image
  14. [次へ] をクリックします。
    image
    今回は共存環境ですので共有コンポーネントで警告が発生しています。
    image
  15. インスタンス名を入力して、[次へ] をクリックします。
    image
  16. [次へ] をクリックします。
    image
  17. サービスアカウントと照合順序を選択して、[次へ] をクリックします。
    ?image? image
    照合順序はデフォルトが [Japanese_CI_AS] となっています。
    最新の日本語の照合順序は SQL Server 2008 と同じで [Japanese_XJIS_100] みたいです。
  18. 管理者アカウントと、ディレクトリ、FILESTREAM の設定をして [次へ] をクリックします。
    image image
    image
  19. 今回は Reporing Services もインストール対象としていたので設定画面が表示されます。
    Reporting Services は後で構成したいので、[レポート サーバーを構成せずにインストールする] を選択して、
    [次へ] をクリックします。
    image
  20. [次へ] をクリックします。
    image
  21. [次へ] をクリックします。
    image
  22. [インストール] をクリックします。
    image image
  23. [OK] をクリックします。
    image
  24. [閉じる] をクリックします。
    image
  25. [OK] をクリックして、手動で再起動します。
    image

以上でインストール完了です。

UCP の設定画面も日本語になっていますね~。

image?

機能は少しずつ確認していきたいと思います。

Written by Masayuki.Ozawa

11月 10th, 2009 at 3:38 pm

Posted in SQL Server

DBCC IND で確認するインデックスの再構成と再構築の違い その 1

leave a comment

SQL Server のインデックスのメンテナンスには

  • 再構成 (REORGANIZE / DEFRAG)
  • 再構築 (REBUILD)

の 2 種類があります。

2 種類の違いを 2 回の投稿に分けてまとめていきたいと思います。

まずは、前回使用した SQL データを挿入して、DBCC IND でページの情報を取得してみました。
# 一度 Truncate でデータをクリアして再挿入しています。

– 結果 1 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 3976 Tbl1 PK_Tbl1 1 0 3977 0
2 WORK 3977 Tbl1 PK_Tbl1 1 0 3978 3976
3 WORK 3978 Tbl1 PK_Tbl1 1 0 3979 3977
4 WORK 3979 Tbl1 PK_Tbl1 1 0 3980 3978
5 WORK 3980 Tbl1 PK_Tbl1 1 0 3981 3979
6 WORK 3981 Tbl1 PK_Tbl1 1 0 3982 3980
7 WORK 3982 Tbl1 PK_Tbl1 1 0 3983 3981
8 WORK 3983 Tbl1 PK_Tbl1 1 0 3984 3982
9 WORK 3984 Tbl1 PK_Tbl1 1 0 3985 3983
10 WORK 3985 Tbl1 PK_Tbl1 1 0 3986 3984
11 WORK 3986 Tbl1 PK_Tbl1 1 0 3987 3985
12 WORK 3987 Tbl1 PK_Tbl1 1 0 0 3986

?

この状態で、前回使用したクラスタ化インデックス更新の SQL を実行して断片化を発生させます。

– 結果 2 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 3976 Tbl1 PK_Tbl1 1 0 3988 0
2 WORK 3977 Tbl1 PK_Tbl1 1 0 4042 4040
3 WORK 3978 Tbl1 PK_Tbl1 1 0 4044 4043
4 WORK 3979 Tbl1 PK_Tbl1 1 0 4046 4045
5 WORK 3980 Tbl1 PK_Tbl1 1 0 3989 4046
6 WORK 3981 Tbl1 PK_Tbl1 1 0 4049 4048
7 WORK 3982 Tbl1 PK_Tbl1 1 0 4051 4049
8 WORK 3983 Tbl1 PK_Tbl1 1 0 4052 4050
9 WORK 3984 Tbl1 PK_Tbl1 1 0 4055 4053
10 WORK 3985 Tbl1 PK_Tbl1 1 0 3990 4055
11 WORK 3986 Tbl1 PK_Tbl1 1 0 4056 3990
12 WORK 3987 Tbl1 PK_Tbl1 1 0 0 4056
13 WORK 3988 Tbl1 PK_Tbl1 1 0 4040 3976
14 WORK 3989 Tbl1 PK_Tbl1 1 0 4047 3980
15 WORK 3990 Tbl1 PK_Tbl1 1 0 3986 3985
16 WORK 4040 Tbl1 PK_Tbl1 1 0 3977 3988
17 WORK 4041 Tbl1 PK_Tbl1 1 0 4043 4042
18 WORK 4042 Tbl1 PK_Tbl1 1 0 4041 3977
19 WORK 4043 Tbl1 PK_Tbl1 1 0 3978 4041
20 WORK 4044 Tbl1 PK_Tbl1 1 0 4045 3978
21 WORK 4045 Tbl1 PK_Tbl1 1 0 3979 4044
22 WORK 4046 Tbl1 PK_Tbl1 1 0 3980 3979
23 WORK 4047 Tbl1 PK_Tbl1 1 0 4048 3989
24 WORK 4048 Tbl1 PK_Tbl1 1 0 3981 4047
25 WORK 4049 Tbl1 PK_Tbl1 1 0 3982 3981
26 WORK 4050 Tbl1 PK_Tbl1 1 0 3983 4051
27 WORK 4051 Tbl1 PK_Tbl1 1 0 4050 3982
28 WORK 4052 Tbl1 PK_Tbl1 1 0 4054 3983
29 WORK 4053 Tbl1 PK_Tbl1 1 0 3984 4054
30 WORK 4054 Tbl1 PK_Tbl1 1 0 4053 4052
31 WORK 4055 Tbl1 PK_Tbl1 1 0 3985 3984
32 WORK 4056 Tbl1 PK_Tbl1 1 0 3987 3986

?

[PagePID] が 3976 ~3990 , 4040 ~ 4056 が使用されているのが確認できます。

この状態で再構成と再構築を実行して違いを確認したいと思います。

[インデックスの再構成]

以下の SQL を実行してインデックスを再構成してみます。

ALTER INDEX [PK_Tbl1] ON [dbo].[Tbl1] REORGANIZE

再構成後に DBCC IND を実行して、ページの情報を取得します。

– 結果 3 –

No FILEName PagePID ObjectName name PageType IndexLevel Nex
tPagePID
PrevPagePID
1 WORK 3976 Tbl1 PK_Tbl1 1 0 3977 0
2 WORK 3977 Tbl1 PK_Tbl1 1 0 3978 3976
3 WORK 3978 Tbl1 PK_Tbl1 1 0 3979 3977
4 WORK 3979 Tbl1 PK_Tbl1 1 0 3980 3978
5 WORK 3980 Tbl1 PK_Tbl1 1 0 3981 3979
6 WORK 3981 Tbl1 PK_Tbl1 1 0 3982 3980
7 WORK 3982 Tbl1 PK_Tbl1 1 0 3983 3981
8 WORK 3983 Tbl1 PK_Tbl1 1 0 3984 3982
9 WORK 3984 Tbl1 PK_Tbl1 1 0 3985 3983
10 WORK 3985 Tbl1 PK_Tbl1 1 0 3986 3984
11 WORK 3986 Tbl1 PK_Tbl1 1 0 3987 3985
12 WORK 3987 Tbl1 PK_Tbl1 1 0 0 3986

?

[PagePID] 3976 ~ 3987 を使用して断片化が解消されています。

それでは再度断片化を発生させて、インデックスの再構築をしてみたいと思います。
断片化を発生させたところ、[PagePID] 3976 ~ 3989 , 4064 ~ 4079 が使用されていました。

[インデックスの再構築]

以下の SQL を実行してインデックスを再構築します。

ALTER INDEX [PK_Tbl1] ON [dbo].[Tbl1] REBUILD

DBCC IND を実行してページの情報を取得します。

– 結果 4 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 4080 Tbl1 PK_Tbl1 1 0 4088 0
2 WORK 4088 Tbl1 PK_Tbl1 1 0 4089 4080
3 WORK 4089 Tbl1 PK_Tbl1 1 0 4090 4088
4 WORK 4090 Tbl1 PK_Tbl1 1 0 4091 4089
5 WORK 4091 Tbl1 PK_Tbl1 1 0 4092 4090
6 WORK 4092 Tbl1 PK_Tbl1 1 0 4093 4091
7 WORK 4093 Tbl1 PK_Tbl1 1 0 4094 4092
8 WORK 4094 Tbl1 PK_Tbl1 1 0 4095 4093
9 WORK 4095 Tbl1 PK_Tbl1 1 0 4096 4094
10 WORK 4096 Tbl1 PK_Tbl1 1 0 4097 4095
11 WORK 4097 Tbl1 PK_Tbl1 1 0 4098 4096
12 WORK 4098 Tbl1 PK_Tbl1 1 0 0 4097

?

[PagePID] 4080 ~ 4098 を使用して断片化が解消されています。

?

インデックスの再構成と再構築では、既に割り当てられている領域を使用するか、新規に領域を割り当てるかの違いがあります。

インデックスの再構成では既に割り当てられている領域を利用して断片化の解消を行います。
そのため、断片化が発生した際に割り当てられていた [PagePID] と同様のページが使用されています。
断片化解消のために新たなエクステントが割り当てられることがありません。

それに対してインデックスの再構築は新規のページを使用して断片化の解消が行われます。
インデックスの再作成に近い形で断片化の解消が行われていたはずです。
新規のエクステントに断片化解消後のインデックスを作成し、作成が終了したらそれまで使用していた領域を
空きページとして解放するようです。

再構成も再構築も断片化の解消により、未使用になったページは他のオブジェクトでも使用可能なように解放されますが、
既存ページの利用か新規ページの割り当てかの違いがありますので、処理終了後の未使用領域には差が出てきます。

?

再構成は既存のページ内での並び替えですが、再構築は再作成を行います。
そのため、再構成と再構築では処理終了後に使用している [PagePID] に違いが出てきます。
あまりにも断片化が発生していると再構成の並び替えに時間がかかり、再構築のほうが早い場合もあったりします。

再構成と再構築の違いは領域の再利用だけでなく、エクステントの並び替えでの動作に関しても違いがあります。
これに関しては次回の投稿でまとめたいと思います。

Written by Masayuki.Ozawa

11月 10th, 2009 at 2:12 pm

Posted in SQL Server

SQL Server 2008 R2 November CTP が TechNet / MSDN で提供開始されました

leave a comment

朝、TechNet / MSDN の会員向けサイトの RSS を確認していたところ、提供が開始されていました。

image

今回の CTP では日本語版のダウンロードも可能となっています。

帰ったら自宅の SQL Server 検証環境にインストールしてみたいです。

Written by Masayuki.Ozawa

11月 9th, 2009 at 10:34 pm

Posted in SQL Server

Exchange 2010 が TechNet / MSDN でダウンロード可能に

leave a comment

TechNet / MSDN の会員向けサイトで Exchange 2010 がダウンロード可能になりました!!

時間がある時に検証環境を Exchange 2007 から 2010 に移行してみたいと思います。

image

Windows Server 2008 R2 上で Exchange 2007 の実行に関しては更新プログラムが提供されたら、
別の環境を構築して試してみようかな。

Written by Masayuki.Ozawa

11月 9th, 2009 at 3:00 pm

Posted in Exchange

DBCC IND を使用したページの連続性の確認

leave a comment

ここ数日は SQL Server の基礎から勉強しなおそうと思い、インデックスの再構築 / 再構成について調べていました。
データの更新を行っているとデータページの断片化が発生し、断片化解消のためにインデックスの再構築 (REBUILD)、
再構成 (REORGANIZE) が必要となります。

ページの連続性が確認できないかなと思い、いろいろと本を眺めていたところ、[DBCC IND] があったなと思い、
少し試してみました。
# SQL Server の投稿に関しては SQL Server 2008 で検証をしていきたいと思います。

まずはテスト用として以下のテーブルを作成しました。

CREATE TABLE [dbo].[Tbl1](
??? [Col1] [uniqueidentifier] NOT NULL,
??? [Col2] [nchar](400) NULL,
CONSTRAINT [PK_Tbl1] PRIMARY KEY CLUSTERED
(
??? [Col1] ASC
)WITH (PAD_INDEX? = OFF, STATISTICS_NORECOMPUTE? = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS? = ON, ALLOW_PAGE_LOCKS? = ON) ON [PRIMARY]
) ON [PRIMARY]

GUID と NCHAR で構成された単純なテーブルです。
このテーブルに以下の SQL でデータを挿入して、インデックスを再構築して断片化を解消した状態にします。

— テーブルにデータを挿入
DECLARE @i int = 1
WHILE (@i <= 100)
BEGIN
??? INSERT INTO [dbo].[Tbl1] VALUES(NEWID(), NCHAR(@i))
??? SET @i +=1
END

— 主キーが GUID のため、データ挿入後は断片化が発生しているためクラスタ化インデックスを再構築
ALTER INDEX [PK_Tbl1] ON [dbo].[Tbl1] REBUILD

?

この状態で DBCC IND を実行して、ページの連続性を確認してみました。

— DBCC IND の実行結果を格納するテーブル変数の定義
DECLARE @Tbl TABLE(
PageFID int,
PagePID int,
IAMFID int,
IAMPID int,
ObjectID int,
IndexId int,
PartitionNumber bigint,
PartitionID bigint,
iam_chain_type sysname,
PageType int,
IndexLevel int,
NextPageFID int,
NextPagePID int,
PrevPageFID int,
PrevPagePID int
)

— テーブル変数に DBCC IND の実行結果を格納
— 1 を指定することでデータページ (ヒープまたはクラスタ化インデックス) を対象とする
INSERT INTO @Tbl EXEC (‘DBCC IND(N”WORK”,N”dbo.Tbl1”, 1)’)

— DBCC IND の結果から必要な列を取得
SELECT
????ROW_NUMBER() OVER (ORDER BY [PagePID] ASC) AS [No],
??? FILE_NAME([PageFID]) AS [FILEName],
??? [PagePID],
??? OBJECT_NAME([ObjectID]) AS [ObjectName],
??? [name],
??? [PageType],
??? [IndexLevel],
??? [NextPagePID],
??? [PrevPagePID]
FROM
??? @Tbl
??? LEFT JOIN
??? [sys].[indexes]
??? ON
??? [@Tbl].[ObjectID] = [sys].[indexes].[object_id]
??? AND
??? [@Tbl].[IndexId] = [sys].[indexes].[index_id]
WHERE
??? [PageType] = 1
ORDER BY
??? [PagePID] ASC

?

以下の実行結果が取得できます。

– 結果 1 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 3328 Tbl1 PK_Tbl1 1 0 3336 0
2 WORK 3336 Tbl1 PK_Tbl1 1 0 3337 3328
3 WORK 3337 Tbl1 PK_Tbl1 1 0 3338 3336
4 WORK 3338 Tbl1 PK_Tbl1 1 0 3339 3337
5 WORK 3339 Tbl1 PK_Tbl1 1 0 3340 3338
6 WORK 3340 Tbl1 PK_Tbl1 1 0 3341 3339
7 WORK 3341 Tbl1 PK_Tbl1 1 0 3342 3340
8 WORK 3342 Tbl1 PK_Tbl1 1 0 3343 3341
9 WORK 3343 Tbl1 PK_Tbl1 1 0 3344 3342
10 WORK 3344 Tbl1 PK_Tbl1 1 0 3345 3343
11 WORK 3345 Tbl1 PK_Tbl1 1 0 3346 3344
12 WORK 3346 Tbl1 PK_Tbl1 1 0 0 3345

?

ここで確認したい内容が [NextPagePID] と [PrepPagePID] です。
この値が対象のページに対しての前後のページ ID となります。

クラスタ化インデックスの再構築後の状態を取得していますので、データの連続性が保たれています。

この状態でクラスタ化インデックスを更新して断片化を発生させます。

UPDATE [dbo].[Tbl1] SET [Col1] = NEWID()

再度、DBCC IND を実行してページの情報を取得します。

– 結果 2 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 3328 Tbl1 PK_Tbl1 1 0 3330 0
2 WORK 3329 Tbl1 PK_Tbl1 1 0 3332 3331
3 WORK 3330 Tbl1 PK_Tbl1 1 0 3331 3328
4 WORK 3331 Tbl1 PK_Tbl1 1 0 3329 3330
5 WORK 3332 Tbl1 PK_Tbl1 1 0 3336 3329
6 WORK 3333 Tbl1 PK_Tbl1 1 0 3337 3336
7 WORK 3334 Tbl1 PK_Tbl1 1 0 3335 3337
8 WORK 3335 Tbl1 PK_Tbl1 1 0 3338 3334
9 WORK 3336 Tbl1 PK_Tbl1 1 0 3333 3332
10 WORK 3337 Tbl1 PK_Tbl1 1 0 3334 3333
11 WORK 3338 Tbl1 PK_Tbl1 1 0 3347 3335
12 WORK 3339 Tbl1 PK_Tbl1 1 0 3441 3347
13 WORK 3340 Tbl1 PK_Tbl1 1 0 3443 3442
14 WORK 3341 Tbl1 PK_Tbl1 1 0 3444 3443
15 WORK 3342 Tbl1 PK_Tbl1 1 0 3445 3444
16 WORK 3343 Tbl1 PK_Tbl1 1 0 3446 3445
17 WORK 3344 Tbl1 PK_Tbl1 1 0 3456 3447
18 WORK 3345 Tbl1 PK_Tbl1 1 0 3457 3348
19 WORK 3346 Tbl1 PK_Tbl1 1 0 0 3458
20 WORK 3347 Tbl1 PK_Tbl1 1 0 3339 3338
21 WORK 3348 Tbl1 PK_Tbl1 1 0 3345 3456
22 WORK 3440 Tbl1 PK_Tbl1 1 0 3442 3441
23 WORK 3441 Tbl1 PK_Tbl1 1 0 3440 3339
24 WORK 3442 Tbl1 PK_Tbl1 1 0 3340 3440
25 WORK 3443 Tbl1 PK_Tbl1 1 0 3341 3340
26 WORK 3444 Tbl1 PK_Tbl1 1 0 3342 3341
27 WORK 3445 Tbl1 PK_Tbl1 1 0 3343 3342
28 WORK 3446 Tbl1 PK_Tbl1 1 0 3447 3343
29 WORK 3447 Tbl1 PK_Tbl1 1 0 3344 3446
30 WORK 3456 Tbl1 PK_Tbl1 1 0 3348 3344
31 WORK 3457 Tbl1 PK_Tbl1 1 0 3459 3345
32 WORK 3458 Tbl1 PK_Tbl1 1 0 3346 3459
33 WORK 3459 Tbl1 PK_Tbl1 1 0 3458 3457

断片化の発生により、ページ数が倍以上に増えています。
PagePID 3338 のレコードを見てみると、次のページが [3347] となっています。
他にも前後のページが連続していないレコードがちらほらと見受けられます。
この状態が断片化が発生している状態ですね。

ALTER INDEX ~ REBUILD を実行して、ページを確認してみます。

– 結果 3 –

No FILEName PagePID ObjectName name PageType IndexLevel NextPagePID PrevPagePID
1 WORK 3464 Tbl1 PK_Tbl1 1 0 3472 0
2 WORK 3472 Tbl1 PK_Tbl1 1 0 3473 3464
3 WORK 3473 Tbl1 PK_Tbl1 1 0 3474 3472
4 WORK 3474 Tbl1 PK_Tbl1 1 0 3475 3473
5 WORK 3475 Tbl1 PK_Tbl1 1 0 3476 3474
6 WORK 3476 Tbl1 PK_Tbl1 1 0 3477 3475
7 WORK 3477 Tbl1 PK_Tbl1 1 0 3478 3476
8 WORK 3478 Tbl1 PK_Tbl1 1 0 3479 3477
9 WORK 3479 Tbl1 PK_Tbl1 1 0 3480 3478
10 WORK 3480 Tbl1 PK_Tbl1 1 0 3481 3479
11 WORK 3481 Tbl1 PK_Tbl1 1 0 3482 3480
12 WORK 3482 Tbl1 PK_Tbl1 1 0 0 3481

結果 1 と同じレコード数となり、ページ番号も連続しています。
断片化が解消されているのがページ数とページの連続性から確認ができますね。

DBCC IND を使用すると、インデックスの再構築と再構成の動作の違いを確認することも可能です。
こちらについては次回投稿したいと思います。
# 結果 2 と結果 3 ではPagePID が変わっているのですが、これがインデックスの再構築と再構成の違いでもあります。

Written by Masayuki.Ozawa

11月 9th, 2009 at 2:54 pm

Posted in SQL Server

tempdb の自動拡張と再起動後の初期サイズについて

leave a comment

SQL Server のデータベースは自動拡張設定を使用することで、データベースの割り当て領域が不足した際に、
自動的に拡張するように設定することができます。

SQL Server のソート等で使用される tempdb にもこの設定は適用することが可能です。

tempdb の領域が不足するとソート時などに以下のエラーが発生します。

メッセージ 1105、レベル 17、状態 2、行 1
データベース ‘tempdb’ にオブジェクト ‘dbo.SORT temporary run storage:? 140737491501056′ の領域を割り当てられませんでした。’PRIMARY’ ファイル グループがいっぱいです。不要なファイルの削除、ファイル グループ内のオブジェクトの削除、ファイル グループへの新しいファイルの追加、またはファイル グループの既存のファイルの自動拡張の設定のいずれかを行ってディスク領域を作成してください。

# tempdb にはソートの一時結果が保存されますので、これはメモリ上でソートができる場合でも保存されますので、
  メモリが足りていても tempdb が足りていないとソートに失敗します。

保険のために自動拡張を有効にして領域不足を解消するのは有効だと思います。

ただし、tempdb はサービスが再起動するタイミングで再作成されています。
自動拡張がされていても、サービスが再起動されると、明示的に設定をしていたサイズで再作成され、
自動拡張後のサイズはクリアされてしまいます。

[自動拡張前の tempdb のサイズ]

image

現在は 8.5MB 割り当てられています。

この状態で 600MB 程度のデータが入っているテーブルをソートしてみます。

[自動拡張後の tempdb のサイズ]

image

671MB まで拡張されました。

今の設定では 10% 単位で拡張がされるようになっています。
自動拡張のイベントを確認してみると、データファイルの自動拡張イベントが大量に出力されています。

image

今回の自動拡張イベントの処理時間の合計だけで、[34,939 ミリ秒] かかっています。
自動拡張の発生で 30 秒。処理時間としてはもったいないですね。
# 瞬時初期化ありの状態でこの秒数です。

今回はクエリエディタから実行しているのでタイムアウトしていませんが、プログラムから実行した場合は、
クエリタイムアウトの秒数に引っ掛かりエラーとなる可能性も。

この状態で、SQL Server のサービスを再起動してみます。

[再起動後の tempdb のサイズ]

image

再起動後は初期サイズの 8.5MB になってしまっています。

これは、ユーザーデータベースの場合は自動拡張が発生すると、初期サイズが変更されるのですが、tempdb に関しては
自動拡張が発生しても初期サイズが変更されないためです。

自動拡張後にデータベースのプロパティを確認してみると、600MB 超のサイズが初期設定にはなっておらず、
明示的に設定したサイズとなっています。
image?

サーバーの定期メンテナンス等で SQL Server を再起動する前に、tempdb の現在のサイズを確認して、
初期サイズの見直しが必要かの判断は重要かな~と思います。

Written by Masayuki.Ozawa

11月 7th, 2009 at 2:27 pm

Posted in SQL Server

SQL Server の専用管理者接続について

leave a comment

前回の投稿でシステムテーブルの更新には、専用管理者接続 (Dedicated Administrator Connection : DAC) を
使用すると書きました。

DAC は SQL Server 2005 からの機能で、SQL Server の応答が無くなった時に、トラブルシューティング等を
するために使用します。

デフォルトでは SQL Server をインストールしているサーバー (127.0.0.1) からのみ接続ができるようになっています。
以下の SQL を実行することで、リモートからも DAC による接続が可能となります。

sp_configure ‘remote admin connections’, 0
go
RECONFIGURE WITH OVERRIDE
go

?

DAC ですがクラスタ環境の場合、ローカルの接続でもリモート DAC が有効になっていないと接続することができません。
このことは BOL にも記載されています。

クラスタ構成では、DAC は既定でオフになります。ユーザーは、sp_configureremote admin connection オプションを実行すると、DAC リスナを有効にしてリモート接続にアクセスできます。
SQL Server が応答せず、DAC リスナが有効になっていない場合は、DAC で接続するために SQL Server を再起動する必要が生じる場合があります。
この理由から、クラスタ システムでは remote admin connections 構成オプションを有効にすることをお勧めします。

?

DAC の接続ですが、SQL Server Browser サービスが起動しているかによって接続方法が変わってきます。

[SQL Server Browser サービスが起動している場合]

こちらは前回の投稿で記載した接続方法になります。
接続先のサーバーとして、[ADMIN:<サーバー名><インスタンス名>] を指定することで接続ができます。

image

[SQL Server Browser サービスが起動していない場合 ]

SQL Server Browser サービスが起動していない状態で [ADMIN:~] で接続をすると、以下のエラーとなります。
image

ADMIN: での接続は DAC で使用しているポートを SQL Server Browser サービスに問い合わせています。
# DAC のポートは動的ポートのため、起動毎にポートが変更されます。
サービスが起動していないとポートがわからないため接続することができません。

DAC に割り当てられているポートは [ERRORLOG] ファイルに出力されています。
# ERRORLOG は SQL Server のインスタンスのインストールディレクトリの [Log] ディレクトリに出力されています。

image

このファイルをテキストエディタで開くと以下のような出力があります。

2009-11-05 23:02:19.60 サーバー??????? Dedicated admin connection support was established for listening remotely on port 50743.

この行に DAC のポート番号が出力されています。
今回の場合は [50743] となっています。

ローカルから接続する場合、サーバー名の指定は [127.0.0.1,<ポート番号>] になります。
# 対象インスタンスの DAC のポートを直接指定するため、インスタンス名は不要です。

image

リモートから接続する場合は、[<サーバー>,<ポート番号>] になります。

image

DAC を使用して何か障害を解決したということは今のところないのですが、接続方法は知っておくと
障害発生時に便利かと。

Written by Masayuki.Ozawa

11月 5th, 2009 at 3:16 pm

Posted in SQL Server

SQL Server 2005 以降でシステムテーブルを直接更新する方法

leave a comment

このところ SQL Server をインストール以外触っておらず、データベース管理者としてのスキルが右肩下がりです…。
このままでは SQL Server のデータベース管理者としてお先真っ暗となってしまいますので、小さなことでもコツコツと
投稿していきたいと思います。

思い立った初回は SQL Server 2005 以降でシステムテーブルを直接更新する方法を投稿したいと思います。

SQL Server 2000 までは sp_configure で [allow updates オプション] を設定することでシステムテーブルを
直接更新することが可能でした。

SQL Server 2005 以降の Books Online では allow update オプションの説明は以下のように記載されています。
# 今回は SQL Server 2008 で検証をしていますが、2005 でも同様の動作となります。

このオプションは sp_configure ストアド プロシージャにまだ含まれていますが、
その機能を SQL Server で使用することはできません。設定しても何の影響もありません。
SQL Server 2005 以降のバージョンでは、システム テーブルの直接更新はサポートされていません。

allow updates オプションを変更すると、RECONFIGURE ステートメントが失敗します。
allow updates オプションへの変更は、すべてのスクリプトから削除する必要があります。

?

実際に SQL Server 2008 で? allow updates を設定すると以下の実行結果となります。

sp_configure ‘allow updates’, 1
GO
RECONFIGURE
GO

[実行結果]

構成オプション ‘allow updates’ が 0 から 1 に変更されました。RECONFIGURE ステートメントを実行してインストールしてください。
メッセージ 5808、レベル 16、状態 1、行 1
システム カタログへのアドホック更新はサポートされていません。

?

RECONFIGURE をするとエラーとなります。
RECONFIGURE WITH OVERRIDE することで設定ができます。

この状態で、sysdatabases のようなシステムテーブルに更新をかけると以下のようなエラーとなります。
# SQL Server 2005 以降では sysdatabases は下位互換のシステムビューで実体は master.sys.sysdbreg だったりしますが。

update sys.sysdatabases set status = status|32768 where dbid = 5

[実行結果]

メッセージ 259、レベル 16、状態 1、行 1
システム カタログへのアドホック更新は許可されません。

?

SQL Server 2005 以降でシステムテーブルを更新するには以下の手順を実行して SQL Server に接続する必要があります。

  1. SQL Server をシングルユーザーモードで起動
  2. 専用管理者接続 (DAC) で接続

[シングルユーザーモードで起動する方法]

シングルユーザーモードで起動する前に、SQL Server 関連のサービスをすべて停止しておきます。
シングルユーザーモードはその名の通り、一人しか接続ができないモードですので SQL Server Agent や、
SSRS / SSIS / SSAS が起動していると、それらのサービスが SQL Server に接続してしまい、データベースエンジンクエリで
接続ができなくなってしまいます。
シングルユーザーモードで起動した後に、接続をしようとして エラー 18461 が発生する場合は、SQL Server 以外の
関連サービスを停止して確認をした方がよいと思います。

image

シングルユーザーモードはコマンドプロンプトで SQL Server を実行することで起動できます。

cd <インスタンスのプログラムディレクトリ>
sqlservr.exe ?m ?s <インスタンス名>

[実行例]
cd “c:Program FilesMicrosoft SQL ServerMSSQL10.SQL2008MSSQLBinn”
sqlservr.exe ?m ?s SQL2008

?

[DAC で接続]

DAC で接続する場合は接続時にサーバー名に [ADMIN:] をつけて接続をします。
今回はサーバーで直接作業をしています。
# リモートで DAC を使用することも可能ですがその場合は別の設定をする必要があります。

image

これでシステムテーブルを更新する準備は完了です。
allow updates は SQL Server 2005 以降では無効なオプションですので、設定をしなくてもシステムテーブルを
更新することが可能です。

試しにシステムテーブルを直接更新してデータベースをエマージェンシー (緊急) モードに設定したいと思います。
sysdatabases / sys.database はビューですので、各ビューの実体である sysdbreg テーブルを直接更新しています。
# use mssqlsystemresource を実行してリソースデータベース上で更新をしようとするとエラーとなりますので
  カレントデータベースは master データベース等で実行する必要があります。

update master.sys.sysdbreg set status = status|32768 where id = 5

[実行結果]

警告: システム テーブル ID 28 がデータベース ID 1 で直接更新されました。
キャッシュの一貫性が維持されていない可能性があります。SQL Server を再起動してください。

(1 行処理されました)

# ビット演算で status にエマージェンシーモードに対応するビットを有効にしています。

下が SQL 実行後の状態になります。
ALTER DATABASE ではなく、システムテーブルの直接更新でエマージェンシーモードに切り替わっています。

image

確認ができたのでシステムテーブルを更新できる状態にして以下の SQL を実行して正常な状態に戻しておきます。

update master.sys.sysdbreg set status = 0 where id = 5

?

以上でシステムテーブルの更新方法は終了です。
使うことがあるかはわかりませんが、奥の手として知っておくと便利な時があるかも知れません。

Written by Masayuki.Ozawa

11月 4th, 2009 at 3:26 pm

Posted in SQL Server

AD 降格時に Exchange 管理コンソールでエラーになった件の続き

leave a comment

Windows Server 2008 AD DS を Windows Server 2008 R2 AD DS に移行し、2008 AD DS を
降格させたときに Exchange Server 2010 RC の管理コンソール (EMC) を開くと Active Directory の
0x51 のエラーが発生してしまう件ですが、Exchange 2010 を OS 毎入れなおしたところ、
エラーが発生しなくなりました…。

再度 2008 AD DS をインストールして、降格させたところ現象が再現。

Set-ExchangeServer コマンドレットの、StaticDomainControllers / StaticConfigDomainController
StaticExcludedDomainControllers / StaticGlobalCatalogs を設定しても解決しませんでした。

また、AD の構成パーティションに情報が残っているのかと思って ldifde で構成パーティションを
エクスポートして一通り調べてみたのですが、2008 AD DS の情報は残っていませんでした。

他のユーザーで EMC を実行したところ、エラーが発生しなかったのでユーザー固有の問題かと思って、
エラーが発生しているユーザーのプロファイルを削除して、再度 EMC を実行したらエラーが発生しなくなりました。

Exchange や AD 側の問題ではなく、ユーザープロファイルの中に何か情報が残ってしまっていたのでしょうか??
具体的な解決策までたどり着いていないのですがメモとして残しておきたいと思います。

Written by Masayuki.Ozawa

11月 3rd, 2009 at 2:19 pm

Posted in Exchange