How to Tell If You Are Out of Room – SQL Azure Team Blog – Site Home – MSDN Blogsを簡単に翻訳したエントリーです。
SQL Azureデータベースはサイズ上限があります。サイズ上限がある理由の一つは、予想を超えてデータ量が拡大し、驚くべき使用料を請求するような事態を望んでいないからです。50GBを上限に、いつでもデータベースの上限を増やしたり減らしたりすることができます。しかし、これは自動ではありません。このエントリーでは、SQL Azureデータベースのサイズをハンドリングし、拡大したり、現在の上限を取得したり、現在の容量を取得したり、サイズエラーを検知したりするTipsを紹介します。
話を始める前に一つ注意しないといけないのは、データベース上限を基に課金されるのでは無く、実際に使用しているデータ量が属する、データベースのエディションの範囲に応じて課金されます。Webエディションでは、0~1GBと1~5GBの範囲でそれぞれ課金されます。ビジネスエディションでは、0~10GB、10~20GB、20~30GB、30~40GB、40~50GBの範囲でそれぞれ課金されます。
現在の上限
次のクエリを使用することで、SQL Azureデータベースの現在の上限を取得することができます。
SELECT DATABASEPROPERTYEX ('AdventureWorksLTAZ2008R2' , 'MaxSizeInBytes' )
MaxSizuInBytesプロパティの結果は、バイト数です。1GBは、1,000,000,000バイトでは無く、1,073,741,824バイトです。
現在のサイズ
次のクエリを使用することで、データベースの現在のサイズを取得することができます。
SELECT SUM(reserved_page_count) * 8192 FROM sys.dm_db_partition_stats
このクエリの結果も、バイト数で返します。上限のサイズを取得するクエリの結果とそのまま比較することができます。
ここで簡単なクイズ。
現在のサイズが上限サイズよりも大きくなるのはいつでしょうか?
答えは、あり得ないです。もし、上限を超えるデータを追加したり更新使用とすると、SQLがエラーを返します。
エラーを検知する
SQL Azureで40544エラーを取得したら、エラーメッセージは「The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions.」となります。
SQL Managementでは次のように表示されます。
Msg 40544, Level 20, State 5, Line 1
The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions. Code: 524289
もしC#で、このエラーをハンドリングしたい場合は、次のようなコードになります。
try { // ... } catch (SqlException sqlException) { switch (sqlException.Number) { // The database has reached its size quota. Partition or delete data, // drop indexes, or consult the documentation for possible resolutions. case 40544: break; } }
自動的にデータベース上限を増やす
データベース量が増え、現在の上限を超えたとき、上限が増えたらすばらしいと思いませんか?SQL Azureは、上限ではなく使用量に応じて課金されます。例えば、0.8GBのデータ量を使用していたら、5GB上限の内、0~1GBの範囲の課金が行われます。データベースが1GBより大きくなった時、エラーは発生せず、1~5GBの範囲の課金が行われます。上限サイズの自動拡張を許可しても、課金は使用している量に応じて課金されます。もし、現在の範囲を超えても、エラー無く自動的に次の範囲の課金が行われます。
データ上限のの自動拡張は、今のところWEBエディションとビジネスエディソンの間は超えません。データベースの上限は、1、5、10、20、30、40、50GBがあります。Webエディションを使用していて、5GBに到達し、データベース上限を拡大させたいときは、ビジネスエディソンに変更する必要があります。こえは、データベースを自動拡張させていくにはエディションを変更するTransact-SQLを使用する必要があると言うことです。
エディションを変更するコード
SQL Serverエラーコード40544をキャッチしたら、エディションを変更したり、上限を自動的に増やすC#コードを書くつもりでした。Windows Azure webロールにコードを追加し、データベースサイズが自動的に増やせるようにします。
しかし、このコンセプトには問題があります。webサイトに1秒間に1000回の接続があり、ちょうどデータベースがいっぱいになり、3、4スレッドスレッドがWindows Azureサーバで40544エラーを受け取るかもしません。それらのスレッドは、データベースサイズを自動拡張させようとしますが、3回も4回も拡張が行われ必要なサイズよりもデータベースサイズが大きくなる可能性があります。解決策は、トランザクション管理をし、データベースの拡大は同時に1つしか実行できないようにすることです。しかし、SQL azure上のALTER DATABASE文は、トランザクション制御されません。
40544エラーをハンドリングし、自動的にデータベースサイズ、エディションを変更させsるソリューションの実現方法を考え続けます。これについて、何か良いアイディアをお持ちでしたら、コメントでアドバイスをください。
データベースサイズの変更
自動的にデータベースサイズを変更できない間、自分で上限を変更するTransact-SQLを流すことになります。エディションを変更する場合は、次のようなALTER DATABASE句を使用できます。
ALTER DATABASE AdventureWorksLTAZ2008R2 MODIFY (EDITION='BUSINESS', MAXSIZE=10GB)
データベースの上限はサイズを大きくしたり、減らしたりできます。もしサイズを減らそうとした時に、減らそうとしているサイズよりも現在のサイズのほうが大きい場合、次のようなエラーが出ます。
Msg 60003, Level 16, State 1, Line 1
Operation failed because the resulting cumulative database size would exceed your database sku limit