代码之家  ›  专栏  ›  技术社区  ›  Bittercoder

如何停止Sql Server的用户实例(Sql Express用户实例数据库文件已锁定(即使在停止Sql Express服务之后)

  •  6
  • Bittercoder  · 技术社区  · 16 年前

    <add name="Default" connectionString="Data Source=.\SQLExpress;
      AttachDbFilename=C:\My App\Data\MyApp.mdf;
      Initial Catalog=MyApp;
      User Instance=True;
      MultipleActiveResultSets=true;
      Trusted_Connection=Yes;" />
    

    我们发现,即使在停止SqlExpress服务之后,也无法复制数据库文件MyApp.mdf和MyApp\ u Log.ldf(因为它们被锁定),并且必须先将SqlExpress服务从自动启动模式设置为手动启动模式,然后重新启动计算机,然后才能复制这些文件。


    更新

    sqlserver.exe  PID: 4680  User Name: DefaultAppPool
    sqlserver.exe  PID: 4644  User Name: NETWORK SERVICE
    

    该文件由sqlserver.exe实例打开,PID:4680

    停止“SQLServer(SQLEXPRESS)”服务,终止了PID:4644的进程,但只剩下PID:4680。

    手动清除剩余的sql server进程不会删除数据库文件上的打开文件句柄,从而允许复制/移动这些文件。

    不幸的是,我希望在WiX安装程序的一些安装前/安装后任务中复制/还原这些文件—因此,我希望有一种方法可以通过停止windows服务来实现这一点,而不是必须退出以杀死所有sqlserver.exe实例,因为这会带来一些问题:

    1. 在安装程序中引入额外的复杂性。

    有人对如何关闭与特定用户实例关联的SQLServer实例有进一步的想法吗?

    4 回复  |  直到 16 年前
        1
  •  7
  •   AMissico    16 年前

    SQL Server Express实用工具, SSEUtil是一个可以让您轻松与SQL Server交互的工具, http://www.microsoft.com/downloads/details.aspx?FamilyID=fa87e828-173f-472e-a85c-27ed01cf6b02&DisplayLang=en

    此外,您可能有一个通过visualstudio的服务器资源管理器数据连接打开的连接,因此请确保从那里的任何数据库断开连接。

    H:\Tools\SQL Server Express Utility>sseutil -l
    1. master
    2. tempdb
    3. model
    4. msdb
    5. C:\DEV_\APP\VISUAL STUDIO 2008\PROJECTS\MISSICO.LIBRARY.1\CLIENTS\CORE.DATA.C
    LIENT\BIN\DEBUG\CORE.DATA.CLIENT.MDF
    
    H:\Tools\SQL Server Express Utility>sseutil -d C:\DEV*
    Failed to detach 'C:\DEV_\APP\VISUAL STUDIO 2008\PROJECTS\MISSICO.LIBRARY.1\CLIE
    NTS\CORE.DATA.CLIENT\BIN\DEBUG\CORE.DATA.CLIENT.MDF'
    
    H:\Tools\SQL Server Express Utility>sseutil -l
    1. master
    2. tempdb
    3. model
    4. msdb
    
    H:\Tools\SQL Server Express Utility>
    

    使用.NET Refector,以下命令用于分离数据库。

    string.Format("USE master\nIF EXISTS (SELECT * FROM sysdatabases WHERE name = N'{0}')\nBEGIN\n\tALTER DATABASE [{1}] SET OFFLINE WITH ROLLBACK IMMEDIATE\n\tEXEC sp_detach_db [{1}]\nEND", dbName, str);
    
        2
  •  2
  •   Milan Gardian    16 年前

    我一直在使用下面的helper方法在单元测试中分离附加到sqlserver的MDF文件(这样SQ-Server就可以释放MDF和LDF文件上的锁,并且单元测试可以在它自己之后进行清理)。。。

    private static void DetachDatabase(DbProviderFactory dbProviderFactory, string connectionString)
    {
        using (var connection = dbProviderFactory.CreateConnection())
        {
            if (connection is SqlConnection)
            {
                SqlConnection.ClearAllPools();
    
                // convert the connection string (to connect to 'master' db), extract original database name
                var sb = dbProviderFactory.CreateConnectionStringBuilder();
                sb.ConnectionString = connectionString;
                sb.Remove("AttachDBFilename");
                var databaseName = sb["database"].ToString();
                sb["database"] = "master";
                connectionString = sb.ToString();
    
                // detach the original database now
                connection.ConnectionString = connectionString;
                connection.Open();
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "sp_detach_db";
                    cmd.CommandType = CommandType.StoredProcedure;
    
                    var p = cmd.CreateParameter();
                    p.ParameterName = "@dbname";
                    p.DbType = DbType.String;
                    p.Value = databaseName;
                    cmd.Parameters.Add(p);
    
                    p = cmd.CreateParameter();
                    p.ParameterName = "@skipchecks";
                    p.DbType = DbType.String;
                    p.Value = "true";
                    cmd.Parameters.Add(p);
    
                    p = cmd.CreateParameter();
                    p.ParameterName = "@keepfulltextindexfile";
                    p.DbType = DbType.String;
                    p.Value = "false";
                    cmd.Parameters.Add(p);
    
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
    

    笔记:

    • 在消除“隐形”连接方面非常有帮助(当一个连接被汇集在一起时,即使你“Close()”它也会保持活动状态;通过明确清除池连接,您不必担心在所有连接字符串中将池标志设置为false)。
    • 这个 是对系统存储过程的调用 sp_detach_db (Transact-SQL) .
        3
  •  1
  •   KnightsArmy    16 年前

    我还不能评论,因为我还没有足够高的代表。有人能把这个信息移到另一个答案,这样我们就不会被骗了吗?

    我只是用这个帖子来解决我的WIX卸载问题。我用了阿米西科回答的这句话。

    string.Format("USE master\nIF EXISTS (SELECT * FROM sysdatabases WHERE name = N'{0}')\nBEGIN\n\tALTER DATABASE [{1}] SET OFFLINE WITH ROLLBACK IMMEDIATE\n\tEXEC sp_detach_db [{1}]\nEND", dbName, str);
    

    在使用WIX的时候效果很好,只是我需要添加一个东西来让它适合我。

    我取出了sp\u\u db,然后将db重新联机。如果不这样做,WIX将在卸载后保留mdf文件。一旦我把数据库恢复在线WIX会正确删除mdf文件。

    string.Format( "USE master\nIF EXISTS (SELECT * FROM sysdatabases WHERE name = N'{0}')\nBEGIN\n\tALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE\n\tALTER DATABASE [{0}] SET ONLINE\nEND", dbName );
    
        4
  •  -3
  •   Vaccano    16 年前

    这可能不是你想要的,但是免费工具Unlocker有一个可以从WIX运行的命令行界面(我使用unlocker有一段时间了,发现它很稳定,而且非常擅长于它最擅长的功能,解锁文件。)

    Unlocker可以解锁和移动/删除大多数文件。

    这样做的缺点是,需要锁定文件的应用程序将不再拥有该文件(但有时仍然可以很好地工作。)请注意,这并不会杀死拥有锁的进程。它只是解除了它的锁(可能重新启动您正在停止的sql服务就足以使其重新锁定和/或正常工作。)

    您可以从这里获得解锁器: http://www.emptyloop.com/unlocker/

    查看命令行选项的运行 unlocker -H

    Unlocker 1.8.8
    
    Command line usage:
       Unlocker.exe Object [Option]
    Object:
       Complete path including drive to a file or folder
    Options:
       /H or -H or /? or -?: Display command line usage 
       /S or -S: Unlock object without showing the GUI 
       /L or -L: Object is a text file containing the list of files to unlock 
       /LU or -LU: Similar to /L with a unicode list of files to unlock 
       /O or -O: Outputs Unlocker-Log.txt log file in Unlocker directory 
       /D or -D: Delete file 
       /R Object2 or -R Object2: Rename file, if /L or /LU is set object2 points to a text file containing the new name of files 
       /M Object2 or -M Object2: Move file, if /L or /LU is set object2 points a text file containing the new location of files 

    假设您的目标是用安装程序中的一个文件替换C:\My App\Data\MyApp.mdf,那么您需要 unlocker C:\My App\Data\MyApp.mdf -S -D . 这将删除该文件,以便您可以复制到新文件中。