我正在维护别人的代码。有一个存储过程每天或每周运行一次(取决于配置),它将一堆记录从活动表迁移到存档。但它不是真正的存档,因为有几个实时进程在 SQL 查询中包含存档表,为此目的正确索引了存档表。
现在这个故事的历史是归档表越来越大,归档 SP 开始需要很长时间。所以有人决定在 SP 开始时删除存档表上的所有索引并在最后重新创建它们是一个好主意。当然,重新创建它们也需要很长时间,但可以说只要插入带有索引的新记录就行了。
这种情况只是对我尖叫:“这是罪恶的! ” 在运行时搞乱索引似乎是错误的,错误的,错误的。我确信这不是一种罕见的情况,那么处理这种情况的“正确”方法是什么?
我们的生产 SQL Server 昨天冻结了。必须杀死 Windows 进程才能让它重新启动。
Microsoft SQL Server 2016 (SP1-CU1) (KB3208177) - 13.0.4411.0 (X64)
Jan 6 2017 14:24:37
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64>
(Build 9600: ) (Hypervisor)
Run Code Online (Sandbox Code Playgroud)
事件查看器在崩溃时说:
分配给节点 0 上的进程的新查询在过去 300 秒内没有被工作线程接收。阻塞或长时间运行的查询会导致这种情况,并可能降低客户端响应时间。使用“最大工作线程”配置选项来增加允许的线程数,或优化当前运行的查询。SQL 进程利用率:0%%。系统空闲:99%%。
发现这篇文章(从 2010 年开始)提供了一些如何阅读故障转储的提示。我查看了来自我们服务器的故障转储,发现了数千个看起来像这样的块:
2376 Id: 6bc.84c8 Suspend: 0 Teb: 00007ff7`f74d4000 Unfrozen
# Child-SP RetAddr Call Site
00 000000b5`5938bcd8 00007fff`d22e6d8e ntdll!NtSignalAndWaitForSingleObject+0xa
01 000000b5`5938bce0 00007fff`c1944b99 KERNELBASE!SignalObjectAndWait+0xc8
02 000000b5`5938bd90 00007fff`c19414dc sqldk!SOS_Scheduler::Switch+0x106
03 000000b5`5938c080 00007fff`c4c5185f sqldk!SOS_Scheduler::SuspendNonPreemptive+0xd3
04 …Run Code Online (Sandbox Code Playgroud) 我有一个用户ls_readonly应该拥有db_datareader多个数据库的权限。我以为我已经设置好了:
但是当我连接到服务器ls_readonly并尝试在对象资源管理器中打开数据库时,我收到一个错误:
数据库 wtest 不可访问。(对象浏览器)
我打开一个查询窗口master并尝试运行:
use wtest
Run Code Online (Sandbox Code Playgroud)
这回应:
Msg 916, Level 14, State 1, Line 1
The server principal "ls_readonly" is not able to access the database "wtest" under the current security context.
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
更新:这是一个线索。如果我ls_readonly作为用户从数据库的安全上下文中删除,那么我会转到服务器安全上下文下的用户,并在“用户映射”下授予对数据库的访问权限,然后它开始工作。
可能是该数据库最初是从另一台服务器恢复的,该服务器也有一个ls_readonly用户。我猜那么用户识别不是基于用户名?
我有一个业务要求在TableA引用上有一个 FK 字段TableB。如果 中有一个值TableBID,它应该是唯一的,但它不是强制性的,因此可能会有多个值为空的记录。
是否可以使用索引或约束以某种方式在数据库级别强制执行这种类型的唯一性?
(与此问题有关)
如果我想查看当前是否有任何长时间运行的查询在我的数据库上执行,最简单的检查方法是什么?(我希望答案会是一些关于master..sysprocesses?)
检查我们昨天的生产日志,我们发现在大约 5 分钟的时间内,一大堆非常简单的查询超时。对服务器日志的进一步调查显示磁盘活动激增,这使我得出结论,当时正在数据库上运行自动 CHECKPOINT。
这是我真的不想在高峰时段发生的事情。所以我想每天在非高峰时间安排一个每日检查点。
这是一个好主意吗?馊主意?浪费时间?如果不是这样,那又是什么?