查看SQL Server数据文件中的数据是什么?

时间:2013-11-21 18:25:17

标签: sql-server sql-server-2012

有一次,我的SQL Server服务器上的数据驱动器即将耗尽空间,因此我不得不向PRIMARY数据组添加第二个文件,并限制第一个文件的增长。这导致新数据进入第二个文件,这很好。现在我想知道哪些表在第一个文件中有数据,以便在将数据迁移到第二个文件时可以知道哪些表将被锁定。有没有办法查看这个?

2 个答案:

答案 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

我的解决方案确实为您提供了这些信息。

enter image description here

获取此信息的另一种方法来自动态管理视图

-- Management view (partitions)
SELECT * FROM sys.dm_db_partition_stats 
WHERE object_id = OBJECT_ID('Temp.PageSplits');
GO

enter image description here

-- Management view (files)
SELECT db_name(database_id) as database_nm, * FROM sys.dm_db_file_space_usage
GO

enter image description here

重建表以使其位于一个文件上的唯一方法是创建新文件组和新文件。确保文件已链接到新组。

-- 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获得空间数量。让我们看一下表格属性。

enter image description here

让我们看一下索引属性。

enter image description here

表和群集索引现在都在新文件/文件组上。