Как найти каталог данных для экземпляра SQL Server?
У нас есть несколько огромных баз данных (20 ГБ +), которые в основном содержат данные статического поиска. Поскольку наше приложение выполняет объединения с таблицами в этих базах данных, они должны быть частью каждого локального SQL-сервера разработчиков (т.е. Они не могут размещаться на центральном общем сервере базы данных).
Мы планируем скопировать канонический набор фактических файлов базы данных SQL Server (*.mdf и *.ldf) и прикрепить их к каждой локальной базе разработчиков.
Какой лучший способ узнать локальный каталог данных экземпляра SQL Server, чтобы мы могли скопировать файлы в нужное место? Это будет сделано с помощью автоматизированного процесса, поэтому я должен найти и использовать его из сборки script.
Ответы
Ответ 1
Это зависит от того, установлен ли путь по умолчанию для файлов данных и журналов или нет.
Если путь задан явно в Properties
= > Database Settings
= > Database default locations
, тогда SQL-сервер сохраняет его в Software\Microsoft\MSSQLServer\MSSQLServer
в DefaultData
и DefaultLog
значениях.
Однако, если эти параметры не заданы явно, SQL-сервер использует пути данных и журнала основной базы данных.
Ниже представлен список script, который охватывает оба случая. Это упрощенная версия запроса, выполняемого SQL Management Studio.
Также обратите внимание, что я использую xp_instance_regread
вместо xp_regread
, поэтому этот script будет работать для любого экземпляра, по умолчанию или имени.
declare @DefaultData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultData', @DefaultData output
declare @DefaultLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', @DefaultLog output
declare @DefaultBackup nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'BackupDirectory', @DefaultBackup output
declare @MasterData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg0', @MasterData output
select @MasterData=substring(@MasterData, 3, 255)
select @MasterData=substring(@MasterData, 1, len(@MasterData) - charindex('\', reverse(@MasterData)))
declare @MasterLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg2', @MasterLog output
select @MasterLog=substring(@MasterLog, 3, 255)
select @MasterLog=substring(@MasterLog, 1, len(@MasterLog) - charindex('\', reverse(@MasterLog)))
select
isnull(@DefaultData, @MasterData) DefaultData,
isnull(@DefaultLog, @MasterLog) DefaultLog,
isnull(@DefaultBackup, @MasterLog) DefaultBackup
Вы можете добиться того же результата, используя SMO. Bellow - образец С#, но вы можете использовать любой другой язык .NET или PowerShell.
using (var connection = new SqlConnection("Data Source=.;Integrated Security=SSPI"))
{
var serverConnection = new ServerConnection(connection);
var server = new Server(serverConnection);
var defaultDataPath = string.IsNullOrEmpty(server.Settings.DefaultFile) ? server.MasterDBPath : server.Settings.DefaultFile;
var defaultLogPath = string.IsNullOrEmpty(server.Settings.DefaultLog) ? server.MasterDBLogPath : server.Settings.DefaultLog;
}
Это намного проще в SQL Server 2012 и выше, если у вас установлены установленные по умолчанию пути (что, вероятно, всегда правильно):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
Ответ 2
Я наткнулся на это решение в документации для оператора Create Database в справке для SQL Server:
SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id = 1 AND file_id = 1
Ответ 3
Несмотря на то, что это очень старый поток, я чувствую, что мне нужно внести простое решение.
В любое время, когда вы знаете, где в Management Studio находится параметр, который вы хотите получить для любого вида автоматизированного script, самый простой способ - запустить быструю трассировку профилировщика на автономной тестовой системе и зафиксировать, что делает Management Studio бэкэнд.
В этом случае, если вы заинтересованы в поиске данных по умолчанию и мест регистрации, вы можете сделать следующее:
SELECT
SERVERPROPERTY ('instancedefaultdatapath') AS [DefaultFile],
SERVERPROPERTY ('instancedefaultlogpath') AS [DefaultLog]
Ответ 4
Для текущей базы данных вы можете просто использовать:
select physical_name from
sys.database_files;
чтобы указать другую базу данных, например. "Модель", используйте sys.master_files
select physical_name from sys.master_files where database_id = DB_ID(N'Model');
Ответ 5
Начиная с Sql Server 2012, вы можете использовать следующий запрос:
SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];
(Это было взято из комментария на http://technet.microsoft.com/en-us/library/ms174396.aspx и протестировано.)
Ответ 6
Различные компоненты SQL Server (данные, журналы, SSAS, SSIS и т.д.) имеют каталог по умолчанию. Этот параметр можно найти в реестре. Подробнее здесь:
http://technet.microsoft.com/en-us/library/ms143547%28SQL.90%29.aspx
Итак, если вы создали базу данных, используя только CREATE DATABASE MyDatabaseName
, она будет создана по пути, указанному в одном из приведенных выше параметров.
Теперь, если администратор/установщик изменил путь по умолчанию, то путь по умолчанию для экземпляра хранится в реестре в
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup
Если вы знаете имя экземпляра, вы можете запросить реестр. Этот пример специфичен для SQL 2008 - сообщите мне, нужен ли вам также путь SQL2005.
DECLARE @regvalue varchar(100)
EXEC master.dbo.xp_regread @rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLServer\Setup',
@value_name='SQLDataRoot',
@[email protected] OUTPUT,
@output = 'no_output'
SELECT @regvalue as DataAndLogFilePath
Каждая база данных может быть создана, переопределяя настройку сервера в ее собственном местоположении, когда вы выдаете оператор CREATE DATABASE DBName
с соответствующими параметрами. Вы можете найти это, выполнив sp_helpdb
exec sp_helpdb 'DBName'
Ответ 7
Сохранение простоты:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
это приведет к возврату всех баз данных со связанными файлами
Ответ 8
В графическом интерфейсе: откройте свойства своего сервера, перейдите в раздел "Параметры базы данных" и выберите "Расположение базы данных по умолчанию".
Обратите внимание, что вы можете отбрасывать файлы базы данных везде, где захотите, хотя кажется, что их чище держать в каталоге по умолчанию.
Ответ 9
Вы можете найти местоположения данных и журнала по умолчанию для текущего экземпляра SQL Server, используя следующий T-SQL:
DECLARE @defaultDataLocation nvarchar(4000)
DECLARE @defaultLogLocation nvarchar(4000)
EXEC master.dbo.xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'DefaultData',
@defaultDataLocation OUTPUT
EXEC master.dbo.xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'DefaultLog',
@defaultLogLocation OUTPUT
SELECT @defaultDataLocation AS 'Default Data Location',
@defaultLogLocation AS 'Default Log Location'
Ответ 10
Маленькая nitpick: папка с данными отсутствует, только папка данных по умолчанию.
В любом случае, чтобы найти его, если вы хотите установить для первого экземпляра по умолчанию:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\Setup\SQLDataRoot
Если есть именованный экземпляр, MSSQL.1 становится чем-то вроде MSSQL10.INSTANCENAME.
Ответ 11
Развернувшись на ответ "splattered bits", вот полный script, который делает это:
@ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION
SET _baseDirQuery=SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1) ^
FROM master.sys.master_files WHERE database_id = 1 AND file_id = 1;
ECHO.
SQLCMD.EXE -b -E -S localhost -d master -Q "%_baseDirQuery%" -W >data_dir.tmp
IF ERRORLEVEL 1 ECHO Error with automatically determining SQL data directory by querying your server&ECHO using Windows authentication.
CALL :getBaseDir data_dir.tmp _baseDir
IF "%_baseDir:~-1%"=="\" SET "_baseDir=%_baseDir:~0,-1%"
DEL /Q data_dir.tmp
echo DataDir: %_baseDir%
GOTO :END
::---------------------------------------------
:: Functions
::---------------------------------------------
:simplePrompt 1-question 2-Return-var 3-default-Val
SET input=%~3
IF "%~3" NEQ "" (
:askAgain
SET /p "input=%~1 [%~3]:"
IF "!input!" EQU "" (
GOTO :askAgain
)
) else (
SET /p "input=%~1 [null]: "
)
SET "%~2=%input%"
EXIT /B 0
:getBaseDir fileName var
FOR /F "tokens=*" %%i IN (%~1) DO (
SET "_line=%%i"
IF "!_line:~0,2!" == "c:" (
SET "_baseDir=!_line!"
EXIT /B 0
)
)
EXIT /B 1
:END
PAUSE
Ответ 12
я бы сделал резервное восстановление просто потому, что его проще и поддерживать управление версиями. Справочные данные особенно нуждаются в версиях, чтобы знать, когда они начали действовать. Прикрепление dettach не даст вам эту способность. Также с резервными копиями вы можете продолжать предоставлять обновленные копии без необходимости закрытия базы данных.
Ответ 13
Ответ от Alex является правильным, но для потомков здесь другой вариант: создать новую пустую базу данных. Если вы используете CREATE DATABASE без указания целевого каталога, вы получаете... каталоги данных по умолчанию/журналы. Легко.
Лично, однако, я бы тоже:
- ВОССТАНОВИТЬ базу данных на ПК разработчика, а не копировать/прикреплять (резервные копии могут быть сжаты, выставлены на UNC) или
- Использовать связанный сервер, чтобы избежать этого в первую очередь (зависит от того, сколько данных проходит через соединение)
ps: 20gb не огромен, даже в 2015 году. Но все это относительное.
Ответ 14
SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceDataPaths
FROM sys.sysaltfiles WHERE filename like '%.mdf' and filename not like '%\MSSQL\Binn\%'
SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceLogPaths
FROM sys.sysaltfiles WHERE filename like '%.ldf' and filename not like '%\MSSQL\Binn\%'
![введите описание изображения здесь]()
Вы можете загрузить подробный SQL script из как найти каталог данных для экземпляра SQL Server
Ответ 15
Вы получите местоположение по умолчанию, если пользовательская база данных по этому запросу:
declare @DataFileName nVarchar(500)
declare @LogFileName nVarchar(500)
set @DataFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 1)+'.mdf'
set @LogFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 2)+'.ldf'
select
( SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(@DataFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 1) as 'Data File'
,
(SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(@LogFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 2) as 'Log File'