web-dev-qa-db-ja.com

SSDTでメモリ最適化ファイルグループの作成中にエラーが発生しました

SSDTのSQLサーバーデータベースプロジェクトにメモリ最適化ファイルグループを追加しようとしています。これは、Visual Studio 2017を使用するSQL Server 2017用です。

ただし、プロジェクトをコンパイル(F5キーを押してビルド)すると、エラーが発生します。このエラーは、(Deployを介して)デプロイするときには発生しません。

ファイルグループは通常どおり作成されます(SSDTによってスクリプト化されたSQLCMD変数を使用)。

ALTER DATABASE [$(DatabaseName)]
ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA

ただし、これによりエラーが発生します。

操作 'AUTO_CLOSE'は、MEMORY_OPTIMIZED_DATAファイルグループを持つデータベースではサポートされていません。

ただし、データベース設定では、自動クローズが実際に無効になっていることが示されています。

Auto Close

SSDTによって何らかの理由で生成された展開スクリプトは、データベースを作成し、ファイルグループを作成し、その後、AUTO_CLOSEをオフに設定するだけです。これがエラーの原因である可能性があります:

CREATE DATABASE [$(DatabaseName)]
ON 
PRIMARY(NAME = [$(DatabaseName)], FILENAME = N'$(DefaultDataPath)$(DefaultFilePrefix)_Primary.mdf')
LOG ON (NAME = [$(DatabaseName)_log], FILENAME = N'$(DefaultLogPath)$(DefaultFilePrefix)_Primary.ldf') COLLATE SQL_Latin1_General_CP1_CI_AS
GO
PRINT N'Creating [MemoryOptimizedFilegroup]...';

GO
ALTER DATABASE [$(DatabaseName)]
    ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;

GO
ALTER DATABASE [$(DatabaseName)]
    ADD FILE (NAME = [MemoryOptimizedFilegroup_69323650], FILENAME = N'$(DefaultDataPath)$(DefaultFilePrefix)_MemoryOptimizedFilegroup_69323650.mdf') TO FILEGROUP [MemoryOptimizedFilegroup];

GO
USE [$(DatabaseName)];

GO
IF EXISTS (SELECT 1
    FROM   [master].[dbo].[sysdatabases]
    WHERE  [name] = N'$(DatabaseName)')
BEGIN
    ALTER DATABASE [$(DatabaseName)]
        SET ANSI_NULLS ON,
            ANSI_PADDING ON,
            ANSI_WARNINGS ON,
            ARITHABORT ON,
            CONCAT_NULL_YIELDS_NULL ON,
            NUMERIC_ROUNDABORT OFF,
            QUOTED_IDENTIFIER ON,
            ANSI_NULL_DEFAULT ON,
            CURSOR_DEFAULT LOCAL,
            CURSOR_CLOSE_ON_COMMIT OFF,
            AUTO_CREATE_STATISTICS ON,
            AUTO_SHRINK OFF,
            AUTO_UPDATE_STATISTICS ON,
            RECURSIVE_TRIGGERS OFF 
        WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE [$(DatabaseName)]
        SET AUTO_CLOSE OFF 
        WITH ROLLBACK IMMEDIATE;
END

CREATE DATABASEの後、デフォルトでAUTO_CLOSEが有効になっているか無効になっているかはわかりません。デフォルトでオンの場合、SSDTが誤った順序で展開スクリプトを生成しているようです。デフォルトでオフの場合、エラーが存在する理由がわかりません。

SSDTプロジェクトでメモリ最適化ファイルグループの作成に成功した人はいますか?

2
Definite

CREATE DATABASEの後、デフォルトでAUTO_CLOSEが有効になっているか無効になっているかはわかりません。デフォルトでオンの場合、SSDTが誤った順序で展開スクリプトを生成しているようです。デフォルトでOFFの場合、エラーが存在する理由がわかりません。

LocalDBはモデルを無視してAUTO_CLOSEをハードコードしているようです

LocalDB/SQLEXPRESS

True、localdbに接続して標準のデータベース作成コマンドを実行する場合

enter image description here

CREATE DATABASE TEST

GO

SELECT name,database_id
FROM sys.databases 
WHERE is_auto_close_on = 1;

name    database_id
TEST    5

modelでauto_closeが無効になっている場合でも、is_auto_close_onが1に設定されているようです。

通常、デフォルト設定はmodelシステムデータベースに基づいています。


理論的にこの問題を解決する

新しく作成されたデータベースの自動クローズを自動的に0に変更するトリガーを作成できます。これは少しハックなアプローチですが、機能します。

自分の責任で試してください/実装してください。

CREATE TRIGGER Change_Auto_Close 
ON ALL SERVER 
FOR CREATE_DATABASE 
AS 
    DECLARE 
        @DatabaseName NVARCHAR(128)
        ,@SQL NVARCHAR(4000);
    SELECT 
        @DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(128)')

    SET @SQL = 'USE [master] ALTER DATABASE ['+@DatabaseName+'] SET AUTO_CLOSE OFF WITH NO_WAIT;';

    IF @@TRANCOUNT = 1
    COMMIT TRAN; -- commit previous tran, otherwise we cannot alter the database
    -- PRINT @SQL;
    EXEC (@SQL);
    BEGIN TRAN; --begin new tran as not get error that the transaction ended in the trigger

GO

here および here のアイデア


その他のエディション

データベースはmodelのコピーとして作成されるため、modelデータベースにis_auto_close_on = 1がある可能性があります。以下は、modelデータベースでauto_closeを有効および無効にしたいくつかのテストです。


modelの自動クローズをオンに設定

USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE ON WITH NO_WAIT;
GO

デフォルトのデータベースを作成する

CREATE DATABASE AutoClosedDB;

新しく作成されたデータベースの自動クローズ状態を検証します

SELECT name, is_auto_close_on 
FROM sys.databases 
WHERE name = 'AutoClosedDB';

結果

name            is_auto_close_on
AutoClosedDB    1

modelの自動クローズをオフに設定

USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE OFF WITH NO_WAIT;
GO

デフォルト設定でデータベースを作成する

CREATE DATABASE NoAutoClosedDB;

新しく作成されたデータベースの自動クローズ状態を検証します

SELECT name, is_auto_close_on 
FROM sys.databases 
WHERE name = 'NoAutoClosedDB';

結果

name            is_auto_close_on
NoAutoClosedDB  0

両方のデータベースでメモリ最適化ファイルグループを作成してみてください

ALTER DATABASE NoAutoClosedDB
    ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;

成功する

ALTER DATABASE AutoClosedDB
    ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;

エラーメッセージで失敗する:

メッセージ10794、レベル16、状態125、行33操作 'AUTO_CLOSE'は、MEMORY_OPTIMIZED_DATAファイルグループを持つデータベースではサポートされていません。


modelデータベースの自動クローズ状態を検証するには、以下のスクリプトを実行します

SELECT name, is_auto_close_on 
FROM sys.databases 
WHERE name = 'model';

自動クローズを無効にする

USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE OFF WITH NO_WAIT;
GO
2
Randi Vertongen

上記のRandi Vertongenによる回答に加えて、SQL Serverインスタンスをインストールし、LocalDBではなくそれに接続するようにデバッグ設定でSSDTプロジェクトを編集する方法もあります。

たとえば、SQLTの名前付きインスタンスをSSDTビルド(デバッグビルドテストでF5キーを押した場合)にのみインストールし、実際の展開に使用した既定のインスタンス(発行を使用した場合)をインストールしました。

これにより、デフォルトのAUTO_CLOSEが1つだけであるLocalDBの制限が克服されます。

2
Definite