如何移动SQL Server数据库文件?


103

我有一个数据库,想要将.mdf.ldf文件移动到另一个位置。但是我不想停止该MSSQLSERVER服务,也不想导出到另一台服务器。

我怎样才能做到这一点?

Answers:


154

您不必停止SQL Server服务即可移动数据库文件,但必须使特定的数据库脱机。这是因为在访问文件时无法移动文件,并且使数据库脱机会阻止SQL Server应用程序使用文件。

移动它们的过程非常简单。已经描述了分离/附接,但是它并不复杂。

使用以下ALTER DATABASE命令更改文件位置:

USE master; --do this all from the master
ALTER DATABASE foo
MODIFY FILE (name='DB_Data1'
             ,filename='X:\NewDBFile\DB_Data1.mdf'); --Filename is new location

注意,您无需在此命令中声明旧位置。更改此路径不会立即生效,但将在下次数据库启动时使用。

使数据库脱机

(我WITH ROLLBACK IMMEDIATE经常将所有人踢出并回滚所有当前未完成的交易)

ALTER DATABASE foo SET OFFLINE WITH ROLLBACK IMMEDIATE;

将文件移动/复制到新位置

只需使用您喜欢的方法复制文件即可(单击'n拖动,XCopy,Copy-Item,Robocopy)

使数据库联机

ALTER DATABASE foo SET ONLINE;

您可以在此处看到更详细的描述。


13
这对我有用。就我而言,我也必须使用第一个命令来移动LDF文件:例如 USE master; --do this all from the master ALTER DATABASE foo MODIFY FILE (name='DB_Data1_log' ,filename='X:\NewDBFile\DB_Data1_log.ldf'); --Filename is new location
Dewi Rees15 2015年

1
也可以仅通过更新文件名以使其与在文件对话框中看到的内容匹配,即可移动全文本索引文件。
DShook 2015年

24
确保在移动数据库文件后,“ NT SERVICE \ MSSQLSERVER”用户具有该文件的权限,否则在尝试使数据库重新联机时会出现错误。
Demonslay335

“名称”应该是什么?在文档中,它具有“ logical_name”。他们的意思是什么?
约翰尼

2
@mlhDev实际上,在我看来,MODIFY FILE顺序是可以更改的。如果先运行MODIFY FILE,它会告诉您命令已成功运行,并且在脱机在线操作后位置会更改(措辞有所不同,但您会明白)。但是,出于明显的原因,脱机->移动文件->联机顺序确实很重要。还要标记Demonslay335的注释。文件权限很重要。
莱昂内特·陈

50

数据库联机时,MDF和LDF文件受到保护,无法移动。

如果您不介意停止数据库的工作,则可以DETACH将其删除,然后再移动文件ATTACH

  • 右键单击数据库名称
  • 选择 Properties
  • 转到Files标签
  • 请记下的PathFileNameMDF和LDF文件。如果您不想最终搜索丢失的文件,则此步骤很重要。
  • 右键单击数据库名称
  • 选择 Tasks -> Detach
  • 将文件移到所需位置
  • 右键单击Databases服务器的节点
  • 选择 Attach
  • 点击Add按钮
  • 指向新位置
  • 请点击 OK

你现在应该没事。有关信息DETACH- ATTACH过程,可以发现在这里

在关于DETACH- 的链接中,ATTACH建议将using ALTER DATABASE语句保持在SQL Server的相同实例上。移动用户数据库中有更多参考。

如果要在移动时保持其运行,请执行BACKUP- RESTORE。在还原过程中,您可以定义数据库文件的新位置。


3
我建议以管理员身份打开SQL Management Studio,以避免重新连接时出现文件访问问题
Simon_Weaver

6

要移动系统数据库文件,请按照下列步骤操作:

  1. 在SSMS中以sa用户身份登录

  2. 为了安全起见,请备份用户创建的数据库。

  3. 杀死所有从SSMS连接到服务器的会话。

  4. 执行以下命令,检查系统数据库的当前文件位置:

    USE master;
    SELECT * FROM sys.master_files;

标识路径并记下文件的当前路径。

  1. 使用TSQL更改除master以外的所有数据库的文件路径:

    ALTER DATABASE database_name MODIFY FILE ( NAME = logical_name , FILENAME = 'new_path\os_file_name' )

例如:

ALTER DATABASE tempdb
MODIFY FILE ( NAME = tempdev
, FILENAME = "DestinationPath\tempdb.mdf");

ALTER DATABASE tempdb
MODIFY FILE ( NAME = templog
, FILENAME = "DestinationPath\templog.ldf");

ALTER DATABASE model
MODIFY FILE ( NAME = modeldev
, FILENAME = "DestinationPath\model.mdf");

ALTER DATABASE model
MODIFY FILE ( NAME = modellog
, FILENAME = "DestinationPath\modellog.ldf");

ALTER DATABASE msdb
    MODIFY FILE ( NAME = MSDBData
, FILENAME = "DestinationPath\msdbdata.mdf");

ALTER DATABASE msdb
    MODIFY FILE ( NAME = MSDBLog
, FILENAME = "DestinationPath\msdblog.ldf");

现在文件位置已更改。

确保同时移动ldf和mdf文件

  1. 在SSMS中,右键单击服务器,然后选择属性。内部属性转到“数据库设置”。将数据库默认位置更改为“数据”,然后将“日志”更改为目标路径。从服务器注销。

    例如:更改C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\E:\projects\DataBaseFiles\MSSQL\DATA\

  2. 停止SQL Server实例。

  3. 将一个或多个文件复制到新位置。使用Robocopy移动文件,以便将访问权限复制到目标文件夹。打开cmd并以管理员身份运行,并使用以下命令:

    robocopy / sec源文件夹目标文件夹

最好去源位置运行命令。删除复制的系统数据库文件以外的其他文件。例如:

 robocopy /sec .\DATA E:\projects\DataBaseFiles\MSSQL\DATA\

(在这里,我们将所有系统数据库文件移动到新位置。)

  1. 从“开始”菜单,指向“所有程序”,再指向“ Microsoft SQL Server”,再指向“配置工具”,然后单击“ SQL Server配置管理器”。

在SQL Server配置管理器中执行以下步骤:

在“ SQL Server服务”节点中,右键单击SQL Server实例(例如,SQL Server(MSSQLSERVER)),然后选择“属性”。在“ SQL Server(instance_name)属性”对话框中,单击“启动参数”选项卡。在“现有参数”框中,选择-d参数以移动主数据文件。单击更新以保存更改。在“指定启动参数”框中,将参数更改为master数据库的新路径。在“现有参数”框中,选择–l参数以移动主日志文件。单击更新以保存更改。在“指定启动参数”框中,将参数更改为master数据库的新路径。

数据文件的参数值必须跟随-d参数,日志文件的值必须跟随-l参数。以下示例显示了主数据文件的默认位置的参数值。

-dC:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\master.mdf
-lC:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\mastlog.ldf

如果计划的主数据文件重定位为E:\ SQLData,则参数值将按以下方式更改:

-dE:\projects\DataBaseFiles\MSSQL\DATA\master.mdf
-lE:\projects\DataBaseFiles\MSSQL\DATA\mastlog.ldf

通过右键单击实例名称并选择“停止”来停止SQL Server实例。重新启动SQL Server实例。

  1. sa用户身份登录SSMS,并通过执行以下查询来验证数据库文件的位置:

    USE master;
    SELECT * FROM sys.master_files;

全部做完。


您可以使用SQL函数自动执行所有数据库的任务:stackoverflow.com/a/19505918/439524
amuliar

3

您会逐步进行:

  1. 关闭所有连接
    ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE

  2. 将数据库设置为脱机状态
    ALTER DATABASE MyDB SET OFFLINE

  3. 到新路径
    ALTER DATABASE MyDB MODIFY FILE(Name = MyDB,Filename ='N:\ DATA \ MyDB.MDF')

  4. 将数据库
    设置为在线状态ALTER DATABASE MyDB SET ONLINE

  5. 设置多用户
    ALTER DATABASE MyDB SET MULTI_USER


3

有一种方法可以移动数据库数据文件(尚不确定是否可以对日志文件执行此操作),而无需使数据库脱机。

Dejan Nakarada-Kordic在此提供了此方法的解释+脚本:https//www.itprotoday.com/sql-server/move-database-files-without-taking-database-offline

简短的版本是在新位置添加另一个数据库文件,然后使用DBCC Shrinkfile(带有选项EMPTYFILE)将数据从旧文件移动到新文件。完成后,您可以删除旧的数据文件。

不是我的解决方案,而是我自己在寻找该解决方案,并发现它对我们的生产环境非常有用。

索芬


1

遵循以下简单的4个步骤:

  1. 打开SSMS,然后从窗口顶部选择“ 新建查询”选项。然后复制并执行以下查询以查找要移动到新路径的数据库的查找路径,并注意您在CurrentLocation列中显示的路径。

SELECT name, physical_name AS CurrentLocation FROM sys.master_files WHERE database_id = DB_ID('DATABASE_NAME');

  1. 现在转到该路径,并记下Database_Name.mdfDatabase_Name_log.ldf文件的名称。然后执行以下两个查询以将数据库移动到特定位置。

ALTER DATABASE DATABASE_NAME MODIFY FILE ( NAME = DATABASE_FILE_NAME , FILENAME = 'NEW_PATH\DATABASE_NAME.mdf');

ALTER DATABASE DATABASE_NAME MODIFY FILE ( NAME = DATABASE_FILE_NAME_log , FILENAME = 'NEW_PATH\DATABASE_FILE_NAME_log.ldf');

  1. 现在,通过右键单击停止服务器Server_Name,您可以在“对象资源管理器”(左侧)中看到该服务器。

    在此处输入图片说明

  2. 然后两个文件从旧路径移动新路径,然后再次通过右键单击Server_Name来启动服务器。通过再次执行第一步查询来确认数据库的新路径。


0

我不确定这是否是最好的方法(我欢迎任何评论告诉我它不是这样),但是它非常简单(如果您的数据库很小,则很快):

首先,将数据库备份到.bak文件。然后,从相同的.bak文件还原数据库,在还原任务的文件选项下选择新的.mdf和.ldf文件位置。

我不会在维护窗口的生产环境中这样做,因为在还原过程中您无法访问数据库。我上面看到的其他方法也有类似的缺点。恢复任务完成后,您不必删除旧文件。它是自动完成的。


1
这种情况有一些缺点。还原时,原始数据库必须被覆盖或重命名。对于大型数据库,该方法会带来严重的IO开销。移动文件中描述的分离,附加修改数据库的方法是方式更快。如果文件在同一NTFS分区中移动,则仅是元数据操作。
vonPryz '16

@Ali-备份和还原。可能需要更长的时间,但通常是更安全的途径。请参阅Aaron Bertrand的分析,网址为:blogs.sqlsentry.com/aaronbertrand/bad-habits-file-backups 也:sqlmag.com/blog/should-i-be-using-san-snapshots-backup-solution
RLF

对于非常大的数据库,此方法(以及分离/附加方法)会导致大量的停机时间。为避免这种情况,请将源数据库置于完全恢复模式,然后在目标数据库保持不可操作状态的情况下执行初始备份还原。然后备份/还原一个或多个事务日志。仅在事务日志的最终备份/还原过程中才需要关闭数据库,这可以包含任意小的时间和大小。显然,您还需要还原为其他名称,然后执行名称交换。此方法大致等效于日志装运。
布赖恩

0

要补充现有的答案:这是一个ALTER DATABASE ... MOVE ...为所有数据库创建语句的脚本:

SELECT 'ALTER DATABASE ' + QUOTENAME(d.name) + 
       ' MODIFY FILE (name=' + QUOTENAME(f.name, '''') +
       ', filename=' + QUOTENAME(REPLACE(f.physical_name, 'C:\', 'D:\'), '''') +
       ');'
  FROM sys.master_files AS f 
       INNER JOIN sys.databases AS d ON f.database_id = d.database_id
 WHERE d.name <> 'master';

注意:

  • 替换REPLACE(f.physical_name, 'C:\', 'D:\')为要对文件路径进行的任何转换。

  • master是免税的,因为其路径由SQL Server的启动选项确定(有关详细信息,请参阅此答案)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.