zoukankan      html  css  js  c++  java
  • 发布订阅清理distribution未执行导致distribution库特别大处理办法

    近期发现数据服务器中数据库所在盘被占用的特别严重,一个800G的盘只剩下不到100G,排除备份所占用的其他的空间竟然有400G被安装目录下的分发数据库distribution.MDF所占用。

    分发数据库distribution.MDF因为SQL代理“ 分发清除: distribution”停止了导致分发数据库的数据一直不能被清除。

    问题找到了下面就是如何把分发数据库中数据给清除了。

    先看一下清理前惨状

    查询占用情况的SQL(这段SQL是从网上查到的,忘从哪复制的,感谢广大的DBA)

    use distribution;
    GO
    select top 10 a.tablename,a.SCHEMANAME,sum(a.TotalSpaceMB) TotalSpaceMB,sum(a.RowCounts) RowCounts
    from (
    SELECT
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB,
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB,
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
    FROM
    sys.tables t
    INNER JOIN
    sys.indexes i ON t.OBJECT_ID = i.object_id
    INNER JOIN
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
    INNER JOIN
    sys.allocation_units a ON p.partition_id = a.container_id
    LEFT OUTER JOIN
    sys.schemas s ON t.schema_id = s.schema_id
    GROUP BY
    t.Name, s.Name, p.Rows) a
    GROUP BY a.tablename,a.SCHEMANAME
    order by sum(a.TotalSpaceMB) desc
    View Code

    可见上图中的总行数,达到了惊人的7亿条,占用空间400G

    接下来就是如何清理了

    方案1:执行EXEC dbo.sp_MSdistribution_cleanup @min_distretention = 0, @max_distretention = 72,结果等了2个小时无任何效果(这种情况下就比较数据量少的情况)无奈放弃

    方案2:通过Delete Top(500000) MSrepl_commands 与MSrepl_transactions 每次删除50万条数据,这个方案是有效果,但是分发数据库的日志也会不断增大,果断放弃了

    方案3(最终成功的方案):通过TRUNCATE TABLE语句实现数据删除,这个也是最终成功的方案

    在执行TRUNCATE TABLE MSrepl_commands 与TRUNCATE TABLE MSrepl_transactions前为了不让其他进程占用分发数据库可以通过”查看日志读取器代理状态“先停止日志往MSrepl_commands 的写入

    需要说明的是在MSrepl_transactions有3千万条数据执行时间不到1秒

    MSrepl_commands 表因为数据量大太执行的时间达到5分钟之多,强调如果数据量大要耐心等待。

    到了此时我以为已经万事大吉了,但是想多了,真正完成还需要继续完成下面的步骤

    首先我发现空间没有减少,什么原因呢:分发数据库没有回收,  执行完TRUNCATE后一定要回收一下数据库,通过命令或菜单操作均可。

    其次在订阅服务器中发现查看同步状态不能启动代理,会提示:进程无法在“CRM-XXX”上执行“sp_repldone/sp_replcounters”

    可以执行  EXEC sp_repldone @xactid =NULL, @xact_segno =NULL, @numtrans = 0, @time =0, @reset =1; EXEC sp_replflush然后重启一下SQL服务

    如果发现还会有错误提示,如订阅服务器提示数据不一致查询不到等问题可以重新发布一下,在订阅中重新初始化

    具体操作:在本地发布中找到发布的事务,右击选择”重新初始化所有订阅“,完成重新发布订阅

    到这里就完成了分发服务器中表MSrepl_commands和表MSrepl_transactions的清理工作。

    但是订阅服务器重新初始化后会发现非聚集索引不见了,我是这样解决的,先在分发库中找到所有自定义的索引,然后再订阅数据中执行一遍

    查询所有自定义索引的SQL如下,因为我建的索引都是以index开头的,其他有需要可以自己修改一下

    SELECT idx.name 索引名称,obj.name 表名,col.name 索引字段名
    ,'create index '+idx.name +' on '+obj.name +'('+col.name +')'+';' 创建索引语句
    FROM sysindexes idx 
    JOIN sysindexkeys idxkey ON idx.id=idxkey.id AND idx.indid=idxkey.indid 
    JOIN sysobjects obj ON idxkey.id=obj.id 
    JOIN syscolumns col ON idxkey.id=col.id AND idxkey.colid=col.colid 
    WHERE idx.indid NOT IN(0,255) AND idx.name LIKE 'index%' AND obj.xtype='U'
    --AND obj.name='sms_saleorder' --查指定表 
    ORDER BY obj.name,idx.name,col.name

    以上是我遇到的问题及解决方法,记录一下,如果有类似情况的朋友可以参考,希望帮到您

  • 相关阅读:
    用mvc实现增删查改
    hibernate Annotation版本的helloworld
    hibernate 级联操作
    Hibrenate一对一外键关联
    hibernate主键生成
    Action属性接收参数
    WildCard的使用
    Struts 路径分析以及是否一定要执行excute()方法
    学习Struts2经验总结
    基于Struts分层web框架,研究传值问题
  • 原文地址:https://www.cnblogs.com/manage/p/14515120.html
Copyright © 2011-2022 走看看