“正在恢复” 的数据库如何处理?

一般来说, 这是因为一个大事务, 让数据库卡着了, 如果数据库重要, 只能让它慢慢还原, 还原的进度可以用

xp_readerrorlog 

存储过程来看。 但是, 如果日志太大, 你又等不了, 那只能删除日志, 让数据库先跑起来了。

下面模拟了这个场景,并作了修复:

本人的另一篇相关文章:点击打开链接

--注意:按序号分开执行
--1. 创建测试库
USE [master]
GO
IF EXISTS(SELECT * FROM sys.databases AS d WHERE d.name='testRestoring')
	DROP DATABASE testRestoring
GO
CREATE DATABASE [testRestoring] ON  PRIMARY 
( NAME = N'testRestoring', FILENAME = N'D:\database\2005\testRestoring.mdf' , SIZE = 3MB , FILEGROWTH = 10MB )
 LOG ON 
( NAME = N'testRestoring_log', FILENAME = N'D:\database\2005\testRestoring_log.ldf' , SIZE = 1MB , FILEGROWTH = 10MB )
GO
ALTER DATABASE [testRestoring] SET RECOVERY SIMPLE WITH NO_WAIT
GO
ALTER DATABASE [testRestoring] SET RECOVERY SIMPLE 
GO
--2. 创建测试表及测试数据
USE testRestoring
GO
IF OBJECT_ID('tmp') IS NOT NULL DROP TABLE tmp
GO
CREATE TABLE tmp(id bigINT NOT NULL PRIMARY KEY)
GO
SET NOCOUNT ON
DECLARE @i INT,@iMax INT
SET @iMax=10000000				-- 1千万条
INSERT INTO tmp (id) VALUES(1)
WHILE 1=1 
BEGIN
    SELECT @i=MAX(id) FROM tmp
    IF @i<=@imax/2
    BEGIN
        INSERT INTO tmp (id)
        SELECT @i+id FROM tmp ORDER BY id
    END
    ELSE
    BEGIN
        INSERT INTO tmp (id)
        SELECT TOP( @iMax-@i ) @i+id FROM tmp ORDER BY id
        BREAK;
    END
END
GO
--3. 删除表中所有数据. 执行下面的 delete 语句后立马重启服务
DELETE FROM tmp
/*
消息 109,级别 20,状态 0,第 0 行
在从服务器接收结果时发生传输级错误。 (provider: 共享内存提供程序, error: 0 - 管道已结束。)
*/

--4. 重启SQL Server 服务, 启动后等待几分钟再执行如下语句。
--   在日志列表的最下面可以看到恢复的进度:
EXEC xp_readerrorlog 
/*
2018-05-14 12:50:29.010	spid26s	Analysis of database 'testRestoring' (18) is 30% complete (approximately 4 seconds remain). This is an informational message only. No user action is required.
2018-05-14 12:50:33.960	spid26s	Analysis of database 'testRestoring' (18) is 100% complete (approximately 0 seconds remain). This is an informational message only. No user action is required.
2018-05-14 12:50:33.970	spid26s	Recovery of database 'testRestoring' (18) is 0% complete (approximately 2819 seconds remain). Phase 2 of 3. This is an informational message only. No user action is required.
*/
--5. 查一下原来的表,还是 1千万,说明事务已回滚
SELECT MAX(id) FROM tmp
/*
10000000
*/

--6. 再执行一次全表删除,并立即停止服务
DELETE FROM tmp
/*
消息 109,级别 20,状态 0,第 0 行
在从服务器接收结果时发生传输级错误。 (provider: 共享内存提供程序, error: 0 - 管道已结束。)
*/

--7. 新建一个文件夹,将
/*
D:\database\2005\testRestoring.mdf
D:\database\2005\testRestoring_log.ldf
两个文件移动过去
*/

--8. 重启服务, 可以看到 testRestoring 还在,但无法访问了, 直接右键删除库
--9. 按原来的库名,创建新库, 注意 mdf, ldf 的名称也要一致
use master
go
CREATE DATABASE [testRestoring] ON  PRIMARY 
( NAME = N'testRestoring', FILENAME = N'D:\database\2005\testRestoring.mdf' , SIZE = 3MB , FILEGROWTH = 10MB )
 LOG ON 
( NAME = N'testRestoring_log', FILENAME = N'D:\database\2005\testRestoring_log.ldf' , SIZE = 1MB , FILEGROWTH = 10MB )
GO
ALTER DATABASE [testRestoring] SET RECOVERY SIMPLE WITH NO_WAIT
GO
ALTER DATABASE [testRestoring] SET RECOVERY SIMPLE 
GO 
--10. 停止服务,将第 7 步新建文件夹中的 testRestoring.mdf 移回 D:\database\2005\. 注:不要移回 ldf 文件
--10. 启动服务
use master
go
alter database testRestoring set emergency
go
--置数据库为单用户模式
alter database testRestoring set single_user with rollback immediate
go
--重建数据库日志文件
alter database testRestoring Rebuild Log on (name=testRestoring_log,filename='D:\database\2005\testRestoring_log3.ldf')
go
--最后设置数据库为多用户模式。
alter database testRestoring set multi_user
go

从预防角度来说,不要一次性删除、更新太多数据, 改成分小批进行, 这才是恰当的。要不卡着了, 就只能等着哭了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值