Checking Last Good DBCC CHECKDB Time With LastGoodCheckDbTime

When did this database last pass its integrity check? LastGoodCheckDbTime provides a useful metadata starting point on supported recent builds. Compare the returned value with the actual check records before treating it as proof that the current integrity process is working.

A railway worker seen from behind tapping a goods wagon wheel with a long hammer to listen to it

Ask About the Database Rather Than the Schedule

A scheduled DBCC CHECKDB job tells you what should happen. Its enabled state does not prove the latest run succeeded or covered every intended database. A metadata timestamp and retained job output provide different evidence about that responsibility.

I start with the database's last known successful check information, then follow it to the operating record. A stale value can reveal a broken schedule, an omitted database, or a deliberate strategy that checks restored copies elsewhere. Those possibilities need different conclusions.

DATABASEPROPERTYEX supports LastGoodCheckDbTime on relevant recent SQL Server builds. Verify support through the actual returned value and your build documentation rather than guessing its introduction version. An unsupported property can return NULL, so unavailable metadata must not be labeled automatically as a confirmed never-checked database. The calendar is useful, but it does not execute CHECKDB when nobody is looking.

Query LastGoodCheckDbTime Across Online Databases

The next query selects online user databases and converts the property to datetime2. It reports both the value and a classification using a configurable age threshold. The demonstration uses seven days as the review policy, not as a universal integrity requirement.

The sentinel or unavailable category handles NULL and an old baseline date without inventing a check that did not occur. Keep that category distinct from stale known values. Review offline databases separately because the inspection's scope deliberately excludes them.

I keep the database name and state beside the result. Metadata visibility and database availability affect what can be inspected. Also keep the server's time convention clear when comparing stored values with GETDATE. Do not relabel a value as UTC merely because an export tool prefers that label. A consistent clock interpretation makes the age classification reproducible and prevents a timezone display from becoming a false warning.

DECLARE @MaximumAgeDays int=7;
WITH Checks AS
(
 SELECT name,state_desc,
 TRY_CONVERT(datetime2,DATABASEPROPERTYEX(name,'LastGoodCheckDbTime')) AS LastGoodTime
 FROM sys.databases WHERE database_id>4 AND state_desc='ONLINE'
)
SELECT name,state_desc,LastGoodTime,
 CASE WHEN LastGoodTime IS NULL OR LastGoodTime<='19000101' THEN 'Unavailable or no recorded good check'
 WHEN LastGoodTime<DATEADD(day,-@MaximumAgeDays,GETDATE()) THEN 'Older than policy'
 ELSE 'Within policy' END AS CheckStatus
FROM Checks ORDER BY LastGoodTime,name;

Run and Retain the Actual Integrity Check

When the operating process calls for a new check, run DBCC CHECKDB through the approved maintenance window and retain its output. The next statement checks the current database, so verify the SSMS database context first. NO_INFOMSGS suppresses informational messages but does not hide errors.

CHECKDB consumes resources and can use an internal snapshot. Plan the work according to database size, storage, and workload. Do not trigger a heavyweight production check simply because a dashboard row looks old without first reviewing the existing integrity process.

What exactly did the scheduled check run? Preserve its command, options, database, server, completion status, and error output. The timestamp alone does not describe all of those details. A record that the job launched is different from a record that the integrity check completed successfully. Read back the property after a clean supported execution, but keep the full execution evidence as the more complete operating record.

DBCC CHECKDB WITH NO_INFOMSGS;
SELECT DB_NAME() AS DatabaseName,
       DATABASEPROPERTYEX(DB_NAME(),'LastGoodCheckDbTime') AS LastGoodCheckTime;
From a timestamp to integrity evidence: a diagram about the LastGoodCheckDbTime

Compare LastGoodCheckDbTime With the Older DBINFO Output

Older administrative approaches inspect DBCC DBINFO WITH TABLERESULTS and look for the internal last-known-good CHECKDB field. That can help compare historical scripts with the modern property-based inventory. The command exposes internal metadata, so do not build a fragile cross-version monitoring contract around its output shape.

The next command displays that older result in the current database. Inspect the actual field labels returned by the build rather than assuming fixed row positions or a permanent undocumented schema. Avoid modifying internal values. This is an inspection comparison only.

Prefer the supported property surface when available and retain the check job's evidence in either case. A legacy script that worked on an old server deserves inspection before replacement, but its internal output is not a guarantee for every new build. Keep the comparison narrow enough to answer whether the two sources describe the same recorded check context.

DBCC DBINFO WITH TABLERESULTS;

Account for Checks Performed on Restored Copies

Some environments restore backups elsewhere and run integrity checks on those copies. That can be a deliberate process, but the original source database's property is not updated by a CHECKDB run against another database on another server. The source timestamp alone will not describe that external operating evidence.

Record the restored backup, source database, restore location, check command, and successful result in the integrity log. Make the monitoring rule aware of that approved process rather than repeatedly declaring the source unchecked because its local property is old.

Restored databases can also carry metadata from the backup, so a nonempty property in a restored copy is not proof that a fresh post-restore check just ran. Confirm the actual execution record. The distinction matters when recovery testing and integrity testing are reviewed together. Keep database-local metadata, inherited backup metadata, and new check evidence clearly identified instead of collapsing them into one unexplained green indicator.

Turn Stale Results Into a Concrete Review

For each stale or unavailable result, identify whether the property is supported, whether the database was in scope, and where the approved check process runs. Then inspect failures, missed schedules, or missing evidence. Do not assume the cause from the timestamp alone.

Set the age threshold according to the database's operating policy and recovery needs. A fixed seven-day demonstration rule is not automatically appropriate for every workload. Keep exceptions documented and reviewed rather than hiding them in a filter.

LastGoodCheckDbTime is useful when it points to a complete integrity record. Read the property, interpret unavailable values carefully, and verify the actual successful check and its location. The goal is confidence in the integrity process, with enough evidence to explain when and how each database was validated.

Related reading on this blog: Splitting DBCC CHECKDB Across the Week for a Large Database and 5 Don'ts When Database Corruption is Detected.

What the timestamp tells you: a checklist on the LastGoodCheckDbTime

A check timestamp is not a complete integrity record, it is metadata that needs its execution context.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

Database Corruption, DBA, SQL Scripts, SQL Server DBCC
Previous Post
SQL SERVER – Fix Error – Cannot execute as the database principal because the principal “dbo” does not exist
Next Post
SQL SERVER – Last Used Stored Procedure

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.