sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)
转自:https://www.cnblogs.com/lyhabc/p/3504380.html?utm_source=tuicool
SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件组
总结:
(1)如果是一个文件组内只有一个文件
~~把所有在该文件组内的表删除聚集索引,然后新建聚集索引至新的文件组
(2)如果是一个文件组内多个文件 【1】把某个文件清空转移到其他文件:使用DBCC SHRINKFILE(要移动数据的数据文件逻辑名称,EMPTYFILE)
【2】把该文件组内所有文件内数据都转移到另外一个文件组: ~~首先使用 DBCC SHRINKFILE(要移动数据的数据文件逻辑名称,EMPTYFILE),把所有数据都转移到同一个文件上去
~~把所有在该文件组内的表删除聚集索引,然后新建聚集索引至新的文件组
--.收缩文件
DBCC SHRINKFILE(test2,EMPTYFILE) --.移除test2数据文件test2.ndf
ALTER DATABASE TEST1
REMOVE FILE test2
这里要根据是一对多还是一对一来选择移动数据的方法 如果是一对多:使用DBCC SHRINKFILE(要移动数据的数据文件逻辑名称,EMPTYFILE) 如果是一对一:删除原有聚集索引,创建新的聚集索引到迁移的文件组 可以使用sp_help 查看表所在文件组, 可以使用如下查看数据库文件与文件组情况。 EXEC [sys].[sp_helpdb] @dbname = TEST1
-- sysname
SELECT DB_NAME(database_id) AS DatabaseName ,
Name AS Logical_Name ,
Physical_Name ,
( size * 8 ) / 1024 SizeMB
FROM sys.master_files
WHERE DB_NAME(database_id) = 'Test1'
sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)
之前写过一篇文章:SQLSERVER将一个文件组的数据移动到另一个文件组
每个物理文件(数据文件)对应一个文件组的情况(一对一)
如果我把数据移到另一个文件组了,不想要这个已经清空的文件组了,怎麽做?
脚本跟之前那篇文章差不多

1 USE master
2 GO
3
4
5 IF EXISTS(SELECT * FROM sys.[databases] WHERE [database_id]=DB_ID('Test'))
6 DROP DATABASE [Test]
7
8 --1.创建数据库
9 CREATE DATABASE [Test]
10 GO
11
12 USE [Test]
13 GO
14
15
16 --2.创建文件组
17 ALTER DATABASE [Test]
18 ADD FILEGROUP [FG_Test_Id_01]
19
20 ALTER DATABASE [Test]
21 ADD FILEGROUP [FG_Test_Id_02]
22
23
24
25 --3.创建文件
26 ALTER DATABASE [Test]
27 ADD FILE
28 (NAME = N'FG_TestUnique_Id_01_data',FILENAME = N'E:\FG_TestUnique_Id_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
29 TO FILEGROUP [FG_Test_Id_01];
30
31 ALTER DATABASE [Test]
32 ADD FILE
33 (NAME = N'FG_TestUnique_Id_02_data',FILENAME = N'E:\FG_TestUnique_Id_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
34 TO FILEGROUP [FG_Test_Id_02];
35
36
37 --4.创建表,这个表的数据存放在[FG_Test_Id_01] 文件组上
38 CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01]
39 GO
40
41
42 --5.插入数据
43 INSERT INTO [dbo].[aa]
44 SELECT 1,REPLICATE('s',3000)
45 GO 500
46
47
48 --6.查询数据
49 SELECT * FROM [dbo].[aa]
50
51
52 --7.创建聚集索引在[FG_Test_Id_02]文件组上
53 CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
54 GO
55
56
57 --8.我们查看一下文件组的逻辑文件名
58 EXEC [sys].[sp_helpdb] @dbname = TEST -- sysname
59
65
66 --9.移除FG_Test_Id_01文件组
67 ALTER DATABASE TEST
68 REMOVE FILE FG_TestUnique_Id_01_data

当你移动数据到文件组[FG_Test_Id_02]上时,这时候文件组[FG_Test_Id_01]里面已经没有数据了
使用下面的脚本查看

1 --数据库文件、大小和已经使用空间
2 USE [Test] --要查看的当前数据库的使用空间,自动增长大小,数据库文件位置
3 GO
4 set nocount on
5 create table #Data(
6 FileID int NOT NULL,
7 [FileGroupId] int NOT NULL,
8 TotalExtents int NOT NULL,
9 UsedExtents int NOT NULL,
10 [FileName] sysname NOT NULL,
11 [FilePath] nvarchar(MAX) NOT NULL,
12 [FileGroup] varchar(MAX) NULL)
13
14 create table #Results(
15 db sysname NULL ,
16 FileType varchar(4) NOT NULL,
17 [FileGroup] sysname not null,
18 [FileName] sysname NOT NULL,
19 TotalMB numeric(18,2) NOT NULL,
20 UsedMB numeric(18,2) NOT NULL,
21 PctUsed numeric(18,2) NULL,
22 FilePath nvarchar(MAX) NULL,
23 FileID int null)
24
25 create table #Log(
26 db sysname NOT NULL,
27 LogSize numeric(18,5) NOT NULL,
28 LogUsed numeric(18,5) NOT NULL,
29 Status int NOT NULL,
30 [FilePath] nvarchar(MAX) NULL)
31
32 INSERT #Data (FileID, [FileGroupId], TotalExtents, UsedExtents, [FileName], [FilePath])
33 EXEC ('DBCC showfilestats WITH NO_INFOMSGS')
34
35 update #Data
36 set #Data.FileGroup = sysfilegroups.groupname
37 from #Data, sysfilegroups
38 where #Data.FileGroupId = sysfilegroups.groupid
39
40 INSERT INTO #Results (db, [FileGroup], FileType, [FileName], TotalMB, UsedMB, PctUsed, FilePath, FileID)
41 SELECT DB_NAME() db,
42 [FileGroup],
43 'Data' FileType,
44 [FileName],
45 TotalExtents * 64./1024. TotalMB,
46 UsedExtents *64./1024 UsedMB,
47 UsedExtents*100. /TotalExtents UsedPct,
48 [FilePath],
49 FileID
50 FROM #Data
51 order BY --1,2
52 DB_NAME(), [FileGroup]
53
54 insert #Log (db,LogSize,LogUsed,Status)
55 exec('dbcc sqlperf(logspace) WITH NO_INFOMSGS ')
56
57 insert #Results(db, [FileGroup], FileType, [FileName], TotalMB,UsedMB, PctUsed, FilePath, FileID)
58 select DB_NAME() db,
59 'Log' [FileGroup],
60 'Log' FileType,
61 s.[name] [FileName],
62 s.Size/128. as LogSize ,
63 FILEPROPERTY(s.name,'spaceused')/8.00 /16.00 As LogUsedSpace,
64 ((FILEPROPERTY(s.name,'spaceused')/8.00 /16.00)*100)/(s.Size/128.) UsedPct,
65 s.FileName FilePath,
66 s.FileID FileID
67 from #Log l , master.dbo.sysaltfiles f , dbo.sysfiles s
68 where f.dbid = DB_ID()
69 and (s.status & 0x40) <> 0
70 and s.FileID = f.FileID
71 and l.db = DB_NAME()
72
73 SELECT r.db AS "Database",
74 r.FileType AS "File type",
75 CASE
76 WHEN r.FileGroup = 'Log' Then 'N/A'
77 ELSE r.FileGroup
78 END "File group",
79 r.FileName AS "Logical file name",
80 r.TotalMB AS "Total size (MB)",
81 r.UsedMB AS "Used (MB)",
82 r.PctUsed AS "Used (%)",
83 r.FilePath AS "File name",
84 r.FileID AS "File ID",
85 CASE WHEN s.maxsize = -1 THEN null
86 ELSE CONVERT(decimal(18,2), s.maxsize /128.)
87 END "Max. size (MB)",
88 CONVERT(decimal(18,2), s.growth /128.) "Autogrowth increment (MB)"
89 FROM #Results r
90 INNER JOIN dbo.sysfiles s
91 ON r.FileID = s.FileID
92 ORDER BY 1,2,3,4,5
93
94 DROP TABLE #Data
95 DROP TABLE #Results
96 DROP TABLE #Log

使用下面的SQL语句移除文件组[FG_Test_Id_01]就可以了
5 --9.移除FG_Test_Id_01文件组
6 ALTER DATABASE TEST
7 REMOVE FILE FG_TestUnique_Id_01_data
此时就只剩下主文件组和[FG_Test_Id_02]文件组了
注意:如果不使用聚集索引来移动文件组[FG_Test_Id_01]上的数据到文件组[FG_Test_Id_02]
1 --4.创建表,这个表的数据存放在[FG_Test_Id_01] 文件组上
2 CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01]
3 GO
直接使用下面SQL语句来收缩文件会报错
1 -收缩一下FG_Test_Id_01文件组文件
2 DBCC SHRINKFILE(FG_TestUnique_Id_01_data,EMPTYFILE)
报错内容

1 DBCC SHRINKFILE: 无法移动堆页 3:515。
2 消息 2555,级别 16,状态 1,第 1 行
3 无法将文件 "FG_TestUnique_Id_01_data" 的所有内容移到其他位置,以完成清空文件操作。
4 语句已终止。
5 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
6 消息 1105,级别 17,状态 2,第 1 行
7 无法为数据库 'Test' 中的对象 'dbo.aa' 分配空间,因为 'FG_Test_Id_01' 文件组已满。请删除不需要的文件、删除文件组中的对象、将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘空间。

因为文件组[FG_Test_Id_01]里还有数据,不能清空
两个物理文件(数据文件)对应一个文件组的情况(一对多)
上面的情况是每个物理文件(数据文件)对应一个文件组的情况
下面这种情况是两个物理文件(数据文件)对于一个文件组的情况
一对一的情况使用聚集索引里移动数据,而一对一的情况使用DBCC SHRINKFILE
创建数据库
test1和test2这两个数据文件归属于主文件组primary,而数据文件test1最大大小为6MB初始大小为5MB
test2数据文件最大大小没有限制
使用下面脚本添加数据到主文件组

1 --1.创建表,这个表的数据存放在主文件组上
2 CREATE TABLE aa(id INT ,cname NVARCHAR(4000))
3 GO
4
5
6 --2.插入数据
7 INSERT INTO [dbo].[aa]
8 SELECT 1,REPLICATE('s',3000)
9 GO 600
10
11
12 --3.查询数据
13 SELECT * FROM [dbo].[aa]
14
15
16
17
18 --4.我们查看一下文件组的逻辑文件名
19 EXEC [sys].[sp_helpdb] @dbname = TEST1
20 -- sysname
21 SELECT DB_NAME(database_id) AS DatabaseName ,
22 Name AS Logical_Name ,
23 Physical_Name ,
24 ( size * 8 ) / 1024 SizeMB
25 FROM sys.master_files
26 WHERE DB_NAME(database_id) = 'Test1'

因为第一个数据文件的最大大小限制,所以有一部分数据插入到了test2.ndf
现在修改test1数据文件的最大大小限制为20MB
相关SQL
1 ALTER DATABASE [Test1] MODIFY FILE(name='Test1',SIZE=5MB, filegrowth=1MB, MAXSIZE=20MB)
执行下面的SQL语句

1 --5.收缩文件
2 DBCC SHRINKFILE(test2,EMPTYFILE)
3
4
5 --6.移除test2数据文件test2.ndf
6 ALTER DATABASE TEST1
7 REMOVE FILE test2

在执行第五条语句的时候,执行下面脚本

1 --数据库文件、大小和已经使用空间
2 USE [Test1] --要查看的当前数据库的使用空间,自动增长大小,数据库文件位置
3 GO
4 set nocount on
5 create table #Data(
6 FileID int NOT NULL,
7 [FileGroupId] int NOT NULL,
8 TotalExtents int NOT NULL,
9 UsedExtents int NOT NULL,
10 [FileName] sysname NOT NULL,
11 [FilePath] nvarchar(MAX) NOT NULL,
12 [FileGroup] varchar(MAX) NULL)
13
14 create table #Results(
15 db sysname NULL ,
16 FileType varchar(4) NOT NULL,
17 [FileGroup] sysname not null,
18 [FileName] sysname NOT NULL,
19 TotalMB numeric(18,2) NOT NULL,
20 UsedMB numeric(18,2) NOT NULL,
21 PctUsed numeric(18,2) NULL,
22 FilePath nvarchar(MAX) NULL,
23 FileID int null)
24
25 create table #Log(
26 db sysname NOT NULL,
27 LogSize numeric(18,5) NOT NULL,
28 LogUsed numeric(18,5) NOT NULL,
29 Status int NOT NULL,
30 [FilePath] nvarchar(MAX) NULL)
31
32 INSERT #Data (FileID, [FileGroupId], TotalExtents, UsedExtents, [FileName], [FilePath])
33 EXEC ('DBCC showfilestats WITH NO_INFOMSGS')
34
35 update #Data
36 set #Data.FileGroup = sysfilegroups.groupname
37 from #Data, sysfilegroups
38 where #Data.FileGroupId = sysfilegroups.groupid
39
40 INSERT INTO #Results (db, [FileGroup], FileType, [FileName], TotalMB, UsedMB, PctUsed, FilePath, FileID)
41 SELECT DB_NAME() db,
42 [FileGroup],
43 'Data' FileType,
44 [FileName],
45 TotalExtents * 64./1024. TotalMB,
46 UsedExtents *64./1024 UsedMB,
47 UsedExtents*100. /TotalExtents UsedPct,
48 [FilePath],
49 FileID
50 FROM #Data
51 order BY --1,2
52 DB_NAME(), [FileGroup]
53
54 insert #Log (db,LogSize,LogUsed,Status)
55 exec('dbcc sqlperf(logspace) WITH NO_INFOMSGS ')
56
57 insert #Results(db, [FileGroup], FileType, [FileName], TotalMB,UsedMB, PctUsed, FilePath, FileID)
58 select DB_NAME() db,
59 'Log' [FileGroup],
60 'Log' FileType,
61 s.[name] [FileName],
62 s.Size/128. as LogSize ,
63 FILEPROPERTY(s.name,'spaceused')/8.00 /16.00 As LogUsedSpace,
64 ((FILEPROPERTY(s.name,'spaceused')/8.00 /16.00)*100)/(s.Size/128.) UsedPct,
65 s.FileName FilePath,
66 s.FileID FileID
67 from #Log l , master.dbo.sysaltfiles f , dbo.sysfiles s
68 where f.dbid = DB_ID()
69 and (s.status & 0x40) <> 0
70 and s.FileID = f.FileID
71 and l.db = DB_NAME()
72
73 SELECT r.db AS "Database",
74 r.FileType AS "File type",
75 CASE
76 WHEN r.FileGroup = 'Log' Then 'N/A'
77 ELSE r.FileGroup
78 END "File group",
79 r.FileName AS "Logical file name",
80 r.TotalMB AS "Total size (MB)",
81 r.UsedMB AS "Used (MB)",
82 r.PctUsed AS "Used (%)",
83 r.FilePath AS "File name",
84 r.FileID AS "File ID",
85 CASE WHEN s.maxsize = -1 THEN null
86 ELSE CONVERT(decimal(18,2), s.maxsize /128.)
87 END "Max. size (MB)",
88 CONVERT(decimal(18,2), s.growth /128.) "Autogrowth increment (MB)"
89 FROM #Results r
90 INNER JOIN dbo.sysfiles s
91 ON r.FileID = s.FileID
92 ORDER BY 1,2,3,4,5
93
94 DROP TABLE #Data
95 DROP TABLE #Results
96 DROP TABLE #Log

你会发现
数据都移动到了test1.mdf里去了
执行第六条SQL语句,删除test2.ndf文件
数据没有丢失
这里关键在于EMPTYFILE参数 :DBCC SHRINKFILE(test2,EMPTYFILE)
总结
这里要根据是一对多还是一对一来选择移动数据的方法
如果是一对多:使用DBCC SHRINKFILE(要移动数据的数据文件,EMPTYFILE)
如果是一对一:创建聚集索引
参考文章: [SQL]透過 DBCC SHRINKFILE([要清空的File], EMPTYFILE) 來將資料移到另一個資料檔之中
大家可以做一下实验
对于同一个文件组里的多个数据文件(不一定是主文件组),
比如有有个文件组叫[FG_Test_01],里面有两个数据文件test3.ndf和test4.ndf
test3.ndf和test4.ndf都有数据
如果我运行DBCC SHRINKFILE(test4,EMPTYFILE),test4.ndf里的数据是否会移动到test3.ndf还是会移动到test1.mdf???
这个实验留给大家o(∩_∩)o
2014-1-14补充:
这个实验的测试脚本和结果

1 USE master
2 GO
3
4 --DROP DATABASE [Test]
5
6
7 IF EXISTS(SELECT * FROM sys.[databases] WHERE [database_id]=DB_ID('Test'))
8 DROP DATABASE [Test]
9
10 --1.创建数据库
11 CREATE DATABASE [Test]
12 GO
13
14 USE [Test]
15 GO
16
17
18 --2.创建文件组
19 ALTER DATABASE [Test]
20 ADD FILEGROUP [FG_Test_Id_01]
21
22
23
24
25
26 --3.创建文件
27 ALTER DATABASE [Test]
28 ADD FILE
29 (NAME = N'FG_TestUnique_Id_01_data',FILENAME = N'E:\FG_TestUnique_Id_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
30 TO FILEGROUP [FG_Test_Id_01];
31
32 ALTER DATABASE [Test]
33 ADD FILE
34 (NAME = N'FG_TestUnique_Id_02_data',FILENAME = N'E:\FG_TestUnique_Id_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
35 TO FILEGROUP [FG_Test_Id_01];
36
37
38
39
40
41 --4.创建表,这个表的数据存放在[FG_Test_Id_02] 文件组上
42 CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01]
43 GO
44
45
46 --5.插入数据
47 INSERT INTO [dbo].[aa]
48 SELECT 1,REPLICATE('s',3000)
49 GO 1000
50
51
52 --6.查询数据
53 SELECT * FROM [dbo].[aa]
54
55
56
57
58 --7.我们查看一下文件组的逻辑文件名
59 EXEC [sys].[sp_helpdb] @dbname = TEST -- sysname
60
61
62
63 --8.收缩文件
64 DBCC SHRINKFILE(FG_TestUnique_Id_02_data,EMPTYFILE)
65
66
67 --9.移除FG_TestUnique_Id_03_data数据文件FG_TestUnique_Id_03_data.ndf
68 ALTER DATABASE TEST
69 REMOVE FILE FG_TestUnique_Id_02_data
70
71
72
73 --10.查询数据
74 SELECT * FROM [dbo].[aa]
75 SELECT COUNT(*) FROM [dbo].[aa]

数据没有丢失
答案:
FG_TestUnique_Id_02_data.ndf里的数据会移动到FG_TestUnique_Id_01_data.ndf,不会移动到Test.mdf
因为DBCC SHRINKFILE只能在同一文件组内移动数据,而mdf只能属于主文件组primary
然后插入数据到分区表报错没有分配文件
sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)的更多相关文章
- 数据库迁移(SQL SERVER导入数据到MySql)
地址:http://blog.csdn.net/jiaohougenyang/article/details/44937801 背景:项目最开始时使用的是SQL Server数据库,业务需求现要将数据 ...
- SQL Server GUID 数据迁移至MongoDB后怎样查看?
关键字:SQL Server NEWID():BSON:MongoDB UUID 1.遇到的问题和困惑 SQL Server中的NEWID数据存储到MongoDB中会是什么样子呢?发现不能简单的通过此 ...
- 微软BI 之SSIS 系列 - 两种将 SQL Server 数据库数据输出成 XML 文件的方法
开篇介绍 在 SSIS 中并没有直接提供从数据源到 XML 的转换输出,Destination 的输出对象有 Excel File, Flat File, Database 等,但是并没有直接提供 X ...
- 《转》SQL Server 2008 数据维护实务
SQL Server 2008 数据维护实务 http://blog.csdn.net/os005/article/details/7739553 http://www.cnblogs.com/xun ...
- 在SQL Server中将数据导出为XML和Json
有时候需要一次性将SQL Server中的数据导出给其他部门的也许进行关联或分析,这种需求对于SSIS来说当然是非常简单,但很多时候仅仅需要一次性导出这些数据而建立一个SSIS包就显得小题大做 ...
- SQL Server 将数据导出为XML和Json
有时候需要一次性将SQL Server中的数据导出给其他部门的也许进行关联或分析,这种需求对于SSIS来说当然是非常简单,但很多时候仅仅需要一次性导出这些数据而建立一个SSIS包就显得小题大做,而SQ ...
- SQL Server 变更数据捕获(CDC)监控表数据
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现过程(Realization) 补充说明(Addon) 参考文献(References) ...
- ORACLE和SQL SERVER的数据同步常用方法
ORACLE和SQL SERVER的数据同步常用方法 1. 自己编程,或者第三方工具2. 在sqlserver中,使用linkedserver,访问oracle,然后编写job进行数据同步3. 在or ...
- sql server导出数据,远程连接失败,需要设置权限
在sql server management中右键当前连接——>方面 在 服务器配置中 将 RemoteAccessEnabled.RemoteDacEnabled设置为TRUE 安全性—— ...
- sql server复制数据到excel格式变成字符串
sql server复制数据到excel格式变成字符串,结果数据都保存在第一个格子里面. 我点击连同标题一起复制,然后粘贴到excel,结果是这样子的.... 这不是我想要的结果,在网上查询了好多,结 ...
随机推荐
- Java的ThreadContext类加载器的实现
疑惑 以前在看源码的时候,总是会遇到框架里的代码使用Thread.currentThread.getContextClassLoader()获取当前线程的Context类加载器,通过这个Context ...
- java中for循环执行过程
for (int j = 0; j < newSize; j++) { //执行todo } 1.首先变量j初始化为0 2.然后j=0的值跟newSize进行比较,假如为true,则执行{}里面 ...
- spring-core依赖jar包
- win 7和虚拟机之间ping
虚拟机的网卡和真实机的IP设为同一网段.用ping检查是否通,通了后用工具连接ssh看能否登录!如果成功的话winscp应该就能用了.如果不同就要就检查防火墙看是否开放了22端口,没有的话就要开放一下 ...
- centos7.4 install docker-ce
1.uninstall old version docker yum -y remove docker-common docker container-selinux docker-selinux d ...
- Xcode模拟iPhone教程!
iOS 开发者常常会使用模拟器来进行调试,当然这就少不了Mac电脑中的Xcode软件了,今天PC6小编就给大家带来在Mac系统下如何快速启动iOS模拟器的使用教程: 一.如何启动iOS模拟器 1.在L ...
- volatile关键字是什么意思
我写了一段简单的对比代码并分别用vs2017以release方式编译然后用IDA观察汇编代码,如下图所示: 代码1 int a=5; printf("%d",a) 代码2 vola ...
- [Idea Fragments] PostScript for 3D Print??
今天看到一篇关于PostScript的文章<编程珠玑番外篇-P PostScript 语言里的珠玑>,尤其是篇尾的这段话,让我对3D Print浮想联翩: 因为 PostScript 语言 ...
- 阐述二维码的原理以及使用google api和PHP QR Code来生成二维码
一.什么是二维码:二维码 (2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的.在许多种类的二维条码中,常用的码 ...
- ios开发之 -- 调用系统定位获取当前经纬度与地理信息
ios 10定位: 在info.plist中加入: //允许在前台使用时获取GPS的描述 定位权限:Privacy - Location When In Use Usage Description / ...