質問者
SQL Server 2008のFileStream機能で4GB超のファイルを登録すると4GB分足りなくなる

質問
-
Visual Studio 2008 C#で、SQL Serverに接続するアプリケーションを作っています。
4GBを超えるバイナリファイルをSQL Serverに登録するにあたって、SQL Server 2008/2012ではFileStreamデータ型を使い登録しています。
SQL Server側にある「C:\data\4GB.dat」を作業用のデータベース「TempDatabase」に格納します。
//作業用データベースの作成
_sql = string.Format("CREATE DATABASE {1}"
+ " ON PRIMARY (NAME = mdf,"
+ " FILENAME = '{0}{1}.mdf',"
+ "SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%),"
+ " FILEGROUP data CONTAINS FILESTREAM (NAME = data,"
+ "FILENAME = '{0}{1}')"
+ " LOG ON (NAME = ldf,"
+ "FILENAME = '{0}{1}.ldf',"
+ "SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)", "C:\\data\\", "TempDatabase");_command.CommandText = _sql;
_command.ExecuteNonQuery();//作業用テーブルの作成
_sql = "CREATE TABLE TempDatabase.dbo.Records"
+ " ([ID] UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,"
+ "[bck] VARBINARY(MAX) FILESTREAM NULL)";_command.CommandText = _sql;
_command.ExecuteNonQuery();_sql = string.Format("INSERT INTO {0}(ID,bck) SELECT NEWID() AS [ID], CAST(BulkColumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK N'{1}',SINGLE_BLOB) AS [bck]", "TempDatabase.dbo.Records", "C:\\data\\4GB.dat");
_command.CommandText = _sql;
_command.ExecuteNonQuery();おおよそ以上のような手順にしています。その結果、SQL Server 2012では正常に登録され、「C:\data\TempDatbase」フォルダに「0881a803-5c5b-493b-9db3-xxxxxx」というような名前のフォルダが作られ、その中に「dbe1ffcf-b617-455b-a3d9-xxxxxx」というような名前のフォルダがあって、「00000014-00000067-xxxx」というような名前のファイルが作られます。そのファイルサイズは「c:\data\4GB.dat」と同じで、ファイルを比較してもまったく同じです。
ところが、SQL Server 2008を対象に実行すると、エラーも発生せず終了するのですが、できあがったファイルは、ファイルサイズがちょうど4GB分(2^32=4294967296バイト分)不足した状態になっています。
INSERT INTO文をあれこれ修正して実行してみましたが、変化はありませんでした。当初はSQL Server 2008のバグかと思い、ServicePack1をあててみたり、SQL Server 2008 R2で実行してみましたが、変化はありませんでした。
(サーバOSはいずれもWindows Server 2008 Standard)どなたかこの現象についてなにかご存じのことがありましたら、お教えください。
すべての返信
-
情報を追加します。
SQL Server 2008(Standard)にService Pack2やService Pack3をあて、最新の状態にしてみましたが、変化はありませんでした。
(Windows Serverとも)作成中のアプリケーションとの切り分けを行なうため、C:\backupフォルダを作成し4GB.bakファイルを配置してから、Transact-SQLで
■データベースを作成する
CREATE DATABASE TempDataBase ON PRIMARY (NAME = mdf, FILENAME = 'C:\backup\TemDataBase.mdf', SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%), FILEGROUP data CONTAINS FILESTREAM (NAME = data, FILENAME = 'C:\backup\TemDataBase') LOG ON (NAME = ldf, FILENAME = 'C:\backup\TemDataBase.ldf', SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%);■テーブルを作成する
CREATE TABLE TempDataBase.dbo.Records ([ID] UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,[bck] VARBINARY(MAX) FILESTREAM NULL);■データを登録する
INSERT INTO TempDataBase.dbo.Records([ID],[bck]) SELECT NEWID() AS [ID], CAST(BulkColumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK N'C:\backup\4GB.bak',SINGLE_BLOB) AS [bck];としても同じ症状です。
ファイルサイズが2.7GBの場合には問題なく登録できています。しかし、4GBを超えた、たとえば4.55GB(4,889,013,760バイト)のファイルを対象にすると、566MB(594,046,464バイト)のファイルができあがります。その差が4,294,967,296バイトで、ちょうど4GBです。ちょうど4GB分切れてしまうことから、SQL Server 2008のバグではないかとも思いましたが、あまりにイージー(それでいて致命的)なバグがこれまで見過ごされてきたとは思えません。
引き続き情報を求めたいと思います。
どなたかお助けを....
-
気になって調べてみたところ、仕様みたいですね。
http://msdn.microsoft.com/en-us/library/bb895334(v=sql.105).aspx
にコメントとして以下のように書かれています。> The maximum database size for Denali is also incorrect
> It's unlikely that Microsoft would decrease the maximum database size limit in Denali back down to 4GB however I've been unable to find the Denali limit anywhere.