简体   繁体   English

如何分离NCrunch节点服务使用的所有LocalDb数据库

[英]How to detach all LocalDb databases used by NCrunch Node service

Occasionally, the clean-up code for the tests that use LocalDB is not run (perhaps when tests are being cancelled). 有时,使用LocalDB的测试的清理代码不会运行(也许在取消测试时)。 The result is a lot of garbage local db databases. 结果是大量的垃圾本地数据库数据库。

I get an error like this when running tests that attempt to create another localDB 当运行尝试创建另一个localDB的测试时,出现类似错误

System.Data.SqlClient.SqlException: Unable to create/attach any new database because the number of existing databases has reached the maximum number allowed: 32765. ved System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) ved System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) ved System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) ved System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) ved System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) ved System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) ved System.Data.SqlClient.SqlCommand.ExecuteNonQuery() ved Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action`2 paramReader) ved Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) ved Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType)

The test-clean-up is something like this in each test class (using xunit) 每个测试类中的测试清理工作都是这样(使用xunit)

public override void Dispose()
{
    base.Dispose();
    FreeDb();
    GC.SuppressFinalize(this);
}

private void FreeDb()
{
    Task.Factory.StartNew(() =>
    {
        var masterConnectionString =
            @"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True; Initial Catalog=master";
        using (var dbConnection = new SqlConnection(masterConnectionString))
        {
            dbConnection.Execute($"ALTER DATABASE [{_databaseName}] SET OFFLINE WITH ROLLBACK IMMEDIATE");
            dbConnection.Execute($"exec sp_detach_db '{_databaseName}'");
        }
    });
}

Using Sql server Management Studio connect to the following server (LocalDb)\\MSSQLLocalDB 使用Sql Server Management Studio连接到以下服务器(LocalDb)\\ MSSQLLocalDB

Afterwards determine which databases are localDb using the following statement: 然后使用以下语句确定哪些数据库是localDb:

SELECT * FROM sys.databases

After this correct the following detach localdb statement to only detach localdbs: 在此之后,请更正以下detach localdb语句以仅分离localdbs:

DECLARE @rowCount INT = 1
DECLARE @databaseName NVARCHAR(MAX)

WHILE @rowCount = 1
BEGIN
    SET @databaseName = null

    SELECT TOP(1)
    @databaseName = name
    FROM sys.databases
    WHERE database_id >= 5
    SET @rowCount = @@ROWCOUNT

    IF @rowCount = 1
    BEGIN
        exec sp_detach_db @databaseName
    END
END

In my case it appears that everything above database_id 4 are localdbs, but this might be different for you. 以我为例,似乎database_id 4之上的所有内容都是localdbs,但这可能与您有所不同。

It appears to be worse. 情况似乎更糟。

The localdb instances being used up are from my NCrunch node. 用完的localdb实例来自我的NCrunch节点。 Which runs as the SYSTEM user. 以SYSTEM用户身份运行。

So from a PowerShell prompt with admin rights I ran 因此,从具有管理员权限的PowerShell提示符运行

choco install pstools

and then 接着

psexec -i -s CMD

to get a command prompt running as SYSTEM 获取以系统身份运行的命令提示符

Not much luck with sqllocaldb.exe there either, but pasting the full path for SQL Management Studio did: 那里的sqllocaldb.exe也不太幸运,但是粘贴SQL Management Studio的完整路径确实可以:

"C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Ssms.exe"

Connect to the server (LocalDb)\\MSSQLLocalDB 连接到服务器(LocalDb)\\MSSQLLocalDB

Then I followed Anders' approach and connected to (LocalDb)\\MSSQLLocalDB and then I did 然后我遵循安德斯的方法,并连接到(LocalDb)\\MSSQLLocalDB ,然后我做了

DECLARE @rowCount INT = 1
DECLARE @databaseName NVARCHAR(MAX)

WHILE @rowCount = 1
BEGIN
    SET @databaseName = null

    SELECT TOP(1)
    @databaseName = name
    FROM sys.databases
    WHERE database_id >= 7
    SET @rowCount = @@ROWCOUNT

    IF @rowCount = 1
    BEGIN
        exec sp_detach_db @databaseName
        exec sp_dbremove @databaseName
    END
END

The sp_dbremove is deprecated but gets the job done here. sp_dbremove已过时,但可以在此处完成工作。 The .mdf and _log.ldf files are even removed now. .mdf和_log.ldf文件现在甚至已删除。

Afterwards the number of dbs went from 32765 down to 6, when counted like so: 之后,dbs的数量从32765减少到6,如下所示:

SELECT COUNT(1) FROM sys.databases

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM