sqlserver dba日常操作

2023-12-18

查询慢sql的方法

1.whoisactive

安装方法

http://whoisactive.com/downloads/下载地址
将下载好的zip包放到sqlserver服务器中
文件-打开-文件-下载好的zip包-在查询窗口点击执行
新建一个查询窗口,输入sp_whoisactive,获取当前运行的所有sql语句
使用方法

输入sp_whoisactive,获取当前运行的所有sql语句
查看当前所有的sql中,观察运行时间,较长时间的,影响到其他业务的,或者影响这个服务器性能,导致其他的sql堆积的sql,就给停止掉
停止方法

whoisactive查看的sql中,可以看到session_id,记录下慢sql的sessionId
使用命令 kill session_id 的方式将慢sql的进行杀掉
2.自己编写的脚本

脚本命令 当数据库出现性能问题时,这个脚本能够直观的看到数据库中SQL 的运行状态,快速找到执行缓慢的语句。这是我使用最频繁的脚本之一.

SELECT
    es.session_id,
    database_name=DB_NAME(er.database_id),
    er.cpu_time,
    er.reads,
    er.writes,
    er.logical_reads,
    login_name,
    er.status,
    blocking_session_id,
    wait_type,
    wait_resource,
    wait_time,
    individual_query=SUBSTRING(qt.text,(er.statement_start_offset/2)+1,((CASE  WHEN  er.statement_end_offset=-1 THEN  LEN(CONVERT(NVARCHAR(MAX),qt.text))* 2 ELSE   er.statement_end_offset  END-er.statement_start_offset)/2)+1),
    parent_query=qt.text,
    program_name,
    host_name,
    nt_domain,
    start_time,
    DATEDIFF(MS,er.start_time,GETDATE())as duration,
    (SELECT  query_plan  FROM  sys.dm_exec_query_plan (er.plan_handle))AS  query_plan
FROM
    sys.dm_exec_requests er
    INNER  JOIN  sys.dm_exec_sessions  es  ON er.session_id=es.session_id
    CROSS  APPLY  sys.dm_exec_sql_text (er.sql_handle)AS  qt
WHERE
    es.session_id> 50         
    AND  es.session_Id  NOT  IN(@@SPID)
ORDER BY
    1, 2

重要信息

logical_reads:逻辑读,衡量语句的执行开销。如果大于10w,说明此语句开销很大。可以检查下索引是否合理

status:进程的状态。running 表示正在运行,sleeping 表示处于睡眠中,未运行任何语句,suspend 表示等待,runnable 等待cpu 调度

blocking_session_id: 如果不为0,例如 60 。表示52号进程正在被60阻塞。50 进程必须等待60执行完成,才能执行下面的语句

host_name :发出请求的服务器名

program_name:发出请求的应用程序名

duration: 请求的执行时间

3、sqlserver profile

打开sqlserver profiler

常规选项中,勾选保存到表,自己设置一个表

设置容量大小,最大行数。单位是:千行。大概设置10w条,就设置值为100

事件选择-勾选显示所有事件

Security Audit选项中,反勾选Login,Logout

session中,反勾选退出连接(existingConnection)

stored procedures(存储过程) 勾选RPC completed 和 SP stmtCompleted

TSQL 勾选 SQL:Batchcompleted和SQL:stmtcomple

选择列筛选器-》duration-》大于等于3000(此处单位为毫秒)意思是筛选执行3秒以上的sql记录

点击运行,就可以看到记录的慢sql了。

sqlserver备份

全备

全备代码: 记得修改相关路径
 
USE [master]
GO
 
/****** Object:  StoredProcedure [dbo].[sp_full_BackupDB]    Script Date: 2020/2/12 18:55:20 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
 
CREATE procedure [dbo].[sp_full_BackupDB](@DBName varchar(50))
as
begin
  declare @sCommandText varchar(255)
  declare @startTime    varchar(255)
  declare @endTime      varchar(255)
  declare @tmp_file_name  varchar(255)
  declare @tmp_file_name_2  varchar(255)
  declare @base_dir       varchar(255)
  declare @base_dir_2       varchar(255)
  declare @now_day        varchar(255)
  declare @rarcmd        varchar(255)  
  declare @rarfile       varchar(255)  
  declare @tmp_prefix       varchar(255)  
  
  set @tmp_prefix = 'test_back'
  
  set @startTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 开始备份  完全备份: ' +  @DBName + '  ' +   @startTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
  ---- 正式备份
   -- 类似 2018-01-02-1407  是 年-月-日-时分  用于日志备份
   -- set @now_day = substring( replace(replace(replace(CONVERT(varchar,   getdate()   , 120 ),'-','-'),' ','-'),':','') , 1, 15)
   
   -- 类似 2018-01-02   是 年月日时分   用于完整、差异备份
   set @now_day =  replace(CONVERT(varchar,  getdate()   , 111 ),'/','-') 
   
   set  @base_dir = 'D:\bak_db\quanbei_db\'
   
   
   -- 全备 master,压缩备份, 生成类似  TongCheng_B2B_DB_TC_master_full_2018-05-28.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName + '_master_full_' + @now_day + '.bak'
   BACKUP DATABASE [master] TO  DISK = @tmp_file_name  with STATS = 1,compression
   
   -- 全备 model,压缩备份,  生成类似  TongCheng_B2B_DB_TC_model_full_2018-05-28.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName +  '_model_full_' + @now_day + '.bak'
   BACKUP DATABASE [model] TO  DISK = @tmp_file_name  with STATS = 1,compression
   
   -- 全备 msdb,压缩备份,   生成类似  TongCheng_B2B_DB_TC_msdb_full_2018-05-28.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName +  '_msdb_full_' + @now_day + '.bak'
   BACKUP DATABASE [msdb] TO  DISK = @tmp_file_name  with STATS = 1,compression
   
   
   -- 全备 该用户数据库     生成类似  TongCheng_B2B_DB_TC_full_2018-05-28.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName +  '_full_' + @now_day + '.bak'
   
   BACKUP DATABASE @DBName  TO  DISK = @tmp_file_name  with STATS = 1,compression  
   
   
   -- 停止1分钟
   waitfor delay '00:01:00'
  
  ----- 结束备份
  
  set  @endTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 结束备份  完全备份:  ' +  @DBName + '  ' +   @endTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
  
  set  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
end
GO
创建过存储过程之后,执行全备命令
exec [sp_full_BackupDB]  库名
等待执行完毕即可

差异备

差异备代码:记得修改相关路径和名字
 
USE [master]
GO
 
/****** Object:  StoredProcedure [dbo].[sp_differential_BackupDB]    Script Date: 2020/2/12 18:57:43 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
 
CREATE procedure [dbo].[sp_differential_BackupDB](@DBName varchar(50))
as
begin
  declare @sCommandText varchar(255)
  declare @startTime    varchar(255)
  declare @endTime      varchar(255)
  declare @tmp_file_name  varchar(255)
  declare @tmp_file_name_2  varchar(255)
  declare @tmp_file_name_3  varchar(255)
  declare @base_dir       varchar(255)
  declare @base_dir_2       varchar(255)
  declare @base_dir_3       varchar(255)
  declare @now_day        varchar(255)
  declare @rarcmd        varchar(255)  
  declare @rarfile       varchar(255) 
  declare @tmp_prefix       varchar(255)  
  
  set @tmp_prefix = 'test_differential_back'
  set @startTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 开始备份: 差异备份  ' +  @DBName + '  ' +   @startTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
  ---- 正式备份
   -- 类似 2018-01-02   是 年月日时分   用于完整、差异备份
   set @now_day =  replace(CONVERT(varchar,  getdate()   , 111 ),'/','-') 
 
   
   set  @base_dir = 'D:\bak_db\differential_db\'
  
   
   -- 差异备份 该用户数据库     生成类似  TongCheng_B2B_DB_TC_differential_2018-05-28.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName +  '_differential_' + @now_day + '.bak'
   
   BACKUP DATABASE @DBName  TO  DISK = @tmp_file_name  
     with differential , STATS = 1,compression   
  
  
  -- 停止1分钟
   waitfor delay '00:01:00'
   
   
  ----- 结束备份
  
  set  @endTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 结束备份: 差异备份  ' +  @DBName + '  ' +   @endTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
  set  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
  
end
GO
差异备执行方式:
exec [sp_differential_BackupDB]  库名
等待执行完毕即可

日志备

日志备代码:记得修改相关路径
 
 
USE [master]
GO
 
/****** Object:  StoredProcedure [dbo].[sp_tlog_BackupDB]    Script Date: 2020/2/12 18:58:56 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
 
CREATE procedure [dbo].[sp_tlog_BackupDB](@DBName varchar(50))
as
begin
  declare @sCommandText varchar(255)
  declare @startTime    varchar(255)
  declare @endTime      varchar(255)
  declare @tmp_file_name  varchar(255)
  declare @base_dir       varchar(255)
  declare @tlog_time        varchar(255)
  declare @tmp_prefix       varchar(255)  
  
  set @tmp_prefix = 'test_log_back'
  set @startTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 开始备份: 日志备份  '  + @DBName + '  ' +   @startTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
  ---- 正式备份
   -- 类似 2017-12-21-1000  
    set @tlog_time = substring( replace(replace(replace(CONVERT(varchar,   getdate()   , 120 ),'-','-'),' ','-'),':','') , 1, 15)
   
   set  @base_dir = 'D:\bak_db\tlog_db\'
   
   
   -- 日志备份 该用户数据库     生成类似  account_tlog_2017-12-20-1000.bak
   set  @tmp_file_name = @base_dir + @tmp_prefix + @DBName +  '_tlog_' + @tlog_time + '.bak'
   BACKUP  log  @DBName  TO  DISK = @tmp_file_name   with   STATS = 1,compression
  
  ----- 结束备份
  
  set  @endTime = convert(varchar,GETDATE( ) , 120)
  set  @sCommandText = 'echo 结束备份: 日志备份  ' +  @DBName + '  ' +   @endTime + ' >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
   
  set  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'
  exec xp_cmdshell  @sCommandText
  
end
GO
执行代码:
exec [sp_tlog_BackupDB]  库名
等待执行完毕即可

ldf备份

进行尾日志还原的时候,mdf不可用,ldf可用的情况下,需要将ldf备份,然后进行还原。(前提是做过全备等备份,然后进行还原)
 
尾日志备份代码: 修改相关路径和库名即可
 
BACKUP LOG 库名 TO DISK=N'D:\bak_db\tlog_db2\tail_log.bak' WITH INIT,NO_TRUNCATE;
 
等待执行完毕即可

事务备份

如果误操作进行节点还原,需要有事务备份,然后进行节点还原。此操作需要一些前置条件支持
 
前置条件:
1、数据库右键属性,在选项中查看数据恢复模式为“完整”
2、在数据误操作之前进行过完整数据备份
 
备份方法:
1、命令行操作方式:
BACKUP LOG [test] TO  DISK = N'D:\bak_db\testback.trn' WITH NOFORMAT, NOINIT,  NAME = N'test-完整 数据库 备份', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
 
2、图形化操作:
a/选择要恢复的数据库,右键-“任务”-“备份”
b/在弹出的备份对话框中备份类型选择“事务日志”,并添加备份文件“log.trn”------->备份类型:事务日志,目标:磁盘,删除原有的路径,添加到自定义的路径。
c/点击确定完成事务日志备份

注意事项

1、sqlserver profile的记录慢sql时间单位问题: 在数据表中记录的微妙。但是设置的那个地方填写的是毫秒

2、数据库属性中,恢复模式问题 一定要选择完整,才能进行全备,和事务备份等。

3、做全备、差异备的时候,一定要停掉所有的连接,关闭job。否则恢复的时候,就会显示恢复中,这是sqlserver的事务未提交问题

4、重启sqlserver服务器的时候,一定要关闭数据库服务,关闭job等。防止数据库事务未提交完毕就重启,会导致数据库在恢复中。

SQL Server 还原

全备还原

还原代码: 修改相应的路径即可
 
 
USE [master]
RESTORE DATABASE [test] FROM  DISK = N'D:\bak_db\quanbei_db\test_backtest_full_2020-02-12.bak'
 WITH  FILE = 1, NORECOVERY,NOUNLOAD,STATS = 5    --如果此处不是最后一步还原的话,使用NORECOVERY,如果此处是最后一步,就需要使用RECOVERY,否则会出问题
GO
 
等待执行完毕即可完成全备还原

差异备份还原

差异备还原代码:修改相对路径即可
USE [master]
RESTORE DATABASE [test] FROM  DISK = N'D:\bak_db\differential_db\test_differential_backtest_differential_2020-02-12.bak'
 WITH  FILE = 1, NORECOVERY,NOUNLOAD,STATS = 5   --如果此处不是最后一步还原的话,使用NORECOVERY,如果此处是最后一步,就需要使用RECOVERY,否则会出问题
GO
 
等待执行完毕即可完成差异备份还原

日志备/尾日志还原

日志备份,尾日志备份的还原,都用该命令即可。记得修改相对应的路径
 
USE [master]
RESTORE LOG [test] FROM  DISK = N'D:\bak_db\tlog_db2\tail_log.bak'
 WITH  FILE = 1,  RECOVERY,NOUNLOAD,STATS = 5   --如果此处不是最后一步还原的话,使用NORECOVERY,如果此处是最后一步,就需要使用RECOVERY,否则会出问题
GO       ---     如果上面报错,可以尝试将WITH后面的内容都删掉,只保留RECOVERY
 
等待执行完毕即可完成日志备份还原

事务日志还原

1、可视化操作:
a.打开数据库还原页面,检查源数据库及目标数据库是否正确,检查完整备份及日志备份是否完整,并点击“时间线”进入时间线选择
b.在弹出的时间线对话框中选择“特定日期和时间”,并将时间设置为误删之前时间点,如16:20
c.再次检查目标数据库,及备份集信息无误,点击“选项”进入选项卡,勾选“覆盖现有数据库”及“关闭现有连接”复选框,然后确定,直至还原成功
 
2、命令行操作
USE [master]
ALTER DATABASE [test] SET SINGLE_USER WITH ROLLBACK IMMEDIATE   --- 修改数据库为单用户模式
-- 还原前进行尾日志备份
BACKUP LOG [test] TO  DISK = N'D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup\test_LogBackup_2020-02-12_19-24-21.bak'
 WITH NOFORMAT, NOINIT,  NAME = N'test_LogBackup_2020-02-12_19-24-21', NOSKIP, NOREWIND, NOUNLOAD,  NORECOVERY ,  STATS = 5
 -- 还原全备备份
RESTORE DATABASE [test] FROM  DISK = N'D:\bak_db\quanbei_db\test_backtest_full_2020-02-12.bak'
 WITH  FILE = 2,  NORECOVERY,  NOUNLOAD,  REPLACE,  STATS = 5
 -- 还原事务日志备份,并设置还原到的时间节点
RESTORE LOG [test] FROM  DISK = N'D:\bak_db\testback.trn'
 WITH  FILE = 1,  NOUNLOAD,  STATS = 5,  STOPAT = N'2020-02-12T18:30:00'
 
ALTER DATABASE [test] SET MULTI_USER
GO
 
等待还原成功即可

备份还原中的问题

还原失败,需要某些权限

问题描述:

SQL Server 阻止了对组件 ‘xp_cmdshell’ 的 过程’sys.xp_cmdshell’
的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用
‘xp_cmdshell’。有关启用 ‘xp_cmdshell’ 的详细信息,请参阅 SQL Server 联机丛书中的
“外围应用配置器”。

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

重命名sql Server数据库名称失败

问题描述:

消息 5030,级别 16,状态 2,第 1 行无法用排他锁锁定该数据库,以执行该操作。

视图模式解决:

1、在对象资源管理器中,连接到 SQL Server 数据库引擎实例,然后展开该实例。
2、右键单击要更改的数据库,再单击“属性”。
3、在“数据库属性”对话框中,单击“选项”页。
4、在“限制访问”选项中,选择“单用户”。
5、如果其他用户连接到数据库,将出现“打开的连接”消息。若要更改属性并关闭所有其他连接,请单击“是”。
6、重命名完了,再限制访问的属性改回原来的就可以啦

命令行模式解决:

--1.执行SQL 
ALTER DATABASE db_database SET SINGLE_USER WITH ROLLBACK IMMEDIATE
--修改为单用户模式
--2.然后关闭所有的查询窗口,重命名你的数据库名称
--3.执行SQL 
ALTER DATABASE db_database SET MULTI_USER
--再修改为多用户模式

作业迁移

单个迁移

在ssms中,打开作业文件夹
 
右键要迁移的作业
 
编写作业脚本为-create到-新的查询窗口
 
将生成的脚本全部赋值下来
 
去目标数据库上面,新建查询窗口执行刚才生成的脚本
 
有可能迁移过后的脚本是禁用状态,
作业文件夹右键-管理计划-根据时间说明将对应的job开启。或者逐个点击开启
 
问题:
1、执行失败:可能原因是源服务器使用的windows账号登陆的,导致无法执行,这个时候需要将登陆账号("@owner_login_name")改为本地的账号
本地登陆名-》ssms中,安全性-登录名下所有启用的账户,此处尽量保证源db的用户和目标db的用户一致。

批量迁移

在ssms中,打开作业文件夹
 
选中作业文件夹,然后按F7,出现对象管理器详细信息界面
 
按着ctrl键,多选要迁移的作业job
 
右键-编写作业脚本为-create到-新的查询窗口
 
将生成的脚本全部复制,到迁移目标数据库上面,新建查询窗口,执行刚才生成的脚本,就可以完成批量迁移
 
有可能迁移过后的脚本是禁用状态,
作业文件夹右键-管理计划-根据时间说明将对应的job开启。或者逐个点击开启
 
问题:
1、执行失败:可能原因是源服务器使用的windows账号登陆的,导致无法执行,这个时候需要将登陆账号("@owner_login_name")改为本地的账号
本地登陆名-》ssms中,安全性-登录名下所有启用的账户,此处尽量保证源db的用户和目标db的用户一致。

登陆账号迁移

批量迁移脚本

---SQL 2005以上版本适用
 
--找到了解决办法.
--1.在A服务器上执行
USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
  DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(256),
    @hexvalue varchar (514) OUTPUT
AS
DECLARE @charvalue varchar (514)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = '0x'
SELECT @i = 1
SELECT @length = DATALENGTH (@binvalue)
SELECT @hexstring = '0123456789ABCDEF'
WHILE (@i <= @length)
BEGIN
  DECLARE @tempint int
  DECLARE @firstint int
  DECLARE @secondint int
  SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
  SELECT @firstint = FLOOR(@tempint/16)
  SELECT @secondint = @tempint - (@firstint*16)
  SELECT @charvalue = @charvalue +
    SUBSTRING(@hexstring, @firstint+1, 1) +
    SUBSTRING(@hexstring, @secondint+1, 1)
  SELECT @i = @i + 1
END
 
SELECT @hexvalue = @charvalue
GO
 
IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
  DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
DECLARE @name sysname
DECLARE @type varchar (1)
DECLARE @hasaccess int
DECLARE @denylogin int
DECLARE @is_disabled int
DECLARE @PWD_varbinary  varbinary (256)
DECLARE @PWD_string  varchar (514)
DECLARE @SID_varbinary varbinary (85)
DECLARE @SID_string varchar (514)
DECLARE @tmpstr  varchar (1024)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)
 
DECLARE @defaultdb sysname
 
IF (@login_name IS NULL)
  DECLARE login_curs CURSOR FOR
 
      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM 
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSE
  DECLARE login_curs CURSOR FOR
 
 
      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM 
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
OPEN login_curs
 
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGIN
  PRINT 'No login(s) found.'
  CLOSE login_curs
  DEALLOCATE login_curs
  RETURN -1
END
SET @tmpstr = '/* sp_help_revlogin script '
PRINT @tmpstr
SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'
PRINT @tmpstr
PRINT ''
WHILE (@@fetch_status <> -1)
BEGIN
  IF (@@fetch_status <> -2)
  BEGIN
    PRINT ''
    SET @tmpstr = '-- Login: ' + @name
    PRINT @tmpstr
    IF (@type IN ( 'G', 'U'))
    BEGIN -- NT authenticated account/group
 
      SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
    END
    ELSE BEGIN -- SQL Server authentication
        -- obtain password and sid
            SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )
        EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
        EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT
 
        -- obtain password policy state
        SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
        SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
 
            SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'
 
        IF ( @is_policy_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked
        END
        IF ( @is_expiration_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked
        END
    END
    IF (@denylogin = 1)
    BEGIN -- login is denied access
      SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )
    END
    ELSE IF (@hasaccess = 0)
    BEGIN -- login exists but does not have access
      SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )
    END
    IF (@is_disabled = 1)
    BEGIN -- login is disabled
      SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'
    END
    PRINT @tmpstr
  END
 
  FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
   END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
GO

批量迁移执行方法

exec master..sp_help_revlogin
 
执行上面的语句,可以生成创建账号登录名的脚本命令

注意,一般情况下,就迁移自己创建的即可,其他的上面登录名可以不用迁移。NT开头的,和windows登陆的两种,可以忽略,这个这次执行命令,可以看到只有一个自建登录名,test_login。
这个脚本无法生成sa,需要自己创建修改密码等

总结
使用这个办法有2个好处。

1。可以批量同步所有需要的登录账号
2.由于产生的SID是相同的,不会有孤立账号的问题。在ALWAY ON环境下,我们就需要采用这种方式。不然没有ALWAYS ON 切换后都需要手动处理 孤立账号的

批量迁移连接服务器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后把生成的脚本,COPY到新的服务器上面执行就可以了。在建立完成后一定要测试链接服务器是不是可用
在这里插入图片描述
总结

批量迁移链接服务器的方法和批量迁移定时作业的方法机会是一样的。

记录数据库的DDL

使用脚本记录下函数,存储过程,触发器,表结构的修改

-- Table to store the data
CREATE TABLE DDLLog(
	id INT NOT NULL IDENTITY(1,1),
	event_type sysname,
	object_id int,
	object_name sysname,
	change_date datetime,
	changed_by sysname
	);
GO
 
 
CREATE TRIGGER tr_DDLLog
ON DATABASE
FOR DDL_PROCEDURE_EVENTS,
    DDL_FUNCTION_EVENTS,
    DDL_VIEW_EVENTS,
    DDL_TRIGGER_EVENTS,
    DDL_TABLE_EVENTS
AS
BEGIN
	INSERT INTO DDLLog(event_type, object_id, object_name, change_date, changed_by)
		VALUES (EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]',  'NVARCHAR(255)'),
				EVENTDATA().value('(/EVENT_INSTANCE/ObjectId)[1]',  'INT'),
				EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]',  'NVARCHAR(255)'),
				getdate(),
				ORIGINAL_LOGIN()
				);
END

测试

--创建存储过程
CREATE PROCEDURE ChangeTest AS
	PRINT '1';
GO
--修改存储过程
ALTER PROCEDURE ChangeTest AS
	PRINT '1';
GO
--删除存储过程
DROP PROCEDURE ChangeTest;
GO

结果

在这里插入图片描述
总结

当下次发生问题时,可以自己心中有数。

数据库重命名

问题描述:

在数据库重命名的时候,平时最经常使用的就是sp_renamedb
,或者是在SSMS工具中右键进行重命名。这样操作简单,快捷。但是有一个问题就是对应的mdf,ldf文件名字不会跟着改变.而且数据库的逻辑文件名也不会跟着改变。

最佳实践
修改数据库的逻辑文件名字

ALTER DATABASE Mydb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
 
ALTER DATABASE [Mydb] MODIFY FILE (NAME=N'Mydb', NEWNAME=N'MydbNew')
GO
ALTER DATABASE [Mydb] MODIFY FILE (NAME=N'Mydb_log', NEWNAME=N'MydbNewlog')
GO

修改物理文件名字

分离数据库

USE [master]
GO
EXEC master.dbo.sp_detach_db @dbname = N'Mydb'
GO

修改物理文件名字
找到db对应的ldf和mdf的路径,进行重命名

附加数据库

USE [master]
GO
CREATE DATABASE MydbNew ON 
( FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\MydbNew.mdf' ),
( FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\MydbNew_log.ldf' )
    FOR ATTACH
GO

设置为多用户

ALTER DATABASE MydbNew SET MULTI_USER

检查

--查看数据库的文件名:  修改最后的db名字
SELECT
name AS [Logical Name],
physical_name AS [DB File Path],
type_desc AS [File Type],
state_desc AS [State]
FROM sys.master_files
WHERE database_id = DB_ID(N'MydbNew')

总结

修改数据库名字是一个很常见的操作,直接改名很容易,但是可能会以后留下隐患。

查询所有数据库的大小

with fs
as
(
    select database_id, type, size * 8.0 / 1024 size
    from sys.master_files
)
select 
    name,
    (select   cast(round(sum(size),2)   as   numeric(15,2))  from fs where type = 0 and fs.database_id = db.database_id) DataFileSizeMB,
    (select cast(round(sum(size),2)   as   numeric(15,2))  from fs where type = 1 and fs.database_id = db.database_id) LogFileSizeMB
from sys.databases db
order by 2 desc;

查询当前数据库的大小

EXEC sp_spaceused

数据库显示“正在还原”的处理方法

1)新建查询,复制下面代码,修改数据库名后,执行;

--恢复并且回到可访问状态,要执行
 RESTORE database 数据库名  with recovery

2)点击对象资源管理器->数据库->右键->刷新,
再次展开,就OK了。

数据库发生死锁怎么处理

查看被锁进程号及被锁表名:

SELECT request_session_id spid, --进程号
       OBJECT_NAME(resource_associated_entity_id) tableName  --被锁表名
FROM sys.dm_tran_locks
WHERE resource_type = 'OBJECT'

解锁:

KILL [进程号]

创建杀掉引起死锁进程的存储过程

create proc dbo.p_killspid 
	@dbname varchar(200)    --要关闭进程的数据库名 
as  
    declare @sql  nvarchar(500)  
    declare @spid nvarchar(20)
    declare #tb cursor for 
        select spid=cast(spid as varchar(20)) from master.dbo.sysprocesses where dbid=db_id(@dbname) 
    open #tb 
    fetch next from #tb into @spid 
    while @@fetch_status=0 
    begin  
        exec('kill '+@spid) 
        fetch next from #tb into @spid 
    end  
    close #tb 
    deallocate #tb
go

sqlserver存储过程杀掉数据库中死锁

Create proc p_lockinfo  
    @kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示  
    @show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示  
    as  
     
    declare @count int,@s nvarchar(1000),@i int  
    select id=identity(int,1,1),标志,  
    进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,  
    数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,  
    登陆时间=login_time,打开事务数=open_tran, 进程状态=status,  
    工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,  
    域名=nt_domain,网卡地址=net_address  
    into #t from(  
    select 标志='死锁的进程',  
    spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
    status,hostname,program_name,hostprocess,nt_domain,net_address,  
    s1=a.spid,s2=0
    from master..sysprocesses a join (  
    select blocked from master..sysprocesses group by blocked  
    )b on a.spid=b.blocked where a.blocked=0
    union all  
    select '|_牺牲品_>',  
    spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
    status,hostname,program_name,hostprocess,nt_domain,net_address,  
    s1=blocked,s2=1
    from master..sysprocesses a where blocked<>0  
    )a order by s1,s2  
     
    select @count=@@rowcount,@i=1
     
    if @count=0 and @show_spid_if_nolock=1
    begin  
    insert #t  
    select 标志='正常的进程',  
    spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,  
    open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address  
    from master..sysprocesses  
    set @count=@@rowcount  
    end  
     
    if @count>0  
    begin  
    create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))  
    if @kill_lock_spid=1
    begin  
    declare @spid varchar(10),@标志 varchar(10)  
    while @i<=@count  
    begin  
       select @spid=进程ID,@标志=标志 from #t where id=@i  
       insert #t1 exec('dbcc inputbuffer('+@spid+')')  
       if @标志='死锁的进程' exec('kill '+@spid)  
       set @i=@i+1  
    end  
    end  
    else  
    while @i<=@count  
    begin  
       select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i  
       insert #t1 exec(@s)  
       set @i=@i+1  
    end  
    select a.*,进程的SQL语句=b.EventInfo  
    from #t a join #t1 b on a.id=b.id  
    end

使用

非原创
在mester中创建存储过程
存储过程执行命令
exec master.dbo.p_lockinfo 0,0 ---显示死锁的进程,不显示正常的进程  
exec master.dbo.p_lockinfo 1,0 ---杀死死锁的进程,不显示正常的进程
exec master.dbo.p_lockinfo 0,1 ---显示死锁的进程,显示正常的进程  
exec master.dbo.p_lockinfo 1,1 ---杀死死锁的进程,显示正常的进程
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sqlserver dba日常操作 的相关文章

  • 增量SQL查询

    我的应用程序有一组固定的 SQL 查询 这些查询以轮询模式运行 每 10 秒一次 由于数据库的大小 gt 100 GB 和设计 超级规范化 我遇到了性能问题 每当数据库上发生更改查询结果的 CRUD 事件时 是否可以对给定查询进行增量更改
  • SQL Server 表中最多可以有多少行

    通常我们可以给出更多的值 在SQL Server中一个表最多可以有多少行 之后我们就无法添加新行了 有一些边缘情况 除了明显的磁盘空间问题之外 SQL Server 会阻止您添加更多行 而不是确切的行数 但值得一提 你有一个IDENTITY
  • 别名 .\SQLEXPRESS 为 (LocalDB)\MSSQLLocalDB

    I have SQLEXPRESS已安装 但代码假设我有一个名为 LocalDB MSSQLLocalDB 如何创建别名以便不必安装SQLLocalDb 启动 Sql Server 配置管理器 使用以下参数为 64 位 SQL Native
  • 在 SQL Server 数据库之间传递用户定义的表类型

    我在 SQL Server 的一个数据库中有一个用户定义的表类型 我们称之为DB1 我的类型的定义非常简单 仅包含 2 列 创建我的类型的脚本如下 CREATE TYPE dbo CustomList AS TABLE ID int Dis
  • 如何:使用 SQL Server 2008 创建自动更新修改日期的触发器

    很高兴知道如何创建一个自动更新的触发器modifiedDate我的 SQL Server 表中的列 Table 时间输入 Id PK UserId FK Description Time GenDate ModDate 触发代码 TR Ti
  • 当没有文件可供下载时,如何避免 SSIS FTP 任务失败?

    我正在使用 SQL Server 2005 并在 SSIS 中创建 ftp 任务 有时会有文件需要通过 ftp 传输 有时则不会 如果没有文件 我不希望任务或包失败 我已将从 ftp 任务到下一个任务的箭头更改为 完成 以便包运行 我已将允
  • 如何列出表中的所有列?

    对于各种流行的数据库系统 如何列出表中的所有列 对于 MySQL 请使用 DESCRIBE name of table 只要您使用 SQL Plus 或 Oracle 的 SQL Developer 这也适用于 Oracle
  • 有很多数据库视图可以吗?

    我很少 每月 每季度 使用 Microsoft SQL Server 2005 数据库视图生成数百份 Crystal Reports 报告 在我不读取这些视图的所有时间里 这些视图是否会浪费 CPU 周期和 RAM 因为我很少从视图中读取数
  • 在 ffmpeg 中,如何使用scale2ref 过滤器缩放 dvdsub 字幕以匹配视频大小?

    我有一个从直播电视录制的 mpeg 文件 其中包含视频以及多个音频和字幕流 我的最终目标是能够创建较小的视频文件 因为 mpeg 文件大小为数 GB 我在这条道路上的第一步只是能够选择视频 音频和字幕流中的每一个并将它们复制到 mkv 文件
  • 显示包含特定表的所有数据库名称

    我的 SQL Server 中有很多数据库 我必须只搜索包含特定表名的数据库名称Heartbitmaster 我有很多数据库 例如Gotgold DVD等 我只想从包含此表的查询中查找数据库名称Heartbitmaster 我搜索我尝试查询
  • 将 SQL Server 日期时间转换为较短的日期格式

    我有一个datetimeSQL Server 中的列为我提供了这样的数据10 27 2010 12 57 49 pm我想查询此列 但只需让 SQL Server 返回年月日 例如 2010 10 27或类似的东西 我应该研究哪些功能 我应该
  • T-SQL 中是否有 LIKE 语句的替代方案?

    我有一个场景我需要执行以下操作 SELECT FROM dbo MyTable WHERE Url LIKE
  • 复制数据库的最佳方法是什么?

    当我想要复制数据库时 我总是创建一个新的空数据库 然后将现有数据库的备份恢复到其中 然而 我想知道这是否真的是最不容易出错 最不复杂且最有效的方法 可以跳过创建空数据库的步骤 您可以在恢复过程中创建新数据库 这实际上是我所知道的克隆数据库最
  • 如何在 SQL Server 中创建文件格式

    我正在尝试在 SQL Server 2017 中试验外部文件 但在第一步中遇到了困难 数据是管道分隔的 我试图遵循文档中的语法 这需要一个FILE FORMAT 以下是 Microsoft 的语法 CREATE EXTERNAL TABLE
  • 创建具有动态列数的临时表

    我正在尝试创建一个具有动态列数的临时表 set cmd SELECT into temp3 from select from sometable x pivot max buildrate for name in columns as y
  • 如何使用 django-pyodbc (ubuntu 16.04) 配置数据库设置 Django-MSSQL?

    我是 Django 新手 目前正在尝试使用另一个数据库来保存我的模型 即MS SQL 我的数据库部署在docker容器中 903876e64b67 microsoft mssql server linux bin sh c opt mssq
  • Sql Server 的夏令时

    我们正在使用一个以 C Unix 格式存储日期的旧应用程序 C 时间基本上是自 1970 年 1 月 1 日以来的秒数 日期以整数形式存储在 SQL Server 数据库中 我正在为使用这些日期的报告编写视图 到目前为止 我正在使用以下命令
  • 对于返回超过1个值的SQL select,当Id为GUID时它们如何排序?

    我想知道 SQL Server 如何对查询返回的数据进行排序 并且各个表的 Id 列都是 uniqueidentifier 类型 我在创建所有 GUID 时使用 NHibernate GuidComb 并执行以下操作 Sheet sheet
  • 如何使用 ffmpeg 将两个视频/音频流混合为一个

    我有两个视频 v1 flv 和 v2 flv 想要创建 v3 flv 其中包含来自 v1 flv 的视频流以及来自 v1 flv 和 v2 flv 的 混合 音频流 使用 ffmpeg 命令可以实现类似的操作吗 谢谢 我认为使用 ffmpe
  • RANK() OVER PARTITION 并重置 RANK

    如何获得在分区更改时重新启动的 RANK 我有这张表 ID Date Value 1 2015 01 01 1 2 2015 01 02 1

随机推荐

  • CSDN找到“仅我可见”内容

    有时候自己做一些笔记参考了他人的内容 所以想将文章转为 仅自己可见 仅作自用 记录一下CSDN找私密文章的方式 今天摸了好一会儿才找到哈哈哈 1 点击导航栏处的创作中心进入 2 查看更多 3 点击浏览就可以查看啦 来源 CSDN找到 仅我可
  • 工业数据的特殊性和安全防护体系探索思考

    随着工业互联网的发展 工业企业在生产运营管理过程中会产生各式各样数据 主要有研发设计数据 用户数据 生产运营数据 物流供应链数据等等 这样就形成了工业大数据 这些数据需要依赖企业的网络环境和应用系统进行内外部流通才能实现价值挖掘 如何高效安
  • 题解 | #火车进站#

    解约的同学看过来 提供一份解约思路 题解 火车进站 include
  • 20um尺度纳米机器人需要的条件

    制作出真正的智能纳米机器人需要什么条件 首先人类已经可以制作出一台符合人类需要的智能机器人了 即便不能生成出一台真正智能的机器人 但是半智能的机器人还是可以生产出来的 我认为半智能的机器人才是人类需要的 毕竟制作出一台可能不听话 失去控制的
  • 【二分查找】【z型搜索】LeetCode240:搜索二维矩阵

    LeetCoe240搜索矩阵 作者推荐 贪心算法 中位贪心 执行操作使频率分数最大 本文涉及的基础知识点 二分查找算法合集 题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 该矩阵具有以下特性 每
  • Minecraft服务器badly compressed packet报错解决方法

    此方法只在1 16 5Mohist端 Forege和水龙头 解决过 在其他版本不一定适用 1 报错信息 因为已经解决了问题所以懒得改回去截图了 随便找的网图 2 解决方案 在服务端和客户端都安装 XL数据包 MOD 虽然写着1 16 4但是
  • echarts漏斗图自定义漏斗颜色、粗细、大小、间隔缝隙

    echarts漏斗图自定义漏斗颜色 粗细 大小 间隔缝隙
  • 24届还有在看工作机会的吗,求求大家看下小米吧,HC非常多

    一定要反问HR的六个问题 offer比较 华为 vs OPPO 离谱的一周 百度裁应届 拼多多 非必要就别去了吧 阿里云25k gt 美团29k 实习转正啦 进来看耍猴 12 17更新 25届实习招聘信息汇总走起 策论 设计产出 Learn
  • sqlserver-事物日志

    前言 每个 SQL Server 数据库都有事务日志 用于记录所有事务以及每个事务所做的数据库修改 事务日志是数据库的一个关键组件 如果系统出现故障 你将需要依靠该日志将数据库恢复到一致的状态 有关事务日志体系结构和内部组件的详细信息 请参
  • Navicat关闭自动检查更新版本教程

    Navicat关闭自动检查更新版本教程 首先 点击菜单中的工具菜单 弹出了下拉菜单选中为选项 点击选项 首先 点击菜单中的工具菜单 弹出了下拉菜单选中为选项 点击选项 去掉勾选上在启动时自动检查更新选项
  • android无线调试连接

    开发时 遇到一些设备无法通过USB线连接adb时 可以尝试使用wifi无线调试 首先 要确保手机和电脑在同一个局域网内 再到开发者选项中打开无线调试 并进入子页面 如下 图一 无线调试设置界面 点击使用配对码配对设备 会弹出如下对话框 图二
  • ubantu22版本配置静态IP地址

    文章目录 编辑网络配置文件 应用网络配置 查看网络配置结果 编辑网络配置文件 在Ubuntu中配置静态IP地址可以通过以下步骤实现 打开终端 使用以下命令编辑网络配置文件 etc netplan 00 installer config ya
  • 【web网页制作】html+css网页制作游戏主题-王者荣耀(5页面)【附源码下载】

    涉及知识 游戏主题网页制作 王者荣耀网页制作成品 游戏网页制作成品 游戏主题web开发 期末网页大作业 网页作业成品 web前端源码实例 如何制作网页 网页设计思路 如何从零开始制作web页面 专栏 web前端大作业网页制作 关于我 一个持
  • Android NDK开发详解Wear之处理 Wear 上的数据层事件

    Android NDK开发详解Wear之处理 Wear 上的数据层事件 等待数据层调用的状态 异步调用 同步调用 监听数据层事件 使用 WearableListenerService
  • 题解 | #浙江大学用户题目回答情况#

    快手测开二面面经 国企面经 多家 得物 测开 一面 中国联通陕西省分公司薪资待遇 京东健康前端实习一面凉经 求java推荐项目 面经回馈 秋招及实习历程中笔经 面经 时间梳理 国企银行 秒杀项目常见问题 终焉篇 双非本产品经理35w 终于来
  • Redis 底层数据结构

    在 Redis数据结构和对象机制 中提到的图中 我们知道 可以通过 redisObject 对象的 type 和 encoding 属性 可以决定Redis 主要的底层数据结构 SDS QuickList ZipList HashTable
  • EMC RI/CI测试方案助您对抗电磁设备干扰!

    方案背景 电磁或射频干扰的敏感性 会给工程师带来重大的风险和安全隐患 尤其是在工业 船用和医疗设备环境 这些环境系统中的控制 导航 监控 通信和警报等关键零部件必须具备电磁抗扰水平 以确保系统始终正常运行 抗扰系统测试方案一般分为传导抗扰与
  • 大语言模型加速信创软件 IDE 技术革新

    QCon 全球软件开发大会 上海站 将于 12 月 28 29 日举办 会议特别策划 智能化信创软件 IDE 专题 邀请到 华为云开发工具和效率领域首席专家 华为软件开发生产线 CodeArts 首席技术总监王亚伟担任专题出品人 为专题质量
  • System.Text.Json.JsonSerializer 自定义实现序列化 DataSet、DataTable

    System Text Json 从 NET Core 3 1 开始 为了能够序列化这些类型 您需要为JsonConverter
  • sqlserver dba日常操作

    查询慢sql的方法 1 whoisactive 安装方法 http whoisactive com downloads 下载地址 将下载好的zip包放到sqlserver服务器中 文件 打开 文件 下载好的zip包 在查询窗口点击执行 新建