You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/relational-databases/ghost-record-cleanup-process-guide.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,34 +20,34 @@ The ghost cleanup process is a single-threaded background process that deletes r
20
20
21
21
## Ghost records
22
22
23
-
Records that are deleted from the leaf level of an index page aren't physically removed from the page. Instead, the record is marked as 'to be deleted', or *ghosted*. This means that the row stays on the page but a bit is changed in the row header to indicate that the row is a ghost. This is to optimize performance during a delete operation. Ghosts are necessary for row-level locking, but are also necessary for snapshot isolation where the database engine must maintain older row versions.
23
+
Records that are deleted from the leaf level pages of an index aren't physically removed from the page. Instead, the record is marked as 'to be deleted', or *ghosted*. This means that the row stays on the page but a bit is changed in the row header to indicate that the row is a ghost. This is to optimize performance during a delete operation. Ghosts are necessary for row-level locking, but are also necessary for snapshot isolation transactions where the database engine must maintain older row versions.
24
24
25
25
## Ghost record cleanup task
26
26
27
-
Records that are marked for deletion, or *ghosted*, are cleaned up by the background ghost cleanup process when they are no longer required. This background process runs after the delete transaction is committed and all row versions are no longer required, and physically removes ghosted records from pages. The ghost cleanup process runs periodically and checks to see if any pages have ghost records. If it finds any, it physically removes the records that are marked for deletion, or *ghosted*, touching at most 10 pages with each execution.
27
+
Records that are marked for deletion, or *ghosted*, are cleaned up by the background ghost cleanup process when they are no longer required. The ghost cleanup process runs periodically and checks to see if any pages have ghost records. If it finds any, it physically removes the records that are marked for deletion, or *ghosted*.
28
28
29
-
When a record is ghosted, the database is marked as having ghosted entries, and the ghost cleanup process only scans such databases. The ghost cleanup process also marks the database as having no ghosted records once all ghosted records have been removed, and skips this database the next time it runs. The process also skips any database if it can't acquire a shared lock on on the database. It retries acquiring the lock the next time it runs.
29
+
When a record is ghosted, the database is marked as having ghosted entries. The ghost cleanup process only scans such databases. The ghost cleanup process also marks the database as having no ghosted records once all ghosted records have been removed, and skips this database the next time it runs. The process also skips any database if it can't acquire a shared lock on the database. It retries lock acquisition on the database the next time it runs.
30
30
31
-
The below query returns an approximate number of ghosted records in a database.
31
+
The follwoing query returns an approximate number of ghosted records in a database.
32
32
33
-
```sql
33
+
```sql
34
34
SELECTSUM(ghost_record_count) AS total_ghost_records,
In rare cases in high-load systems with many deletes, the ghost cleanup process can cause a performance issue because it can replace the frequently accessed pages in the buffer pool with pages that have ghosted records, and generate extra IO load. If this occurs, you can temporarily disable this process with the use of[trace flag 661](../t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql.md#tf661).
43
+
In high-load systems with many deletes, the ghost cleanup process might cause a performance issue because it replaces the frequently accessed pages in the buffer pool with pages that have ghosted records. As a result, the frequently accessed pages must be re-read from disk, generating extra disk IO and increasing query latency. If this occurs, you can disable ghost cleanup using[trace flag 661](../t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql.md#tf661).
44
44
45
-
Disabling ghost cleanup permanently is not recommended. Without ghost cleanup, your database can grow unnecessarily large, which can lead to performance issues. Since the ghost cleanup process removes records that are marked as ghosts, disabling the process leaves these records on the page, preventing the database engine from reusing this space. This forces the database engine to add data to new pages instead, leading to bloated database files, and can also cause [page splits](indexes/specify-fill-factor-for-an-index.md). Page splits lead increase disk IO which can reduce query performance.
45
+
Without ghost cleanup, your database can grow unnecessarily large, which can lead to performance issues. Since the ghost cleanup process removes records that are marked as ghosts, disabling the process leaves these records on the page, preventing the database engine from reusing this space. This forces the database engine to add data to new pages instead, leading to bloated database files, and can also cause [page splits](indexes/specify-fill-factor-for-an-index.md). Page splits increase disk IO which can reduce query performance.
46
46
47
-
Once the ghost cleanup process is disabled, some action needs to be taken to remove the ghosted records. For example, you can rebuild indexes, which creates new pages from existing data, omitting ghosted records.
47
+
If ghost cleanup is disabled, the only action that removes the ghosted records is an index rebuild. Rebuilding an index creates new pages from existing data, omitting ghosted records in the process.
48
48
49
-
> [!WARNING]
50
-
> Disabling the ghost cleanup process is not recommended.
49
+
> [!WARNING]
50
+
> Disabling the ghost cleanup process permanently is not recommended.
@@ -48,15 +48,15 @@ The data file ID to clean. *@fileid* is **int**, with no default.
48
48
49
49
#### [ @cleaning_delay = ]*cleaning_delay*
50
50
51
-
Specifies an interval to delay between the cleaning of pages. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system.
51
+
Specifies an interval to delay before the cleanup of each page, in seconds. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system at the expense of increasing the duration of the cleanup process.
52
52
53
53
## Return code values
54
54
55
55
`0` (success) or `1` (failure).
56
56
57
57
## Remarks
58
58
59
-
The `sp_clean_db_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page and then zero-initializes the remainder of the space on the page. In environments where the physical security of the data files is at risk, you can use this stored procedure to ensure that no residual deleted data remain in the data files.
59
+
The `sp_clean_db_file_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page, and then zero-initializes the remainder of the data space on the page. In environments where the physical security of the data files or the underlying storage is at risk, you can use this stored procedure to ensure that no residual deleted data remains in the data files or in storage.
60
60
61
61
The time required to run `sp_clean_db_file_free_space` depends on the size of the data file, the number of used pages in the file, and the I/O capabilities of the disk. Because running `sp_clean_db_file_free_space` can significantly increase I/O activity, we recommend that you run this procedure outside the usual operation hours.
@@ -43,15 +43,15 @@ The name of the database to clean. *@dbname* is **sysname**, with no default.
43
43
44
44
#### [ @cleaning_delay = ]*cleaning_delay*
45
45
46
-
Specifies an interval to delay between the cleaning of pages. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system.
46
+
Specifies an interval to delay before the cleanup of each page, in seconds. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system at the expense of increasing the duration of the cleanup process.
47
47
48
48
## Return code values
49
49
50
50
`0` (success) or `1` (failure).
51
51
52
52
## Remarks
53
53
54
-
The `sp_clean_db_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page and then zero-initializes the remainder of the space on the page. In environments where the physical security of the data files is at risk, you can use this stored procedure to ensure that no residual deleted data remain in the data files.
54
+
The `sp_clean_db_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page, and then zero-initializes the remainder of the data space on the page. In environments where the physical security of the data files or the underlying storage is at risk, you can use this stored procedure to ensure that no residual deleted data remains in the data files or in storage.
55
55
56
56
The time required to run `sp_clean_db_free_space` depends on the size of the data files, the number of used pages in the files, and the I/O capabilities of the disk. Because running `sp_clean_db_free_space` can significantly increase I/O activity, we recommend that you run this procedure outside the usual operation hours.
0 commit comments