sql-server - 无法继续执行,因为 session 处于终止状态。在构建聚集索引时

标签 sql-server sql-server-2012

尝试创建聚集索引时出现以下错误

The statement has been terminated.
Msg 596, Level 21, State 1, Line 0
Cannot continue the execution because the session is in the kill state.

Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.



指数是:
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT

BEGIN TRANSACTION
GO

CREATE CLUSTERED INDEX IX_CO_DES_INPUT 
ON dbo.CO_DES_INPUT(DESIGN_ID, PRODUCT_INPUT_NUM, INPUT_NAME)
          WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
               ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

ALTER TABLE dbo.CO_DES_INPUT 
  SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

我在用

Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64)
Standard Edition (64-bit) on Windows NT 6.3 (Build 9600: )



我跑了
DBCC CheckDB ('concept-test') WITH NO_INFOMSGS, ALL_ERRORMSGS  

它没有发现任何问题

我担心我的数据库已损坏,因为我收到此错误。我如何纠正我的问题并将这个索引放在 table 上?

谢谢

最佳答案

状态的常见原因是:

  • 系统无法打开数据或日志文件所在的设备
  • 创建或打开物理设备时未找到指定文件
  • SQL Server 在事务中间崩溃
  • 安装杀毒软件无法上网,无法访问数据或日志文件
  • 数据库服务器被非法关闭
  • 磁盘空间不足无法写入
  • SQL 无法完成回滚或前滚操作
  • 数据库文件被第三方备份软件锁定

  • 怎么解决

    首先找出问题的原因。请返回上一步检查是否是上述原因造成的。例如,没有足够的磁盘空间。

    对于根本原因,我们必须首先解决根本问题,然后修复数据库。

    包括:
  • 检查系统是否更新,是否存在严重的安全隐患,是否存在黑客行为
  • 检查系统电源是否稳定
  • 检查磁盘空间是否足够
  • 检查数据库文件是否对数据库进程具有读写权限
  • 检查是否安装了第三方杀毒软件
  • 检查是否安装了第三方备份软件
  • 尝试将数据库文件挂载到另一台计算机

  • 如果您已经解决了根本问题,则可以按照以下步骤操作。注意,在开始之前,如果数据库是虚拟机,强烈建议创建一个虚拟机快照。

    10步修复法

    1.打开SSMS

    打开 SSMS 并连接到失败的 SQL Server 实例。

    2.准备执行SQL

    找到错误状态的数据库,注意不要扩展它。只需创建一个新查询。

    3.将数据库设置为紧急状态

    执行以下SQL

    EXEC sp_resetstatus database_name;
    ALTER DATABASE database_name SET EMERGENCY
    

    这将数据库设置为紧急状态以允许进一步修复。

    4. 对数据库运行错误扫描

    执行以下SQL

    DBCC CHECKDB (database_name)
    DBCC CHECKCATALOG (database_name)
    

    这将对当前故障数据库运行故障扫描。你可能会看到很多失败。可以依次检查这些错误。请注意,此步骤不会修复任何错误。

    5. 准备修复

    要运行数据库修复脚本,您必须将数据库设置为单个用户。这也可以防止其他可能正在维修的人意外进入。

    同时,我们要回滚最近的事务,因为上一个事务肯定已经失败了,而且很有可能是上一个事务导致了数据库失败。

    ALTER DATABASE database_name SET SINGLE_USER WITH ROLLBACK IMMEDIATE
    

    6. 运行修复

    DBCC CHECKDB (database_name, REPAIR_FAST) -- quick fix
    DBCC CHECKDB (database_name, REPAIR_REBUILD) -- reset index
    DBCC CHECKDB (database_name, REPAIR_ALLOW_DATA_LOSS) -- Allows correction of missing data
    DBCC CHECKALLOC (database_name, REPAIR_REBUILD) -- Fixed allocation problem
    DBCC DBREINDEX (database_name, REPAIR_REBUILD) -- fix index problem
    

    上面的代码将尝试修复数据库错误。如果您在执行过程中遇到障碍,请查看文末高频问题章节。

    注意上面代码中,REPAIR_ALLOW_DATA_LOSS表示允许丢弃数据以修复数据库。第六步可能需要很长时间,一般30GB左右的数据库需要几个小时。需要耐心等待。

    运行上面的 SQL 可能不是完全固定的。您可以使用以下 SQL 多次修复错误。

    DECLARE @Number INT = 1 ;
    While @Number < = 10
    Begin
    PRINT @Number;
    SET @Number = @Number + 1 ;
    DBCC CHECKDB(database_name, REPAIR_ALLOW_DATA_LOSS)
    End
    

    7. 重新允许多用户连接数据库

    至此,数据库已经恢复。我们可以重新允许多个连接到数据库。

    ALTER DATABASE database_name SET MULTI_USER
    

    8. 立即备份

    此时,数据库已达到可用状态。应立即备份数据库以导出可用数据状态的副本。如果数据库是虚拟机,建议在备份的同时进行快照。

    同时建议重启整个数据库服务器,检查重启后数据库是否仍然正常。这是为了避免可能导致重复数据库泄漏的原因。

    9. 检查数据

    可用数据可用后,我们可以检查当前数据库状态是否为较新的状态。

    10.修复其他错误

    在上述过程结束时,虽然大部分数据已经可用,但数据库中仍然存在更多错误。

    您可以使用以下 SQL 查看这些错误:

    DBCC CHECKDB (database_name)
    

    如果要修复这部分错误,可以尝试备份然后恢复备份,可能会解决这部分问题。

    常问问题

    当数据库处于单用户状态时,我们无法离开当前连接。因为一旦我们离开,可能会有其他连接直接被占用。

    在这种情况下,我们必须手动杀死其他冲进来的连接,确保我们是唯一在操作数据库的用户。

    方法如下:

    先执行下面的SQL

    Select d.name, d.dbid, spid, login_time, nt_domain, nt_username, loginame
      From sysprocesses p inner join sysdatabases d on p.dbid = d.dbid
     Where d.name = 'testdb01'
    Go
    

    您将看到输出 session 的列表并找出传入连接的 SPID。例如,SPID 为 51。

    执行以下SQL

    Kill 51
    Go
    

    此时,我们可以继续在这个单用户数据库上执行 SQL。

    关于sql-server - 无法继续执行,因为 session 处于终止状态。在构建聚集索引时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40449982/

    相关文章:

    sql - 查询从年初开始每周的总计

    sql - 在两个月之间选择

    sql-server - 使用 float 还是小数来计算会计应用程序的美元金额?

    sql - 如何将一个表的每条记录中的数据复制到与第一个表相关的另一个表的多个记录中?

    sql - 表的多个别名

    sql-server - ; 之间有什么区别?和 SQL Server 存储过程中的 GO?

    memory - 在 SQL Server 2012 中看到高内存使用率

    azure - SSMS 对象资源管理器上未显示数据库

    c# - Linq to SQL - 从两个表返回记录详细信息

    sql - 在 Case 表达式结果 SQL 中插入换行符