Como posso encontrar o diretório de dados para uma instância do SQL Server?
-
19-09-2019 - |
Pergunta
Temos alguns enorme bancos de dados (20GB +) que contêm principalmente dados de pesquisa estáticos. Porque os nossos executa aplicativos junta-se contra tabelas nesses bancos de dados, eles têm que ser parte de cada desenvolvedores de SQL Server local (ou seja, eles não podem ser hospedados em um servidor de banco de dados central, compartilhada).
Estamos pensando em copiar um conjunto canônico dos arquivos de banco de dados SQL Server reais (* .mdf e * .ldf) e anexá-las ao banco de dados local de cada desenvolvedor.
Qual é a melhor maneira de descobrir o diretório de dados do instância local do SQL Server para que possamos copiar os arquivos para o lugar certo? Isto será feito através de um processo automatizado, então eu tenho que ser capaz de encontrar e usá-lo a partir de um script de construção.
Solução
Depende se caminho padrão está definido para dados e arquivos de log ou não.
Se o caminho está definido explicitamente na Properties
=> Database Settings
=> Database default locations
então servidor armazena SQL TI em Software\Microsoft\MSSQLServer\MSSQLServer
em valores DefaultData
e DefaultLog
.
No entanto, se esses parâmetros não são definidas explicitamente, servidor SQL utiliza caminhos de dados e de log do banco de dados mestre.
Abaixo está o script que cobre ambos os casos. Esta é simplificada versão da consulta que SQL Management Studio é executado.
Além disso, observe que eu uso xp_instance_regread
vez de xp_regread
, então este script irá trabalhar para qualquer instância, padrão ou nomeado.
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
Você pode conseguir o mesmo resultado usando SMO. Bellow é C amostra #, mas você pode usar qualquer outra linguagem .NET ou 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;
}
É muito mais simples no SQL Server 2012 e acima, supondo que você tenha caminhos padrão definido (o que provavelmente é sempre uma coisa certa a fazer):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
Outras dicas
Mesmo que este é um fio muito velho, eu sinto que eu preciso para contribuir com uma solução simples. Qualquer hora que você sabe onde no Management Studio um parâmetro está localizado que você deseja acessar para qualquer tipo de script automatizado, a maneira mais fácil é executar um rastreio profiler rápido em um sistema de teste autônomo e captura o Management Studio está fazendo no backend .
Neste exemplo, supondo que você está interessado em encontrar os dados padrão e os locais de log que você pode fazer o seguinte:
SELECIONAR
SERVERPROPERTY ( 'instancedefaultdatapath') AS [DefaultFile],
SERVERPROPERTY ( 'instancedefaultlogpath') AS [DefaultLog]
me deparei com esta solução na documentação para a instrução Criar banco de dados na ajuda para o 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
Para o banco de dados atual você pode apenas usar:
para especificar outro banco de dados, por exemplo, 'Model', de uso sys.master_files
select physical_name from sys.master_files where database_id = DB_ID(N'Model');
A partir do SQL Server 2012, você pode usar a seguinte consulta:
SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];
(Isto foi tomado de um comentário em http://technet.microsoft.com/en-us /library/ms174396.aspx , e testado.)
Vários componentes do SQL Server (Data, Logs, SSAS, SSIS, etc) tem um diretório padrão. A configuração para isso pode ser encontrado no Registro. Leia mais aqui:
http://technet.microsoft.com/ en-us / library / ms143547% 28SQL.90% 29.aspx
Então, se você criou um banco de dados usando apenas CREATE DATABASE MyDatabaseName
seria criado no caminho especificado em uma das configurações acima.
Agora, se o administrador / instalador mudou o caminho padrão, em seguida, o caminho padrão para a instância é armazenada no registro em
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup
Se você sabe o nome da instância, em seguida, você pode consultar o registro. Este exemplo é SQL específica de 2008 -. Deixe-me saber se você precisa do caminho SQL2005 bem
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',
@value=@regvalue OUTPUT,
@output = 'no_output'
SELECT @regvalue as DataAndLogFilePath
Cada banco de dados pode ser criado sobrepondo a configuração do servidor em um local próprio que é quando você emitir a declaração CREATE DATABASE DBName
com os parâmetros apropriados. Você pode descobrir isso por executar sp_helpdb
exec sp_helpdb 'DBName'
Mantê-lo simples:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
este retornará todos os bancos de dados com arquivos associados
A partir da GUI:. Aberta suas propriedades do servidor, vá para o Configurações de banco de dados , e veja locais padrão de banco de dados
Note que você pode soltar os arquivos de banco de dados onde quer que você gosta, embora pareça mais limpo para mantê-los no diretório padrão.
Você pode encontrar dados e de log locais padrão para a instância atual do SQL Server usando o seguinte 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'
pequeno procurar defeitos:. Não há nenhuma pasta de dados, apenas uma padrão pasta de dados
De qualquer forma, para encontrá-lo, supondo que você deseja instalar pela primeira instância padrão:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL.1 \ Setup \ SQLDataRoot
Se houver uma instância nomeada, MSSQL.1 torna-se algo como MSSQL10.INSTANCENAME.
resposta Expansão em "pedaços salpicado", aqui está um script completo que faz isso:
@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
i teria feito uma cópia de segurança restaurar simplesmente becuase é mais fácil e suporte de versões. Dados de referência precisa especialmente para ser versionadas, a fim de saber quando ele começou a fazer efeito. A destacá anexar não vai dar-lhe essa capacidade. Também com backups você pode continuar a fornecer cópias atualizadas sem ter que desligar o banco de dados.
Alex resposta é o caminho certo, mas para a posteridade aqui está uma outra opção: criar um novo banco de dados vazio. Se você usar CREATE DATABASE sem especificar um dir-alvo que você começa ... os dados padrão / diretórios de log. Fácil.
Pessoalmente no entanto eu provavelmente quer:
- restaurar o banco de dados para PC do desenvolvedor, em vez de copiar / attach (backups podem ser comprimidos, exposta em um UNC), ou
- Use um servidor vinculado para evitar fazer isso em primeiro lugar (depende a quantidade de dados vai até a junção)
ps:. 20gb não é enorme, mesmo em 2015. Mas é tudo relativo
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\%'
Você pode baixar script SQL detalhe como encontrar o diretório de dados para uma instância do SQL Server
Você vai obter a localização padrão se do banco de dados do usuário por esta consulta:
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'