前言
最近因为线上alwayson环境的一个数据库上使用内存表。经过大概一个星期监控程序发现了一个非常严重问题这个数据库的日志文件不会截断,已用空间一直在增加(存在定时的每个小时的日志备份),同时内存表数据库文件也无法删除,下面就介绍一下后面我的处理过程,话不多说了,来一起看看详细的介绍吧。
数据库:SQL Server2014 Enterprise Edition (64-bit)
删除文件
使用一个单独非alwayson环境的数据库测试。
一、创建内存表
---创建内存表文件组
ALTER DATABASE [test] ADD FILEGROUP [test_ag] CONTAINS MEMORY_OPTIMIZED_DATA
GO
----创建内存表数据库文件
ALTER DATABASE [test]
ADD FILE
(
NAME = 'test_memory',
FILENAME ='D:\database\memory'
)
TO FILEGROUP [test_ag];
GO
二、删除内存表数据库文件
USE [test]
GO
ALTER DATABASE [test] REMOVE FILE [test_memory]
GO

备注:此时还未创建表,创建完后数据库文件执行删除就无法删除,接下来试试在线文档的删除方法方法
三、官方相关的删除方法
即使已使用“DBCC SHRINKFILE”操作清空 FILESTREAM 容器,但出于各种系统维护原因,数据库可能仍然需要保留对已删除文件的引用。 sp_filestream_force_garbage_collection (TRANSACT-SQL)将运行 FILESTREAM 垃圾回收器删除这些文件时,则可以安全进行这些操作。 除非 FILESTREAM 垃圾回收器已从 FILESTREAM 容器中删除所有文件,否则 ALTER DATABASEREMOVE FILE 操作将无法删除 FILESTREAM 容器并返回错误。 建议使用以下过程删除 FILESTREAM 容器。
1.运行DBCC SHRINKFILE (TRANSACT-SQL)带有 EMPTYFILE 选项以将此容器的活动内容移动到其他容器
USE test;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE test
ADD FILE (
NAME = Test1data,
FILENAME = 'D:\database\t1data.ndf',
SIZE = 5MB
);
GO
-- Empty the data file.
DBCC SHRINKFILE (test_memory, EMPTYFILE);
GO

2.确保已在 FULL 或 BULK_LOGGED 恢复模型中执行日志备份。
3.确保复制日志读取器作业已运行(如果相关)。

通过log_reuse_wait_desc的状态可以看到当前数据库已经无需日志备份,当然我已经执行过日志备份。
4.运行sp_filestream_force_garbage_collection (TRANSACT-SQL)强制垃圾回收器删除不再需要此容器中的任何文件
USE [test]
GO
EXEC sp_filestream_force_garbage_collection @dbname = N'test' @filename = N' test_memory ';
5.执行带有 REMOVE FILE 选项的 ALTER DATABASE,以删除此容器。
USE [test]
GO
ALTER DATABASE [test] REMOVE FILE [test_memory]
GO

还是无法删除!!!
四、问题分析
一开始是在alwayson的环境中删除,提示由于副本的原因无法删除。后面单独在一个非alwayson的环境下的数据库测试同样是无法删除,起初以为是创建了内存表的原因后面测试仅仅创建文件组和文件然后来删除文件同样是无法删除,个人猜测有可能是buffer的缘故;在buffer中一直存在内存表相关的文件存在,通过执行DBCC DROPCLEANBUFFERS命令也无法清空buffer中的内存表对象。使尽浑身解数还是无法将它删除掉,最后只能投降了!!!线上环境等不下去;只能使用最不愿使用的生成表结构导出数据的办法来重建新的数据库。
生成脚本重建数据库
创建一个新的数据库同时保证当前数据库可用(重命名当前的数据库,新创建的数据库使用之前的名称这样可以保证应用程序那边不需要改变),这样如果出现什么问题也可以及时的切换回来。
步骤如下(在允许停机维护的情况下进行):
1.禁用所有相关作业
2禁用应用程序登入用户<瞒jR2 |