zoukankan      html  css  js  c++  java
  • SQL Server 幽灵数据删除

    从表中删除数据,或导致行移动的更新操作,通常会把数据从表中就地删除,并释放行所占用的存储空间,但是在某些情况下,该行实际上可以作为幽灵数据保留在数据页上。一行数据从索引页面的叶级别删除,并不总是实时从数据页中物理删除,而是把该记录标记为已删除,这个记录称作幽灵(ghost)记录。这意味着该行数据仍然保留在数据页中,但是行的内部存储结构中发生了变化,把该行标记为已删除(ghost)。

    SQL Server内置了一个ghost cleanup进程,这是一个单线程的后台进程,用于删除被标记为已删除的幽灵数据。从SQL Server 2012版本之后,ghost cleanup进程每个5秒钟自动运行,检查数据页上是否存在标记为幽灵记录的数据行,如果找到幽灵数据,那么ghost cleanup进程会把它们从物理存储上删除,ghost cleanup每次执行都会至多检查10个Page。

    清除幽灵数据的优点是显而易见的,

    • 释放存储空间,并把重新使用这部分空间存储更多的数据,避免数据文件的暴增
    • 能够一定程度上避免索引页的拆分(Page Split),由于Page存在部分未使用的空间,新的数据会直接使用这部分free space。

    当一个记录被发现时,数据库就被标记为“有幽灵数据”,一旦删除所有的幽灵数据之后,数据库就会被标记为“没有幽灵数据”,ghost cleanup进程会跳过被标记为“没有幽灵数据”的数据库。

    查询索引中的幽灵数据的数量

    用户可以通过dm_db_index_physical_stats来统计各个索引中包含的幽灵数据行的数量:

    select db_name(database_id) as ghosted_database_name
        ,object_name(p.object_id) as table_name
        ,i.name as index_name
        ,sum(ghost_record_count) total_ghost_records
    from sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, 'SAMPLED') p
    inner join sys.indexes i
        on p.object_id=i.object_id
            and p.index_id=i.index_id
    group by p.database_id
        ,p.object_id
        ,i.name
    order by total_ghost_records desc

    从数据库文件中清除幽灵数据

    用户可以手动SP来清除幽灵数据:

    sys.sp_clean_db_file_free_space   
      [ @dbname = ] 'database_name'   
      , [ @fileid = ] 'file_number'   
      [ , [ @cleaning_delay = ] 'delay_in_seconds' ] [;]  
    
    sys.sp_clean_db_free_space   
      [ @dbname = ] 'database_name'   
      [ , [ @cleaning_delay = ] 'delay_in_seconds' ] [;] 

    参考文档:

    Ghost cleanup process guide

  • 相关阅读:
    Jzoj5542 董先生的钦点
    Jzoj5542 董先生的钦点
    (各种)FFT模板
    (各种)FFT模板
    Jzoj3528 图书馆
    Jzoj3528 图书馆
    Jzoj5317 Func
    Jzoj5317 Func
    Jzoj3591 数据
    【UVa11021】Tribles
  • 原文地址:https://www.cnblogs.com/ljhdo/p/13254434.html
Copyright © 2011-2022 走看看