SE の雑記

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

PFS / GAM / DCM / は何ページごとに存在する??

one comment

SQL Server には Allocation Page として、PFS / GAM / SGAM / IAM / DCM / BCM というような管理ページがあります。

SQL Server のページ情報のヘッダには、[m_prevPage] [m_nextPage] という前ページ、次ページの情報が格納されています。
Allocation Page がフルになった時に、このヘッダ情報がどのようになるのだろうということが気になり調べてみました。

■ページヘッダを取得してテーブル化

ページヘッダは [DBCC PAGE] を使用して取得することが可能です。
以下のようなクエリで取得可能です。

DBCC TRACEON(3604)
DBCC PAGE(N’TEST’, 1, 6, 1)
DBCC TRACEOFF(3604)

 

DBCC PAGE の実行結果は、[WITH TABLERESULTS] を使用することで表形式で取得することができます。
image

ヘッダ情報を [INSERT INTO ~ EXEC (‘DBCC PAGE ~’)] でテーブルに格納すると、ヘッダ情報が調べやすくなると思い、以下のようなクエリを作ってみました。

SET NOCOUNT ON
GO
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS
GO
DBCC TRACEON(3604) WITH NO_INFOMSGS

DECLARE @tbl Table(
    ParentObject nvarchar(20),
    Object nvarchar (50),
    Field nvarchar(50),
    VALUE nvarchar(50)
)

DECLARE @DBCCTbl Table (
    no int IDENTITY,
    bpageno nvarchar(50),
    m_type int,
    ObjectId int,
    IndexId int,
    m_prevPage nvarchar(50),
    m_nextPage nvarchar(50)
)

DECLARE @stratpage int = 1
DECLARE @endpage int = 30000
DECLARE @pagetype nvarchar(2) = 11

/*
    Data:1     Index:2    Lob3:3     Lob4:4
    Sort:7    GAM:8    SGAM:9    IAM:10
    PFS:11    Boot:13    FileHeader:15
    DCM:16    BCM:17
*/

WHILE (@stratpage <= @endpage)
BEGIN
    INSERT INTO @tbl
    EXEC (‘DBCC PAGE(”TEST”, 1, ‘ + @stratpage + ‘, 0) WITH TABLERESULTS,NO_INFOMSGS’)
   
    INSERT INTO
        @DBCCTbl (bpageno,
                m_type,
                ObjectId,
                IndexId,
                m_nextPage,
                m_prevPage)
    SELECT
        *
    FROM
        (SELECT Field,VALUE
         FROM @tbl
        ) AS SourceTable
    PIVOT
    (
        MAX(VALUE)
        FOR Field IN ([bpageno], [m_type], [Metadata: ObjectId], [Metadata: IndexId], [m_nextPage], [m_prevPage])
    ) AS PivotTable
   
    DELETE FROM @tbl
    SET @stratpage += 1
END
DBCC TRACEOFF(3604)  WITH NO_INFOMSGS

SELECT * FROM  @DBCCTbl WHERE m_type = @pagetype ORDER BY no ASC

stratpage と endpage で検索するページの範囲を指定して、pagetype で検索する Allocation Page の種類を指定します。
pagetype の種類に関してはコメントでクエリ内に記載していますが、このような種類があります。
# pagetype に関しては、Internals Viewer for SQL Server のソースコードを参考にさせていただいています。
# 初期の情報格納を nvarchar(50) にしてしまっていたり、INSERT 時に暗黙の型変換が発生しているはずだったりと結構荒い作りですが。

 

■m_prevPage と m_nextPage


SQL Server のテーブルのレコードはページの集まりとなっています。
ページ間はページヘッダの m_prevPage / m_nextPage でつながれています。
image

前や先にページが無い場合は 0 となります。
それでは、先ほどのクエリを使用してデータページ (m_type=1) の m_prevPage と m_nextPage を見たいと思います。
image
データを断片化しないように INSERT していますのできれいにページが連続して並んでいる状態になっています。
# このページの連続性が崩れていると論理スキャンフラグメンテーションが発生している状態となります。

データページ関しては、m_prevPage と m_nextPage を使用してページ間のリンクが設定されていることが確認できますね。

 

■Allocation Page のページリンク


それでは、PFS 等の Allocation Page で m_prevPage と m_nextPage の情報を取得して、ページリンクの状態を調べてみたいと思います。

1~30,000 ページの中に PFS ページ (m_type=11) で管理する Allocation Page) がどれぐらい含まれているかを取得してみます。
実行結果がこちら。
image

PFS ですが、8,088 ページごとに存在しているのが上記の結果から確認ができます。

同様に GAM / DCM のページ情報も取得してみたいと思います。
# 2 ページ目の GAM / DCM は8,088 ページより離れた間隔で存在しているのでクエリはちょっと変更しています。
image

image

PFS は 8,088 ページごとに存在していますが、511,000 ページ以上離れた間隔で存在しています。
PFS は [Page Free Space] という名称があらわすようにページ単位で空き領域を管理しています。
GAM / DCM (SGAM / BCM も) はエクステント単位で領域を管理しています。
そのため、ページが存在する間隔も変わってきています。
# PFS は 64MB 分のページを管理、GAM / DCM は 4GB 分のエクステントを管理しています。

Data Page とは異なり、PFS / GAM / DCM では m_prevPage / m_nextPage を使用したページリンクの管理はされていないみたいですね。

IAM に関しては Data Page と同様の管理となっているようです。
image

以前から、PFS 等のページの連続性ってどうなっているのかが気になっていたのですが調べる方法が見えてきてちょっとすっきりしました。

Share

Written by Masayuki.Ozawa

3月 20th, 2011 at 12:45 pm

Posted in SQL Server

Tagged with

One Response to 'PFS / GAM / DCM / は何ページごとに存在する??'

Subscribe to comments with RSS or TrackBack to 'PFS / GAM / DCM / は何ページごとに存在する??'.

  1. […] PFS / GAM / DCM / は何ページごとに存在する?? に続いて疑問に思ったので調べてみましたシリーズです。 […]

    リソースガバナーで制御されているメモリはどの領域?? « SE の雑記

    20 3月 11 at 21:15

Leave a Reply