今回は [デタッチ / アタッチを使用したデータベースの移動] について振り返っていきたいと思います。
SQL Server にはデータベースを デタッチ (サーバーからデータベースのエントリを外す) / アタッチ (サーバーにデータベースのエントリを追加) することで、データベースを移動 (別サーバー / 同一サーバーの別ディレクトリ) することができます。
セミナーの中では、上位バージョンへのアタッチ / アタッチ後の統計情報についてのお話がありましたので、今回はその点をまとめてみたいと思います。
■上位バージョンへのアタッチ
SQL Server ではデータベースをデタッチ / アタッチすることでデータベースを移動することができます。
アタッチはバージョンが上位のデータベースに対しても実行することが可能です。
SQL Server 2000 では [pubs] というデータベースがありました。
このデータベースをデタッチして SQL Server 2008 R2 にアタッチしてみたいと思います。
まずは、SQL Server 2000 で [pubs] データベースを [デタッチ] します。
デタッチをすることで、SQL Server からデータベースのエントリが外れます。
この状態になると SQL Server のサービスを起動していた状態でデータベースのファイル (mdf / ldf) をコピーすることが可能となります。
ファイルをコピーして SQL Server 2008 R2 に [アタッチ] をします。
このような操作をすることでデータベースを移動することができます。
アタッチした直後はデータベースの [互換性レベル] はアタッチ元のバージョンの状態となっています。
今回は SQL Server 2000 のデータベースをアタッチしていますので、互換性レベルも [SQL Server 2000] となっています。
互換性レベルが低い状態では、SQL Server のすべての機能が使用できないのでアタッチで移動した場合は互換性レベルを変更することも検討したほうが良いかと思います。
互換性レベルを低くした場合、以前のバージョンの構文解析が使える可能性がありますが、なくなった機能が保障されるわけではないですので。
■アタッチ後の統計情報の更新状況について
データベースのアタッチ後の、データベースの断片化や統計情報ですがアタッチ後も以前の状態を引き継いでいる (アタッチ前のバージョンの状態) という話がセミナー内でありました。
この動作を実際に確認してみたいとおもいます。
今回は [pubs] データベースの [UPKCL_auidind] のインデックスの統計情報について確認してみたいと思います。
統計情報の確認ですが、以下のクエリを使用しました。
DBCC SHOW_STATISTICS(‘dbo.authors’, ‘UPKCL_auidind’) WITH STAT_HEADER |
SQL Server 2000 で実行した結果が以下になります。
それでは、SQL Server 2008 R2 でも確認をしてみたいと思います。
[Updated] を比較すると、同一の日付になっていることが確認できます。
互換性レベルを変更して、統計情報の更新状況を確認してみます。
互換性レベルを [SQL Server 2000] → [SQL Server 2008] に変更して、
統計情報を確認してみます。
互換性レベルを変更しても、統計情報は変わっていないですね。
異なるバージョンにアタッチをした場合、統計情報は以前の情報がそのまま引き継がれます。
そのため、手動で統計情報を更新することで最新のバージョンの統計情報に明示的に更新することがセミナーで話にありました。
[sp_updatestats] を実行することで全オブジェクトを対象として統計情報を更新することができます。
sp_updatestats を実行した後は、統計情報が更新されていることが確認できます。
実行前後を比較すると統計情報の内容が変わっていることが確認できます。
インデックスの断片化の状態も変わらないのでデータベースの断片化解消と統計情報の更新はアタッチ後に実施したほうが良さそうですね。
# インデックスの再構築をした場合は統計情報も更新されたはずですが。
■アタッチ後のデータベースの互換性について
データベースは下位互換があるため、新しいバージョンの SQL Server では下位バージョンの SQL Server のデータベースをアタッチすることが可能です。
セミナーを受けていて、一度上位のバージョンでアタッチしたデータベースを下位のバージョンで再度アタッチすることができるかという疑問がわきましたのでこの点について少し確認をしてみたいと思います。
まずは SQL Server 2000 でデタッチしたデータベースを SQL Server 2008 R2 でアタッチします。
その後、何も操作をしないで SQL Server 2000 にデータベースをアタッチしてみます。
そうすると以下のエラーが発生します。
一度、上位のバージョンでアタッチしたデータベースは下位のバージョンではアタッチできないようです。
SQL Server 2000 だとメッセージが分かりにくいので、SQL Server 2005 でアタッチをしてみたいと思います。
こちらのエラーメッセージだとわかり易いですね。
SQL Server のデータベースはダウングレード パスがサポートされていないと表示されています。
SQL Server のデータベースですが内部でデータベースのバージョンを保持しています。
# ここでいうバージョンは互換性レベルとは異なります。
データベースのバージョンですが、[DBCC DBINFO] を使用することで確認ができます。
DBCC DBINFO を実行するためにはトレースフラグ [3604] を有効にする必要があります。
以下のクエリを実行すると DBCC DBINFO による情報の取得ができます。
DBCC TRACEON(3604) DBCC DBINFO DBCC TRACEOFF(3604) |
SQL Server 2000 で実行した結果が以下になります。
DBINFO STRUCTURE: DBINFO @0x05D2F170 dbi_checkptLSN dbi_dbbackupLSN dbi_differentialBaseLSN dbi_createIndexLSN dbi_oldestBackupXactLSN dbi_versionChangeLSN dbi_recoveryForkNameStack entry 0 entry 1 |
SQL Server 2000 では、バージョンは [539] となります。
SQL Server 2008 R2 で実行した結果が以下になります。
DBINFO STRUCTURE: DBINFO @0x000000000E83DBE0 dbi_dbid = 1 dbi_status = 65544 dbi_nextid = 1739153241 m_fSeqNo = 217 m_blockOffset = 496 m_slotId = 1 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 dbi_oldestBackupXactLSN m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 m_fSeqNo = 204 m_blockOffset = 328 m_slotId = 150 dbi_createIndexLSN m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 dbi_versionChangeLSN m_fSeqNo = 141 m_blockOffset = 232 m_slotId = 1 dbi_MinSkipLSN m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 entry 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 entry 1 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 dbi_dbmRedoLsn m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 dbi_dbmOldestXactLsn m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 dbi_EncryptionHistory Scan 0 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 Scan 1 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 Scan 2 m_fSeqNo = 0 m_blockOffset = 0 m_slotId = 0 |
SQL Server 2008 R2 では [661] となります。
アタッチを GUI で実行した場合にはわからないのですが、クエリでアタッチをすると以下のメッセージが表示されていることが確認できます。
USE [master] |
データベース ‘pubs’ をバージョン 539 から現在のバージョン 661 に変換しています。 |
アタッチしたタイミングでデータベースのアップグレードが実行されます。
そのため、特に操作をしなくてもデータベースをアタッチしただけで内部のバージョン情報が変わり、下位の SQL Server ではアタッチできなくなります。
軽く調べたところ、SQL Server のバージョン別のデータベースの内部バージョン情報は以下のようになるようです。
SQL Server 2000 | 539 |
SQL Server 2005 | 611 |
SQL Server 2008 | 655 |
SQL Server 2008 R2 | 661 |
SQL Server Denali CTP1 | 684 |
デタッチ / アタッチによるデータベースの移動は内部バージョンと統計情報の更新に気を付ける必要がありそうですね。
振り返りの最後にパフォーマンスデータコレクションについてのお話がありました。
今回の振り返りの最後としてパフォーマンスデータコレクションについてまとめていきたいと思います。