sqlserver dba日常操作

查询慢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 的运行状态,快速找到执行缓慢的语句。这是我使用最频繁的脚本之一.

SELECTes.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
FROMsys.dm_exec_requests erINNER  JOIN  sys.dm_exec_sessions  es  ON er.session_id=es.session_idCROSS  APPLY  sys.dm_exec_sql_text (er.sql_handle)AS  qt
WHEREes.session_id> 50         AND  es.session_Id  NOT  IN(@@SPID)
ORDER BY1, 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
GOSET QUOTED_IDENTIFIER ON
GOCREATE procedure [dbo].[sp_full_BackupDB](@DBName varchar(50))
as
begindeclare @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.bakset  @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.bakset  @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.bakset  @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.bakset  @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  @sCommandTextset  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'exec xp_cmdshell  @sCommandTextend
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
GOSET QUOTED_IDENTIFIER ON
GOCREATE procedure [dbo].[sp_differential_BackupDB](@DBName varchar(50))
as
begindeclare @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.bakset  @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  @sCommandTextset  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'exec xp_cmdshell  @sCommandTextend
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
GOSET QUOTED_IDENTIFIER ON
GOCREATE procedure [dbo].[sp_tlog_BackupDB](@DBName varchar(50))
as
begindeclare @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.bakset  @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  @sCommandTextset  @sCommandText = 'echo  -------------------    >>  D:\bak_db\backup_detail.txt'exec xp_cmdshell  @sCommandTextend
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 = 102、图形化操作:
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 NULLDROP 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)
BEGINDECLARE @tempint intDECLARE @firstint intDECLARE @secondint intSELECT @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
ENDSELECT @hexvalue = @charvalue
GOIF OBJECT_ID ('sp_help_revlogin') IS NOT NULLDROP 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 sysnameIF (@login_name IS NULL)DECLARE login_curs CURSOR FORSELECT 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 lON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSEDECLARE login_curs CURSOR FORSELECT 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 lON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
OPEN login_cursFETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGINPRINT 'No login(s) found.'CLOSE login_cursDEALLOCATE login_cursRETURN -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)
BEGINIF (@@fetch_status <> -2)BEGINPRINT ''SET @tmpstr = '-- Login: ' + @namePRINT @tmpstrIF (@type IN ( 'G', 'U'))BEGIN -- NT authenticated account/groupSET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'ENDELSE BEGIN -- SQL Server authentication-- obtain password and sidSET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUTEXEC sp_hexadecimal @SID_varbinary,@SID_string OUT-- obtain password policy stateSELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @nameSELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @nameSET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'IF ( @is_policy_checked IS NOT NULL )BEGINSET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checkedENDIF ( @is_expiration_checked IS NOT NULL )BEGINSET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checkedENDENDIF (@denylogin = 1)BEGIN -- login is denied accessSET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )ENDELSE IF (@hasaccess = 0)BEGIN -- login exists but does not have accessSET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )ENDIF (@is_disabled = 1)BEGIN -- login is disabledSET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'ENDPRINT @tmpstrENDFETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denyloginEND
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);
GOCREATE TRIGGER tr_DDLLog
ON DATABASE
FOR DDL_PROCEDURE_EVENTS,DDL_FUNCTION_EVENTS,DDL_VIEW_EVENTS,DDL_TRIGGER_EVENTS,DDL_TABLE_EVENTS
AS
BEGININSERT 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 ASPRINT '1';
GO
--修改存储过程
ALTER PROCEDURE ChangeTest ASPRINT '1';
GO
--删除存储过程
DROP PROCEDURE ChangeTest;
GO

结果

在这里插入图片描述
总结

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

数据库重命名

问题描述:

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

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

ALTER DATABASE Mydb SET SINGLE_USER WITH ROLLBACK IMMEDIATEALTER 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 sizefrom 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=0from master..sysprocesses a join (  select blocked from master..sysprocesses group by blocked  )b on a.spid=b.blocked where a.blocked=0union 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=1from master..sysprocesses a where blocked<>0  )a order by s1,s2  select @count=@@rowcount,@i=1if @count=0 and @show_spid_if_nolock=1begin  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=1begin  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 ---杀死死锁的进程,显示正常的进程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/283920.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宝塔部署flask项目

宝塔(bt.cn)部署flask项目&#xff0c;发现问题还挺多。不过终于是搞定了。 先可以用pycharm建一个空的flask项目&#xff0c;这样好发现问题。 到网站栏目点击python项目&#xff0c;新建一个python项目。 要选择flask框架&#xff0c;uwsgi运行方式。 端口如果选择80端口&a…

执行计划EXPLAIN详解

什么是EXPLAIN&#xff1f; EXPLAIN是MySQL提供的一条语句&#xff0c;用于详细展示MySQL如何执行一条SELECT语句。通过使用EXPLAIN&#xff0c;开发者可以看到MySQL如何处理查询及连接表&#xff0c;帮助我们诊断性能问题。 使用方法非常直接&#xff0c;只需在SELECT查询前…

儿童玩具行业分析:发展态势良好,市场空间不断拓展

玩具是有利于促进幼儿体、德、智、美的全面发展;符合儿童年龄特征&#xff0c;能满足其好奇心、好动和探索活动的愿望;造型优美&#xff0c;反映事物的典型特征;活动多变&#xff0c;有助于鼓励学习。中国玩具产品包括毛绒玩具、塑胶玩具、纸质玩具、电子玩具、木制玩具、金属玩…

虚拟机无法进入系统问题

概述 客户在华为云平台上创建了两台虚拟机并部署aarch64 V10 OS&#xff0c;2021-10-28其中一台虚拟机业务出现异常&#xff0c;运维重启虚拟机后系统进不去&#xff0c;左上角光标闪烁&#xff0c;接着重启另一台虚拟机同样起不来&#xff0c;现象一致。 分析 通过分析现场…

嵌入式Linux学习(3)——中断(Interrupt)子系统概念

目录 一. 中断概念与分类 1.1 中断分类 1.2 中断事件的处理流程 1.3 中断号(IRQ number) 1.4 中断源(Interrupt Source) 1.5 中断触发方式 二. 中断子系统架构 2.1 GIC 2.2 中断子系统架构 2.3 GIC与IP 2.3.1 典型GIC IP PLC390 GIC 400 GIC 500 REF 一. 中断概念与…

如何基于企业需求,又便宜又快地定制开发一套CRM客户管理系统?

如何基于企业需求&#xff0c;又便宜又快地定制开发一套CRM客户管理系统&#xff1f; 定制开发CRM客户管理系统是为了满足企业个性化需求而进行的&#xff0c;它可以帮助企业提高客户关系管理效率&#xff0c;提供更好的客户服务和实现精细化运营。本文将为大家介绍CRM定制开发…

TaxtArea中内嵌一张放松图片,该图片实现属性悬浮放大功能

TaxtArea中内嵌一张发送图片&#xff0c;该图片实现属性悬浮放大功能&#xff0c;离开还原效果&#xff0c;点击发送按钮后&#xff0c;发送图片变为loading&#xff0c; <div class"textarea-wrapper" ><a-textarearef"textArea"v-model.trim&q…

javafx可视化java编程入门教程

JavaFX是一个用于构建富客户端应用程序的开发框架。它提供了丰富的图形界面和多媒体功能,并且非常易于学习和使用。本文将带你从入门到精通JavaFX,让你了解如何使用JavaFX构建出色的界面和交互式应用程序。 第一部分:入门 JavaFX的入门非常简单。首先,你需要安装JavaFX开…

【C盘爆满系列二,留个笔记下次用】

C盘爆满系列二 这次遇到的c盘爆满的清空&#xff0c;始终未检测出具体原因1、系统休眠文件2、WinSxS 这次遇到的c盘爆满的清空&#xff0c;始终未检测出具体原因 使用这个扫描软件&#xff0c;扫描出了问题&#xff0c;主要占有存储的有两个大的方面。 1、系统休眠文件 因为…

借助图形控件Aspose.Tasks,在 C# 中将 XER 转换为 SVG

Primavera P6 是一款流行的项目管理软件&#xff0c;它使用XER 文件格式来存储项目数据。 SVG&#xff08;即可缩放矢量图形&#xff09;是一种流行的矢量图像格式&#xff0c;可用于为 Web 和打印应用程序创建可缩放图形。在某些情况下&#xff0c;我们可能需要以编程方式将 P…

唯众成功入选“全国基础软件安全可信行业产教融合体”理事单位

12月15日&#xff0c;全国基础软件安全可信行业产教融合共同体成立大会在武汉隆重召开。武汉唯众智创科技有限公司作为受邀嘉宾参加了成立大会。大会公布了共同体成员单位名单&#xff0c;唯众成功当选理事单位。 全国基础软件安全可信行业产教融合共同体 全国基础软件安全可信…

C++学习笔记(十五)

一、继承 继承是面向对象三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; 我们发现&#xff0c;定义这些类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性。 这个时候我们就可以考虑利用继承的技术&#xff0c;减…