2013-11-21 13 views
6

Tại một thời điểm, ổ đĩa dữ liệu của tôi trên máy chủ SQL Server sắp hết dung lượng, vì vậy tôi phải thêm một tệp thứ hai vào nhóm dữ liệu PRIMARY và đặt giới hạn cho sự tăng trưởng của tệp đầu tiên. Điều đó làm cho dữ liệu mới đi vào tập tin thứ hai, đó là tốt. Bây giờ tôi muốn biết bảng nào có dữ liệu trong tệp đầu tiên để tôi có thể biết bảng nào sẽ bị khóa khi tôi di chuyển dữ liệu đó sang tệp thứ hai. Có cách nào để xem cái này không?Xem dữ liệu nào nằm trong tệp dữ liệu SQL Server nào?

Trả lời

14

Kèm theo đây là một cơ sở dữ liệu mẫu tương tự như tình hình của bạn.

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

*/ 

Về cơ bản, tôi đã tạo tệp dữ liệu chính đầu tiên hết dung lượng.

Khi bạn thêm tệp dữ liệu bổ sung, nó sẽ tự động được thêm vào nhóm tệp chính .

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

Có nhiều cách để thực hiện những việc như tìm mức sử dụng không gian trong SQL Server.

Đầu tiên là lượt xem danh mục. Giải pháp của Ali không hiển thị các trang được sử dụng, kích thước tối đa, v.v.

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

Giải pháp của tôi cung cấp cho bạn thông tin đó.

enter image description here

Một cách khác để có được thông tin này là từ quan quản lý động.

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

Cách duy nhất để xây dựng lại bàn để nó vào một tập tin là để tạo ra một nhóm tập tin mới và một tập tin mới. Đảm bảo tệp được liên kết với nhóm mới.

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

Thả ràng buộc và chuyển dữ liệu vào nhóm tệp mới. Tạo khóa chính mới mặc định cho nhóm tệp bảng. Chỉ là những gì chúng ta muốn.

-- 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); 

Một mục cuối cùng để hoàn thành bài viết này. Chúng tôi có thể nhận được số lượng không gian thông qua SSMS. Cho phép xem xét các thuộc tính bảng.

enter image description here

Cho phép xem xét thuộc tính chỉ mục.

enter image description here

Cả bảng và chỉ mục cụm giờ đều nằm trong nhóm/tệp mới.

+0

Bạn đang nói DBCC SHRINKFILE (dbdatafile1, EMPTYFILE) sẽ không chuyển tất cả dữ liệu sang tệp thứ hai? – influent

+0

Mọi cơ sở dữ liệu đều có 1 * .mdf tệp (tệp dữ liệu chính), 1+ * .ndf (tệp dữ liệu thứ cấp) và 1+ * .ldf tệp nhật ký. Như đã nêu từ Microsoft, bạn không thể làm trống tệp .mdf vì đó là vị trí của tệp khởi động cho cơ sở dữ liệu với thông tin hệ thống. Do đó, bạn không thể thực hiện những gì bạn đang cố gắng. Ngoài ra, kể từ khi WAL - viết ghi nhật ký trước là một luồng, nhiều tệp * .ldf không hỗ trợ hiệu suất. –

+0

Cảm ơn nhưng câu trả lời dài dòng. – FLICKER

16

Bạn có thể sử dụng kịch bản này để xem bảng đang trên mà nhóm tập tin và vị trí địa lý thực tế của họ

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 
+0

Kịch bản tuyệt vời. +1 –

+1

Làm thế nào về các datafiles của các đối tượng khác như các chỉ mục văn bản đầy đủ, các chỉ mục không phân cụm, các định nghĩa SP, v.v .. Làm thế nào để kịch bản này có thể được sửa đổi để nó hiển thị tất cả các đối tượng trong một db nhất định? – Stackoverflowuser

+0

Câu trả lời chính xác! Cảm ơn. – FLICKER

Các vấn đề liên quan