我们有一个由供应商支持的应用程序,并且有一段代码在一个过程中执行非常繁重的逻辑读取和耗时,因此我建议他们稍微调整查询以减少 IO 和时间,它在在数据和性能方面进行测试,但是在生产中失败并返回不同的数据,我们不得不回滚更改。需要您的专家建议。
这是在测试环境中对数据进行了3个多月的测试,我们从未出现过任何数据问题。部署后立即开始在生产中很少失败,并产生不一致的数据。
现有查询:
SELECT @Ref= CAST(MAX(ISNULL(CAST(ref_clnt AS INT),0))+1 AS VARCHAR(10))
FROM table_name WITH(NOLOCK)
WHERE s_mode='value'
Run Code Online (Sandbox Code Playgroud)
建议查询:
SELECT @Ref = ref_clnt+1 FROM table_name WITH(NOLOCK)
WHERE RefNo = (SELECT MAX(RefNo) FROM table_name WHERE s_mode = 'value')
Run Code Online (Sandbox Code Playgroud)
表的DDL如下:
CREATE TABLE [dbo].[table_name](
[RefNo] [dbo].[udt_RefNo] NOT NULL,
[S_Mode] [varchar](10) NOT NULL,
[ref_clnt] [varchar](50) NULL)
CONSTRAINT [PK_table_name] PRIMARY KEY CLUSTERED
(
[RefNo] ASC
)
Run Code Online (Sandbox Code Playgroud)
仅提供查询中使用的定义中的那些列。
Udt_RefNo 是用户定义的数据类型:
CREATE TYPE [dbo].[udt_RefNo] FROM [char](16) NOT NULL
GO
Run Code Online (Sandbox Code Playgroud)
SQL Server 版本:Microsoft SQL Server 2014 (SP3) 版权所有 …
我支持基于供应商的应用程序,它充满了块和死锁。死锁主要涉及两个或三个进程,但是我昨天注意到,它涉及 9 个 SPID。
有人可以帮助我理解这个死锁图和如何避免这种情况的解决方案。
<deadlock><victim-list><victimProcess id="process2ff017c28"/><victimProcess id="process2f1538108"/><victimProcess id="process2f618d088"/><victimProcess id="process2f6d828c8"/><victimProcess id="process2f6d83848"/><victimProcess id="process2da9b5468"/><victimProcess id="process2efac7468"/><victimProcess id="process2efac7848"/></victim-list><process-list><process id="process2ff017c28" taskpriority="0" logused="0" waitresource="OBJECT: 11:1142295129:0 " waittime="4412" ownerId="284194209" transactionname="implicit_transaction" lasttranstarted="2019-04-08T15:29:07.323" XDES="0x2a785f800" lockMode="IX" schedulerid="1" kpid="9052" status="suspended" spid="63" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2019-04-08T15:30:58.733" lastbatchcompleted="2019-04-08T15:30:58.733" lastattention="1900-01-01T00:00:00.733" clientapp="jTDS" hostname="APPNAME" hostpid="123" loginname="IRB_APP_USER" isolationlevel="repeatable read (3)" xactid="284194209" currentdb="11" currentdbname="Database_Name" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058"><executionStack><frame procname="adhoc" line="1" stmtstart="46" stmtend="180" sqlhandle="0x02000000b6b6e728e6bf289c908196a1f4e56b8892a5eab10000000000000000000000000000000000000000">
unknown </frame></executionStack><inputbuf>
(@P0 bigint,@P1 bigint)update Table_Name set STATUS_ID= @P0 where id= @P1 </inputbuf></process><process id="process2f1538108" taskpriority="0" logused="0" waitresource="OBJECT: 11:1142295129:0 " waittime="4411" ownerId="284107628" transactionname="implicit_transaction" lasttranstarted="2019-04-08T15:24:11.843" XDES="0xdacf54e0" lockMode="IX" …Run Code Online (Sandbox Code Playgroud) 有人告诉我,对于数据文件备份在范围级别操作,对于日志文件,备份在页面级别操作。
我知道数据文件的文件类型总是“行数据”并以范围(混合或统一范围)的形式存储,而日志以日志的形式存储,即 VLF(虚拟日志文件)。
可以请某人稍微详细地阐明这个概念,因为我对备份如何区分数据和日志感到有些困惑。如果是完整备份,它将存储写入数据文件的所有已提交更改,用于差异 - 自数据文件的上次完整备份以来的所有更改。对于日志备份 - 所有已提交但未写入数据文件的更改。
感谢您对此的宝贵意见。
我知道我的数据库上有很多阻塞,并已尽力按供应商进行排序,因为他们支持此应用程序并且尚未产生任何成功的结果。时不时,我们会遇到阻塞问题,这种阻塞变得如此严重,而且他们的设计非常糟糕,以至于整个门户都会关闭,除非我杀死少数持有排他锁的 SPID(大部分)。
我已经使用 sp_blitzindex 近一年了,并且是 Brent Ozar 先生和团队提供的 First Responder Kit 的忠实粉丝。当我对这个发生阻塞的数据库执行 sp_blitzindex 时,它说 - “积极的索引不足:总锁定等待时间 > 5 分钟(行 + 页),平均等待时间长”,优先级为 10。我检查了URL列并还检查了其他相关页面,但无法获得太多帮助。
我知道此处列出的表已编入索引,并且需要创建更多索引,但是当我使用以下命令在表级别为这些对象分别运行相同的过程即 sp_blitzindex 时:
EXEC dbo.sp_BlitzIndex @DatabaseName='db1', @SchemaName='sch', @TableName='tab1';
Run Code Online (Sandbox Code Playgroud)
我根本没有得到任何丢失的索引详细信息。所有现有索引都被利用并且读取计数小于写入计数,只有这里突出显示的问题在主键的“锁定等待”列中。
我不知道需要创建哪个列索引。我还检查了 sp_blitzlock 以查看是否可以收集更多信息,这会有所帮助,但是我看到有很多死锁并且列出了相同的对象,这些对象在积极索引不足中被计算出来。
还通过在此特定数据库中将排序顺序作为“读取”和“持续时间”传递来检查 sp_blitzcache 的输出,但没有丢失索引请求。有警告说“未参数化查询”和“未参数化查询,非 SARGables”,这些计划涉及不同的表集。
任何帮助都受到高度赞赏。
Version: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) Sep 7 2018 01:37:51 Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 (Build 9600: ) (Hypervisor)
Run Code Online (Sandbox Code Playgroud) 几个月以来,我一直在努力解决这个问题,我说这不是数据库问题,并将此案例分配给存储和操作系统团队,然后他们将其分配给我。这个问题反复发生,没有任何定义的发生模式。
我检查了这里提出的相同问题,我可以说这不是数据库损坏的问题,因为我使用 Ola Hallengren 的脚本进行维护工作,并且每周对用户和系统数据库进行数据库完整性检查(checkdb),并且没有报告任何问题在那里面。
也针对类似问题访问了第二个链接,可以确认 tempdb 处于简单恢复状态。
我为数据和日志添加了一个额外的文件,这样如果一个文件不可用,另一个文件仍然可以访问,但是后来我知道 tempdb 的访问是顺序的,因此只有当第一个文件已满时它才会转到第二个文件:
每次出现此问题时,我都可以看到 Windows 应用程序日志中还有另一个错误,如下所示:
SQLServerLogMgr::LogWriter: Operating system error 170(The requested resource is in use.) encountered.
Run Code Online (Sandbox Code Playgroud)
存储团队已将这些文件从防病毒扫描中排除。
这里需要注意的一件事 - 我检查了其他系统数据库及其文件位置,可以看到对于 master 和 model,数据和日志文件在同一个驱动器(E 驱动器)中,而对于 tempdb 和 msdb,数据在 E 驱动器和日志中文件在 G 驱动器中,不确定这是否相关。
当作业触发或任何事件被触发时,是否有任何检查系统数据库的顺序?如果该驱动器出现问题,则 msdb 也在同一驱动器上。
这是一个集群服务器,数据库驱动器在两台服务器中共享,服务器用于共享点应用程序。
Server Version: Windows Server 2012 Standard
SQL Server: Microsoft SQL Server 2012 (SP4-GDR) (KB4057116) - 11.0.7462.6 (X64)
Jan 5 2018 22:11:56
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.2 …Run Code Online (Sandbox Code Playgroud) 备份 cassandra 或 scyladb 以便我们可以轻松在开发环境中恢复它的正确(建议)方法是什么?
我一直在使用sp_whoisactive,这对于查找运行会话和阻塞的详细信息非常有帮助。
我想检查是否有任何选项可以根据此过程安排作业,并仅在数据库上存在活动阻塞并且阻塞持续时间超过可配置的分钟数时才提醒我。
此外,只有当它达到超过可配置的数据库阻塞数量时才应触发警报。
我使用了http://www.sqlserver-dba.com/2017/01/how-to-monitor-blocked-processes-with-sql-alert-and-email-sp_whoisactive-report.html中给出的详细信息,但是它发送每次运行时发出警报,似乎没有检查是否有阻塞。无论是只运行一个查询还是运行多个查询,无论是阻塞还是不阻塞,都发送电子邮件。不确定,如果我错过了什么。
我一直在使用 sp_blitzindex,它非常有帮助(感谢 Brent Ozar 和团队)。我对我的数据库执行了这个过程,下面是一个属于 Indexaphobia 组的表的发现:
下面是基础表的定义:
CREATE TABLE [dbo].[table_name](
[L] [int] IDENTITY(1,1) NOT NULL,
[R] [varchar](15) NOT NULL,
[A] [int] NOT NULL,
[VAR32_01] [varchar](32) NULL,
[VAR32_02] [varchar](32) NULL,
[VAR32_03] [varchar](32) NULL,
[VAR32_04] [varchar](32) NULL,
[VAR32_05] [varchar](32) NULL,
[VAR32_06] [varchar](32) NULL,
[VAR32_07] [varchar](32) NULL,
[VAR32_08] [varchar](32) NULL,
[VAR32_09] [varchar](32) NULL,
[VAR32_10] [varchar](32) NULL,
[VAR32_11] [varchar](32) NULL,
[VAR32_12] [varchar](32) NULL,
[VAR32_13] [varchar](32) NULL,
[VAR32_14] [varchar](32) NULL,
[VAR32_15] [varchar](32) NULL,
[VAR32_16] [varchar](32) NULL,
[VAR32_17] [varchar](32) NULL,
[VAR32_18] [varchar](32) NULL,
[VAR32_19] [varchar](32) …Run Code Online (Sandbox Code Playgroud) 我正面临一个奇怪的问题,其中我分析了一个每 3 分钟运行一次并且给 CPU 带来负载的存储过程。我发现有许多 select 语句是此过程的一部分,并且所有这些语句都在进行全表扫描(读取表中的所有页面)。所以,我在测试环境中测试了它们,并使用非聚集索引支持它。与有关供应商确认相同,他们同意更改。我昨天将它们部署到生产中,检查了这些查询的逻辑读取,并在新索引后交叉检查相同,验证它具有积极影响,逻辑读取下降了 1/10。
部署此索引后,每 3 分钟运行一次的过程立即开始失败。手动执行以检查问题并发现,除了在 1 小时内发生 1 或 2 次之外,它每次都会导致死锁。我完全不知道索引怎么会导致死锁?理想情况下,索引应该解决死锁,但恰恰相反。
我所指的表是一个堆,没有聚集主键,而是具有非聚集主键。我得到了各方的同意进行从 NC 到集群的更改,但是它通过 PK-FK 关系与多个表链接并且需要停机时间,因此它目前处于暂停状态。
我已经捕获了死锁图并且还设置了 sp_blitzlock。应用程序查询和这个过程之间似乎发生了死锁,但是我不明白这个索引是如何导致它的,以及当我回滚这个索引时,它运行顺利并且没有死锁。
死锁图如下:
<deadlock>
<victim-list>
<victimProcess id="processef645b848" />
</victim-list>
<process-list>
<process id="processef645b848" taskpriority="0" logused="0" waitresource="PAGE: 6:1:965 " waittime="3661" ownerId="303318514" transactionname="INSERT" lasttranstarted="2020-11-02T12:18:12.793" XDES="0x31fbb78e0" lockMode="S" schedulerid="1" kpid="8564" status="suspended" spid="1246" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-11-02T12:18:00.500" lastbatchcompleted="2020-11-02T12:18:00.500" lastattention="1900-01-01T00:00:00.500" clientapp="SQLAgent - TSQL JobStep (Job 0x417A2365E91D1647B2C225CA23D84860 : Step 1)" hostname="DB_Server" hostpid="3628" loginname="SQL_Agent_Login" isolationlevel="read committed (2)" xactid="303318514" currentdb="7" currentdbname="DB_Name_1" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="adhoc" …Run Code Online (Sandbox Code Playgroud) 我们正在尝试定义备份策略。我们打算申请以下内容:
但我们也在探索其他选项 - 事务日志备份和 Azure 备份(默认为 2 小时)
我是否正确地说差异备份会让我们到达上次差异备份,然后我们可以使用日志备份来接近我们想要恢复的位置?
因此,备份将如下所示:
自星期三以来每 2 小时 Inc - 日志备份。
让我们说灾难在周三中午来袭!
恢复差异,让我们在星期三凌晨 1 点...然后我们使用日志备份让我们在灾难发生之前到达。
这是类型之间的正确区分吗?
我有一个特殊的情况让我使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED. (我sp_getapplock用来确保单个进程访问给定的行。)
我正在尽力避免任何类型的锁定升级。我清楚地知道ISOLATION LEVEL READ UNCOMMITTED读取有什么作用,但我不确定删除。
我看到用做删除一些示例代码ROWLOCK和READPAST,连同ISOLATION LEVEL READ UNCOMMITTED但我是没有什么,会做明确的,所以我也没有一直在使用它了。
这是否需要防止我的删除锁定升级或就ISOLATION LEVEL READ UNCOMMITTED足够了?
我正在 Stackoverflow 数据库上进行测试,以找出 SQL Server 不建议在执行计划中使用索引的可能情况,但是如果我们引入索引,它将有很大帮助!
对于 Group by、Order by Clause 和聚合函数(计数函数 - 表的最小副本)来说,这很容易吗?我编写了一个随机查询,其中我知道引入支持性索引肯定会有所帮助,但是缺少索引建议将仅在连接条件上而不是在 order by 子句上。
查询如下:
select top 100 Location from Users U join Badges B
on B.UserId = U.Id
order by Location desc
Run Code Online (Sandbox Code Playgroud)
引入以下索引来提高性能:
create index Location on Users(Location)
go
create index UsersId on Badges(UserId)
go
Run Code Online (Sandbox Code Playgroud)
优化器按照上述查询的预期使用索引:
逻辑读取和时间统计如下:
现在,我想测试仅在位置列上的用户表上建立索引并且在徽章(UserId)表上没有索引的情况下的性能,这里性能变得很糟糕(需要大约 7 分钟):
逻辑读取和时间统计如下:
用户表上的索引被大量使用,从执行计划和逻辑读取可以明显看出,但是执行聚集索引扫描和表假脱机(惰性假脱机)会导致大部分问题。
以上所有测试均在 SQL Server 2019 上以 SQL Server 2016 兼容模式(130)进行。
如果有人可以就根本问题提供建议,将会有很大帮助。
这里还要注意一点,当这两个表中的任何一个上都没有非聚集支持索引时,相同的查询会在 9 秒内完成。下面是执行计划:
逻辑读取和时间统计:
出于测试目的,我将兼容性级别更改为 2019(150),令我惊讶的是 - 之前的相同查询仅在用户(位置)表上有索引,而不在徽章表上有索引,在 2 秒内完成,而在 SQL Server 2016 中需要 …
最近有人问我问题 - 标准服务器角色和固定服务器角色之间有什么区别。
我知道固定服务器角色包括:系统管理员、安全管理员等。
我不确定标准服务器角色。
谢谢你。
sql-server ×12
backup ×2
deadlock ×2
index ×2
blocking ×1
cassandra ×1
locking ×1
log ×1
performance ×1
permissions ×1
role ×1
scylladb ×1
table-spool ×1
tempdb ×1