4.SQLServer数据库状态监控-作业状态
有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件。SQL Server也有它的定时任务组件 SQL Server Agent,基于它可以方便的部署各种数据库相关的作业(job)。 一 . 作业历史纪录 作业的历史纪录按时间采用FI
有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件。SQL Server也有它的定时任务组件 SQL Server Agent,基于它可以方便的部署各种数据库相关的作业(job)。
一. 作业历史纪录
作业的历史纪录按时间采用FIFO原则,当累积的作业历史纪录达到上限时,就会删除最老的纪录。
1. 作业历史纪录数配置
所有作业总计纪录条数默认为1000,最多为999999条;单个作业总计记录条数默认为100,最多为999999条。有下面2种方式可以进行修改:
(1) SSMS/SQL Server Agent/属性/历史;
(2) 未记载的扩展存储过程,SQL Server 2005及以后版本适用,以下脚本将记录数设回默认值:
EXEC msdb.dbo.sp_set_sqlagent_properties @jobhistory_max_rows=-1, @jobhistory_max_rows_per_job=-1 GO
2. 删除作业历史纪录
(1) SSMS/SQL Server Agent/右击作业文件夹或某个作业/查看历史纪录/清除
在SQL Server 2000中会一次清除所有作业历史记录,SQL Server 2005 及以后版本可以有选择的清除某个作业/某个时间之前的历史纪录;
(2) SQL Server 2005及以后版本,提供了系统存储过程如下:
--清除所有作业15天前的纪录 DECLARE @OldestDate datetime SET @OldestDate = GETDATE()-15 EXEC msdb.dbo.sp_purge_jobhistory @oldest_date=@OldestDate --清除作业”Test”3天前的纪录 DECLARE @OldestDate datetime DECLARE @JobName varchar(256) SET @OldestDate = GETDATE()-3 SET @JobName = 'Test' EXEC msdb.dbo.sp_purge_jobhistory @job_name=@JobName, @oldest_date=@OldestDate
作业历史纪录数有上限,通常不需要手动去删除。
3. 保留作业历史纪录
即便设置了历史记录上限到999999,如果作业很多,加之作业运行很频繁,最终历史记录还是会被慢慢删除掉。
如果想要保留某些作业历史的记录,可以打开作业属性/步骤/编辑/高级,选择将这个步骤的历史记录输出到文件/自定义表中,如下图:
650) this.width=650;" alt="" style="max-width:90%" />
二. 作业运行状态
界面上可以通过: SSMS/SQL Server Agent/右击作业文件夹或某个作业/查看历史纪录,如下用SQL 语句检查作业状态。
1. 作业上次运行状态及时长
利用系统表msdb.dbo.sysjobhistory:
(1) 表中的run_status字段表示作业上次运行状态,有0~3共4种状态值,详见帮助文档,另外在2005的帮助文档中写到:sysjobhistory的run_status为4表示运行中,经测试是错误的,在2008的帮助中已没有4这个状态;
(2) 表中run_duration字段表示作业上次运行时长,格式为HHMMSS,比如20000则表示运行了2小时。
如下脚本查看所有作业最后一次运行状态及时长:
if OBJECT_ID('tempdb..#tmp_job') is not null drop table #tmp_job --只取最后一次结果 select job_id, run_status, CONVERT(varchar(20),run_date) run_date, CONVERT(varchar(20),run_time) run_time, CONVERT(varchar(20),run_duration)run_duration into #tmp_job from msdb.dbo.sysjobhistoryjh1 where jh1.step_id = 0 and(select COUNT(1) from msdb.dbo.sysjobhistory jh2 wherejh2.step_id = 0 and(jh1.job_id = jh2.job_id) and(jh1.instance_id <=jh2.instance_id))=1 --排除syspolicy_purge_history这个系统作业 select a.namejob_name, case b.run_status when 0 then 'Failed' when 1 then 'Succeeded' when 2 then 'Retry' when 3 then 'Canceled' else 'Unknown' end as job_status, LEFT(run_date,4)+'-'+SUBSTRING(run_date,5,2)+'-'+RIGHT(run_date,2) +SPACE(1) +LEFT(RIGHT(1000000+run_time,6),2)+':' +SUBSTRING(RIGHT(1000000+run_time,6),3,2)+':' +RIGHT(RIGHT(1000000+run_time,6),2) as job_started_time, +LEFT(RIGHT(1000000+run_duration,6),2)+':' +SUBSTRING(RIGHT(1000000+run_duration,6),3,2)+':' +RIGHT(RIGHT(1000000+run_duration,6),2) as job_duration from msdb.dbo.sysjobs a left join #tmp_jobb on a.job_id=b.job_id where a.name not in('syspolicy_purge_history') and a.enabled = 1 order by b.run_status asc,a.name,b.run_duration desc
2. 作业当前运行状态及时长
什么时候可能要检查作业的当前状态?
(1) 需要关闭SQL Server或SQL Server Agent服务时;
(2) 等到当前作业完成,有后续动作;
(3) 纯粹只是查看当前作业运行到哪个步骤等等。
通过SSMS/SQL Server Agent/右击作业文件夹或某个作业/查看历史纪录,看到的作业历史记录存放在:
select * from msdb.dbo.sysjobhistory
需要注意的是:至少作业已完成第一步运行,sysjobhistory表中才会有作业历史纪录,若当前作业没有完成任何一个步骤,那表里就不会有本次运行纪录。所以作业当前状态用有时无法通过sysjobhistory查看,尤其是作业只有1个步骤且运行时间很长时。
2.1. SQL Server 2005及以后版本
(1) 当前运行状态:系统存储过程msdb.dbo.sp_help_job,返回所有作业的运行状态(current_execution_status),共7种状态值,详见帮助文档。查看所有作业状态如下:
exec msdb..sp_help_job
(2) 当前运行时长:系统存储过程sp_help_job无法获得作业运行时长,可通过新增的系统表sysjobactivity来查看。查看正在运行的作业如下:
select a.name, b.start_execution_date, DATEDIFF(MI,b.start_execution_date,GETDATE()) as job_duration from msdb..sysjobs a inner join msdb..sysjobactivityb on a.job_id = b.job_id where b.start_execution_date isnot null and b.stop_execution_date isnull
以下脚本结合sp_help_job和sysjobactivity,得到作业的当前状态及时长:
exec sp_configure'show advanced options',1 RECONFIGURE exec sp_configure'Ad Hoc Distributed Queries',1 RECONFIGURE if OBJECT_ID('tempdb..#jobinfo') is not null drop table #jobinfo select * into #jobinfo from openrowset('sqloledb', 'server=(local);trusted_connection=yes','exec msdb.dbo.sp_help_job') select a.name, j.current_execution_status, b.start_execution_date, DATEDIFF(MI,b.start_execution_date,GETDATE()) asjob_duration_minute from msdb..sysjobs a inner join msdb..sysjobactivityb on a.job_id = b.job_id inner join #jobinfo j on a.job_id = j.job_id where b.start_execution_date isnot null and b.stop_execution_date isnull
2.2. SQL Server 2000沿用过来的方法
在SQL Server 2000时,没有sysjobactivity这个系统表,通常借助sysprocesses监视作业的当前运行状态及时长。
select j.name, p.status ascurrent_execution_status, p.last_batchas start_execution_date, ISNULL(DATEDIFF(MI, p.last_batch, GETDATE()), 0) asjob_duration_minute from msdb.dbo.sysjobs j, master..sysprocesses p where p.program_name like 'SQLAgent - TSQL JobStep(Job%' and substring((cast(j.job_id as varchar(36))),7,2) + substring((cast(j.job_id as varchar(36))),5,2) + substring((cast(j.job_id as varchar(36))),3,2) + substring((cast(j.job_id as varchar(36))),1,2) + substring((cast(j.job_id as varchar(36))),12,2) + substring((cast(j.job_id as varchar(36))),10,2) + substring((cast(j.job_id as varchar(36))),17,2) + substring((cast(j.job_id as varchar(36))),15,2) + substring((cast(j.job_id as varchar(36))),20,4) + substring((cast(j.job_id as varchar(36))),25,12) = substring((cast(p.program_name as varchar(75))),32,32)
sysprocesses里获得的作业编号跟sysjobs里是不一致的,所以上面进行了转换,通常只转换job_id的前8位字符也行,如下脚本做了job_id的简化转换,并检查作业已运行超过30分钟:
declare @MaxMinutes int set @MaxMinutes = 30 select j.name, p.status ascurrent_execution_status, p.last_batchas start_execution_date, ISNULL(DATEDIFF(MI, p.last_batch, GETDATE()), 0) asjob_duration_minute from msdb..sysjobs j inner join master..sysprocesses p on substring(left(cast(j.job_id as varchar(36)),8),7,2) + substring(left(cast(j.job_id as varchar(36)),8),5,2) + substring(left(cast(j.job_id as varchar(36)),8),3,2) + substring(left(cast(j.job_id as varchar(36)),8),1,2) = substring(p.program_name,32,8) where p.program_name like 'SQLAgent - TSQL JobStep(Job%' and ISNULL(DATEDIFF(MI, p.last_batch, GETDATE()), 0) > @MaxMinutes
还有种比较笨的方法,在要监视的所有作业中增加一个步骤,如 : select GETDATE() 放在第一步,这样在sysjobhistory中就会有步骤1的运行纪录了,以此为起点,可以计算已运行时长。如果有很多已经部署的job,这确实不是个好办法。
又或者,在每个作业最后一步,放一个检查的步骤,这样所有状态时长全都监视到了,问题是如果作业运行时间过长,最后的检查步骤根本无法被运行到。
三. 作业状态告警
作业在完成后,自己有状态检查和告警机制,通常选择邮件告警,如下图:
650) this.width=650;" alt="" style="max-width:90%" />
但这仅限对作业最终运行状态监视:
(1) 没有运行结束的作业无法告警,或者说对作业的运行时长没有监视;
(2) 如果作业在某个中间步骤设置了:失败后继续下一步,后续的作业步骤都成功,那么作业最终状态不会显示会失败,不会触发告警,如下脚本检查每个作业的所有步骤最后一次运行状态:
if OBJECT_ID('tempdb..#tmp_job_step') is not null drop table #tmp_job_step select jh1.job_id, jh1.step_id, jh1.run_status, CONVERT(varchar(20),jh1.run_date) run_date, CONVERT(varchar(20),jh1.run_time) run_time, CONVERT(varchar(20),jh1.run_duration) run_duration into #tmp_job_step from msdb.dbo.sysjobhistoryjh1 where (select COUNT(1) from msdb.dbo.sysjobhistoryjh2 where (jh1.job_id = jh2.job_id and jh1.step_id = jh2.step_id) and(jh1.instance_id <=jh2.instance_id))=1 select a.namejob_name, s.step_name, case b.run_status when 0 then 'Failed' when 1 then 'Succeeded' when 2 then 'Retry' when 3 then 'Canceled' else 'Unknown' end as job_status, LEFT(run_date,4)+'-'+SUBSTRING(run_date,5,2)+'-'+RIGHT(run_date,2) +SPACE(1) +LEFT(RIGHT(1000000+run_time,6),2)+':' +SUBSTRING(RIGHT(1000000+run_time,6),3,2)+':' +RIGHT(RIGHT(1000000+run_time,6),2) as job_started_time, +LEFT(RIGHT(1000000+run_duration,6),2)+':' +SUBSTRING(RIGHT(1000000+run_duration,6),3,2)+':' +RIGHT(RIGHT(1000000+run_duration,6),2) as job_duration from msdb.dbo.sysjobs a left join #tmp_job_stepb on a.job_id=b.job_id inner join msdb.dbo.sysjobsteps s on b.job_id = s.job_id and b.step_id = s.step_id where a.name not in('syspolicy_purge_history') and a.enabled = 1 order by b.run_status asc,a.name,b.run_duration desc
小结
SQL Server Agent作业自身的告警机制,有时并不够用,所以还需要部署另外的作业,来检查其他所有作业的运行状况,大致步骤如下 :
(1) 部署数据库邮件;
(2) 部署作业:定时检查其他所有作业/步骤状态,发邮件告警;
作业运行时长可以在这一并检查,有时一些作业运行了很多天没结束还没人知道,也可以考虑放在性能监控里,和其他数据库请求一起监控。但是对于时长,通常需要有个性能基线,如果没有的话直接和历史最大值相比也是不错的选择。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le mappage polymorphe Hibernate peut mapper les classes héritées à la base de données et fournit les types de mappage suivants : join-subclass : crée une table séparée pour la sous-classe, incluant toutes les colonnes de la classe parent. table par classe : créez une table distincte pour les sous-classes, contenant uniquement des colonnes spécifiques aux sous-classes. union-subclass : similaire à join-subclass, mais la table de classe parent réunit toutes les colonnes de la sous-classe.

Les dernières versions d'Apple des systèmes iOS18, iPadOS18 et macOS Sequoia ont ajouté une fonctionnalité importante à l'application Photos, conçue pour aider les utilisateurs à récupérer facilement des photos et des vidéos perdues ou endommagées pour diverses raisons. La nouvelle fonctionnalité introduit un album appelé "Récupéré" dans la section Outils de l'application Photos qui apparaîtra automatiquement lorsqu'un utilisateur a des photos ou des vidéos sur son appareil qui ne font pas partie de sa photothèque. L'émergence de l'album « Récupéré » offre une solution aux photos et vidéos perdues en raison d'une corruption de la base de données, d'une application d'appareil photo qui n'enregistre pas correctement dans la photothèque ou d'une application tierce gérant la photothèque. Les utilisateurs n'ont besoin que de quelques étapes simples

Pour gérer les erreurs de connexion à la base de données en PHP, vous pouvez utiliser les étapes suivantes : Utilisez mysqli_connect_errno() pour obtenir le code d'erreur. Utilisez mysqli_connect_error() pour obtenir le message d'erreur. En capturant et en enregistrant ces messages d'erreur, les problèmes de connexion à la base de données peuvent être facilement identifiés et résolus, garantissant ainsi le bon fonctionnement de votre application.

Comment utiliser MySQLi pour établir une connexion à une base de données en PHP : Inclure l'extension MySQLi (require_once) Créer une fonction de connexion (functionconnect_to_db) Appeler la fonction de connexion ($conn=connect_to_db()) Exécuter une requête ($result=$conn->query()) Fermer connexion ( $conn->close())

Grâce au package base de données/sql de la bibliothèque standard Go, vous pouvez vous connecter à des bases de données distantes telles que MySQL, PostgreSQL ou SQLite : créez une chaîne de connexion contenant les informations de connexion à la base de données. Utilisez la fonction sql.Open() pour ouvrir une connexion à la base de données. Effectuez des opérations de base de données telles que des requêtes SQL et des opérations d'insertion. Utilisez defer pour fermer la connexion à la base de données afin de libérer des ressources.

L'utilisation de la fonction de rappel de base de données dans Golang peut permettre : d'exécuter du code personnalisé une fois l'opération de base de données spécifiée terminée. Ajoutez un comportement personnalisé via des fonctions distinctes sans écrire de code supplémentaire. Des fonctions de rappel sont disponibles pour les opérations d'insertion, de mise à jour, de suppression et de requête. Vous devez utiliser la fonction sql.Exec, sql.QueryRow ou sql.Query pour utiliser la fonction de rappel.

Utilisez la bibliothèque DataAccessObjects (DAO) en C++ pour connecter et exploiter la base de données, notamment en établissant des connexions à la base de données, en exécutant des requêtes SQL, en insérant de nouveaux enregistrements et en mettant à jour les enregistrements existants. Les étapes spécifiques sont : 1. Inclure les instructions de bibliothèque nécessaires ; 2. Ouvrir le fichier de base de données ; 3. Créer un objet Recordset pour exécuter des requêtes SQL ou manipuler des données ; 4. Parcourez les résultats ou mettez à jour les enregistrements en fonction de besoins spécifiques.

Guide de connexion à la base de données PHP : MySQL : Installez l'extension MySQLi et créez une connexion (nom du serveur, nom d'utilisateur, mot de passe, nom de base de données). PostgreSQL : installez l'extension PgSQL et créez une connexion (hôte, nom de base de données, utilisateur, mot de passe). Oracle : Installez l'extension OracleOCI8 et créez une connexion (nom du serveur, nom d'utilisateur, mot de passe). Cas pratique : Obtenir des données MySQL, requête PostgreSQL, enregistrement de mise à jour OracleOCI8.
