有一次,我的SQL Server服务器上的数据驱动器即将耗尽空间,因此我不得不向PRIMARY数据组添加第二个文件,并限制第一个文件的增长。这导致新数据进入第二个文件,这很好。现在我想知道哪些表在第一个文件中有数据,以便在将数据迁移到第二个文件时可以知道哪些表将被锁定。有没有办法查看这个?
答案 0 :(得分:18)
您可以使用此脚本查看哪些表位于哪个文件组及其实际物理位置
SELECT OBJECT_NAME(i.id) AS [Table_Name]
, i.indid
, i.[name] AS [Index_Name]
, i.groupid
, f.name AS [File_Group]
, d.physical_name AS [File_Name]
, s.name AS [Data_Space]
FROM sys.sysindexes i
INNER JOIN sys.filegroups f ON f.data_space_id = i.groupid
AND f.data_space_id = i.groupid
INNER JOIN sys.database_files d ON f.data_space_id = d.data_space_id
INNER JOIN sys.data_spaces s ON f.data_space_id = s.data_space_id
WHERE OBJECTPROPERTY(i.id, 'IsUserTable') = 1
ORDER BY f.name, OBJECT_NAME(i.id), groupid
答案 1 :(得分:16)
附上一个类似于您情况的示例数据库。
-- Create database
CREATE DATABASE [out_of_space]
ON PRIMARY
( NAME = N'out_of_space_dat', FILENAME = N'C:\mssql\data\out_of_space_dat.mdf' , SIZE = 4MB , FILEGROWTH = 1MB, MAXSIZE = 4MB )
LOG ON
( NAME = N'out_of_space_log', FILENAME = N'C:\mssql\log\out_of_space_log.ldf' , SIZE = 1MB , FILEGROWTH = 4MB , MAXSIZE = 4MB )
GO
-- Switch to correct database
Use [out_of_space];
GO
-- Delete existing schema.
IF EXISTS (SELECT * FROM sys.schemas WHERE name = N'Temp')
DROP SCHEMA [Temp]
GO
-- Add new schema.
CREATE SCHEMA [Temp] AUTHORIZATION [dbo]
GO
-- Delete existing table
IF OBJECT_ID(N'[Temp].[PageSplits]') > 0
DROP TABLE [Temp].[PageSplits]
GO
-- Create new table
CREATE TABLE [Temp].[PageSplits]
(
[SplitId] [int] IDENTITY (1, 1) NOT NULL,
[SplitGuid] UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWSEQUENTIALID()),
[SplitDt] [datetime] NOT NULL DEFAULT (getdate()),
CONSTRAINT [pk_Split_Guid] PRIMARY KEY CLUSTERED
( [SplitGuid] ASC )
)
GO
-- Make 50K of records
DECLARE @VAR_CNT INT = 1;
WHILE (@VAR_CNT <= 50000)
BEGIN
INSERT [Temp].[PageSplits] DEFAULT VALUES;
SET @VAR_CNT = @VAR_CNT + 1;
END
GO
-- Get record count
SELECT COUNT(*) AS TOTAL_RECS
FROM [Temp].[PageSplits]
GO
-- Error Message
/*
Msg 1105, Level 17, State 2, Line 5
Could not allocate space for object 'Temp.PageSplits'.'pk_Split_Guid' in database 'out_of_space' because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.
*/
-- Show me the data file
sp_spaceused '[Temp].[PageSplits]'
/*
name rows reserved data index_size unused
PageSplits 46870 1736 KB 1720 KB 16 KB 0 KB
*/
基本上,我使第一个主数据文件空间不足。
添加其他数据文件后,它会自动添加到主文件组。
-- Add another file
ALTER DATABASE [out_of_space]
ADD FILE
(
NAME = out_of_space_dat2,
FILENAME = N'C:\mssql\data\out_of_space_dat2.ndf',
SIZE = 2MB,
MAXSIZE = 10MB,
FILEGROWTH = 2MB
);
GO
-- Make 5K of records
DECLARE @VAR_CNT INT = 1;
WHILE (@VAR_CNT <= 5000)
BEGIN
INSERT [Temp].[PageSplits] DEFAULT VALUES;
SET @VAR_CNT = @VAR_CNT + 1;
END
GO
有许多方法可以在SQL Server中查找空间使用情况。
首先是目录视图。 Ali的解决方案不显示使用的页面,最大尺寸等。
-- Get allocation units by file and partition
select
OBJECT_NAME(p.object_id) as my_table_name,
u.type_desc,
f.file_id,
f.name,
f.physical_name,
f.size,
f.max_size,
f.growth,
u.total_pages,
u.used_pages,
u.data_pages,
p.partition_id,
p.rows
from sys.allocation_units u
join sys.database_files f on u.data_space_id = f.data_space_id
join sys.partitions p on u.container_id = p.hobt_id
where
u.type in (1, 3) and
OBJECT_NAME(p.object_id) = 'PageSplits'
GO
我的解决方案确实为您提供了这些信息。
获取此信息的另一种方法来自动态管理视图。
-- Management view (partitions)
SELECT * FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('Temp.PageSplits');
GO
-- Management view (files)
SELECT db_name(database_id) as database_nm, * FROM sys.dm_db_file_space_usage
GO
重建表以使其位于一个文件上的唯一方法是创建新文件组和新文件。确保文件已链接到新组。
-- Add a new file group
ALTER DATABASE [out_of_space]
ADD FILEGROUP fg_new_space
GO
-- Add the third data file
ALTER DATABASE [out_of_space]
ADD FILE
(
NAME = out_of_space_dat3,
FILENAME = N'C:\mssql\data\out_of_space_dat3.ndf',
SIZE = 2MB,
MAXSIZE = 10MB,
FILEGROWTH = 2MB
)
TO FILEGROUP fg_new_space
GO
删除约束并将数据移动到新文件组。构建一个默认为表文件组的新主键。正是我们想要的。
-- Drop the constraint
ALTER TABLE [Temp].[PageSplits] DROP CONSTRAINT [pk_Split_Guid] WITH (MOVE TO [fg_new_space])
GO
-- Add back the primary key
ALTER TABLE [Temp].[PageSplits] ADD
CONSTRAINT [pk_Split_Guid] PRIMARY KEY CLUSTERED
( [SplitGuid] ASC );
完成本文的最后一项。我们可以通过SSMS获得空间数量。让我们看一下表格属性。
让我们看一下索引属性。
表和群集索引现在都在新文件/文件组上。