SQL Server 允许您将作业配置为在失败时发送电子邮件警报。这是监控您的工作的一种简单而有效的方法。但是,这些警报不包括任何细节——只是成功或失败的通知。
如果作业失败,典型的警报电子邮件将如下所示:
JOB RUN: 'DBA - Consistency Check Databases' was run on 8/14/2011 at 12:00:04 AM
DURATION: 0 hours, 0 minutes, 0 seconds
STATUS: Failed
MESSAGES: The job failed. The Job was invoked by Schedule 2 (Nightly Before
Backup 12AM). The last step to run was step 1 (Check Databases).
Run Code Online (Sandbox Code Playgroud)
要确定失败的原因,您必须导航到 SQL Server Management Studio 中的实例,找到作业并查看其执行历史记录。在大型环境中,必须不断地这样做可能会很痛苦。
理想的警报电子邮件应预先包含失败原因,并让您直接着手解决方案。
我熟悉这个问题的解决方案。有没有人有任何经验?它的缺点是:
spDBA_job_notification有没有人想出更好的解决方案?
我刚刚在我的网站http://sqlfiddle.com上推出了一项功能,允许用户查看其查询的原始执行计划。对于 PostgreSQL、MySQL 和(在某种程度上)Oracle,查看原始执行计划输出似乎很容易理解。但是,如果您查看 SQL Server 的执行计划输出(使用 生成SET SHOWPLAN_XML ON),即使对于相对简单的查询,也有大量的 XML 需要处理。这是一个示例(取自此“小提琴”的最后一个查询的执行计划:http : //sqlfiddle.com/#!3/ 1fa93/1):
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.1" Build="10.50.2500.0">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementText="
select * from supportContacts" StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.0032853" StatementEstRows="3" StatementOptmLevel="TRIVIAL" QueryHash="0x498D13A3874D9B6E" QueryPlanHash="0xD5DDBD3C2D195E96">
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/>
<QueryPlan CachedPlanSize="16" CompileTime="0" CompileCPU="0" CompileMemory="72">
<RelOp NodeId="0" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="3" EstimateIO="0.003125" EstimateCPU="0.0001603" AvgRowSize="42" EstimatedTotalSubtreeCost="0.0032853" TableCardinality="3" Parallel="0" EstimateRebinds="0" EstimateRewinds="0">
<OutputList>
<ColumnReference Database="[db_1fa93]" Schema="[dbo]" Table="[supportContacts]" Column="id"/>
<ColumnReference Database="[db_1fa93]" Schema="[dbo]" Table="[supportContacts]" …Run Code Online (Sandbox Code Playgroud) 我将传感器数据存储在表SensorValues 中。表和主键如下:
CREATE TABLE [dbo].[SensorValues](
[DeviceId] [int] NOT NULL,
[SensorId] [int] NOT NULL,
[SensorValue] [int] NOT NULL,
[Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED
(
[DeviceId] ASC,
[SensorId] ASC,
[Date] DESC
) WITH (
FILLFACTOR=75,
DATA_COMPRESSION = PAGE,
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [MyPartitioningScheme]([Date])
Run Code Online (Sandbox Code Playgroud)
然而,当我选择在特定时间有效的传感器值时,执行计划告诉我它正在执行排序。这是为什么?
我原以为,由于我存储了按日期列排序的值,因此不会发生排序。还是因为索引不仅仅按日期列排序,即它不能假设结果集已排序?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = …Run Code Online (Sandbox Code Playgroud) DB 工作的新手,所以感谢您对基本问题的耐心。我在本地机器上运行 SQL Server 2014,我有一个小表和一个基本的客户端应用程序来测试不同的方法。我在INSERT INTOandUPDATE语句中都得到了一个表锁。客户端是具有以下代码的 ASP.NET 应用程序:
OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn; …Run Code Online (Sandbox Code Playgroud) 我们目前有 2 个 DBA,我和另外一个人,我们都觉得需要额外的资源(或两个)。我和我的直接经理就这个话题进行了几次不同的交谈,但我很难让这个想法被推销。最近,我们的经理与我们分享说,提出我们想要或认为需要做的事情的“软价值观”清单真的很好,但真正有帮助的是提出“硬价值观”,显示美元储蓄。
您能否首先帮助我了解我们感知到的需求是否合法,如果是,我们如何提出这个“硬价值”清单。我觉得我们可以想出一些我们需要做的事情来为公司节省资金,但这可能只是放在我们优先事项列表的前面,并且在这个过程中给我们带来了更多的压力。
为了让您对我们的环境有一个高层次的了解,以下是我所关注的关于我们提供支持的内容。
生产服务器 – 30 多个
生产数据库 – 200 多个
SQL 版本 – 2008/2008R2/2012,现在展望 2014 年,以及今年晚些时候的 2016 年
应用程序(第 3 方和本土开发) –
支持20 多个应用程序团队 – 6 个
虚拟化 – 75%虚拟化 25% 的物理
集群 – 3 个以上计划
复制 – 1 个分发服务器、2 个订阅服务器、24 个订阅、6 个发布服务器、12 个发布
日志传送 – 8 个主要 + 更多计划、4 个辅助 + 更多计划、49 个日志传送数据库 + 更多计划的
可用性组——目前没有,但探索可能性
推动版本更改或 DBA 资源的每年平均应用程序升级/安装——2-3
修补(SP、CU)——目前不存在,除非出现问题 累积数据库大小——14TB+
报告服务器——一个由 2 台服务器组成的横向扩展部署,我们都不精通 SSRS
分析服务器——两台服务器,我们都不精通 SSAS
我们应该使用哪些指标来证明或反驳对额外 DBA 的需求?
我最初的意图是展示我们当前的能力与我们计划的项目和重复任务的对比,但我们需要展示雇用额外资源的投资回报率。
我们碰巧使用的是 SQL Server 2012 标准版。我还碰巧使用了 Ola Hallengren 的脚本来提供一个简单、更灵活的框架来进行备份和维护。
这个问题不是关于 Ola 的脚本,而是关于最佳实践。我意识到最终的答案是“这取决于贵公司的要求”。但我正在尝试就如何最好地满足我对公司要求的理解寻求社区的建议。
我希望每 15 分钟设置一次事务日志备份。这样我们希望丢失不超过 15 分钟的数据。我应该设置一项使用 ALL_DATABASES 的作业吗?还是为每个数据库设置一项工作并并行启动它们更好?我问,因为根据我如何看待 Ola 的脚本功能,我有一种感觉,即备份是串行启动的。串行的缺点是每个连续的备份都等待另一个完成。这可能会增加备份之间的时间量(即大于 15 分钟)。另外,我担心一个备份的失败会阻止其他备份的发生,我不希望出现这种情况。我希望其他人继续备份。
那么,Ola 的脚本是串行执行的,而且故障也会停止连续备份吗?
每个数据库都有一份工作是不是更好?还是做所有事情的单一工作?我倾向于单独的工作,但我希望了解 SQL Server DBA 通常倾向于做什么。
我们的 ETL 流程有一个长时间运行的 SELECT INTO 语句,它动态地创建一个表,并用数亿条记录填充它。
该声明看起来像 SELECT ... INTO DestTable FROM SrcTable
出于监控目的,我们希望大致了解此语句在执行时的进度(大约行计数、写入的字节数或类似内容)。
我们尝试了以下方法无济于事:
-- Is blocked by the SELECT INTO statement:
select count(*) from DestTable with (nolock)
-- Returns 0, 0:
select rows, rowmodctr
from sysindexes with (nolock)
where id = object_id('DestTable')
-- Returns 0:
select rows
from sys.partitions
where object_id = object_id('DestTable')
Run Code Online (Sandbox Code Playgroud)
此外,我们可以在 中看到事务sys.dm_tran_active_transactions,但我无法找到一种方法来获取给定的受影响行数transaction_id(类似于@@ROWCOUNT也许,但带有transaction_idas 参数)。
我知道在 SQL Server 上,SELECT INTO 语句是 DDL 和 DML 语句合二为一,因此,隐式表创建将是一个锁定操作。我仍然认为必须有一些聪明的方法来在语句运行时获取某种进度信息。
我们的数据库架构师告诉我们的一位客户,SQL Server 2014 与 2012 相比是一个糟糕的选择,因为它缺乏 2012 具有的性能和稳定性优势。我读过的所有内容都与此相矛盾。 Aaron Bertrand 说的正好相反,我从 MS 那里读到的所有白皮书也同意——2014 年得到了增强,解决了人们在 2012 年遇到的一些 AG 问题。
选择 2014 年而不是 2012 年有什么主要缺点吗?
我有一个用户表:
|Username|UserType|Points|
|John |A |250 |
|Mary |A |150 |
|Anna |B |600 |
Run Code Online (Sandbox Code Playgroud)
和级别
|UserType|MinPoints|Level |
|A |100 |Bronze |
|A |200 |Silver |
|A |300 |Gold |
|B |500 |Bronze |
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个查询来获取每个用户的级别。类似的东西:
SELECT *
FROM Users U
INNER JOIN (
SELECT TOP 1 Level, U.UserName
FROM Levels L
WHERE L.MinPoints < U.Points
ORDER BY MinPoints DESC
) UL ON U.Username = UL.Username
Run Code Online (Sandbox Code Playgroud)
这样的结果将是:
|Username|UserType|Points|Level |
|John |A |250 |Silver |
|Mary |A |150 |Bronze |
|Anna |B |600 …Run Code Online (Sandbox Code Playgroud) 大家好,提前感谢您的帮助。我们在 SQL Server 2017 可用性组方面遇到了挑战。
背景
公司是一家零售B2B后端软件。约500个单租户数据库,5个共享数据库供所有租户使用。工作负载特征主要是读取,并且大多数数据库的活动非常低。
托管在同一地点的物理生产服务器最近从共享 SAN/FCI 配置的 Windows Server 2012 上的 SQL Server 2014 Enterprise 升级到 Windows Server 2016 上的 SQL Server 2017 Enterprise,在 2 插槽/32 核/768 GB RAM 和本地使用 AlwaysOn AG 的 SSD 驱动器。AG 流量使用具有交叉电缆连接的专用 10G NIC 端口。
他们的要求是所有数据库一起进行故障转移,因此他们必须将它们全部放在一个 AG 中。它是同一服务器上的单个不可读取的同步副本。
新服务器已于2018年6月投入生产,安装了最新的CU(当时的CU7)和windows更新,系统运行良好。大约一个月后,在将服务器从 CU7 更新到 CU9 后,他们开始注意到以下挑战,按优先级顺序列出。
我们一直在使用 SQL Sentry 监控服务器,并没有观察到物理瓶颈。所有关键指标似乎都不错。CPU 平均为 20%,IO 时间通常小于 1ms,RAM 未充分利用,网络 <1%。
挑战
故障转移后症状似乎好转,但几天后又会出现,无论哪个服务器是主要服务器 - 两台服务器上的症状都相同。
偶发的客户端超时和连接故障,例如
...建立连接时发生错误...
或者
执行超时过期
有时这些会持续长达 40 秒,然后消退。
事务日志备份作业的完成时间是以前的 10 倍。以前备份所有500个数据库的日志需要2-3分钟,现在需要15-25分钟。我们已经验证备份本身运行良好,吞吐量良好。但是,在完成一个日志的备份之后和开始下一个之前,会有一个小的延迟。它开始时非常低,但在一两天内达到 2-3 秒。乘以500个数据库,还是有区别的。
有时,一些看似随机的数据库会在手动故障转移后陷入“未同步”状态。解决此问题的唯一方法是重新启动辅助副本上的 SQL Server 服务,或者删除这些数据库并将其重新加入 …
sql-server ×10
backup ×1
insert ×1
join ×1
locking ×1
max ×1
metrics ×1
monitoring ×1
primary-key ×1