如何为你的数据库事务日志减肥?

Posted syncnavigator

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何为你的数据库事务日志减肥?相关的知识,希望对你有一定的参考价值。

在大多数SQL Server的工作环境中,尤其是在OLTP环境中,数据库的事务日志性能出现瓶颈时往往会导致事务完成需要更多的时间,此时许多人把原因都归结于I/O子系统,理由是它不能够支撑工作负载产生的的大量的事务日志,然而实际情况却都未必如此。

技术分享图片

事务日志写等待时间

对 于事务日志来讲,写操作等待的时间可以使用sys.dm_id_virtual_file_stats和系统中的事件writelog等待进行监视。如果 写等待时间比你期望的I/O子系统较高,那麽I/O子系统就不能够支撑,这是一般的假设,但不意味着需要升级你的I/O子系统。

在许多系统你是你会发现有相当比例的多余的日志记录的产生,如果能够减少这些不需要的日志记录,相应的也就减少了写入磁盘的事务日志的数量,也相应的转化为写等待时间的减少,因此也就减少了事务完成的时间。

引起多余日志记录的产生有两个主要的原因:

未被使用的nonclustered indexes

索引碎片的增多

未被使用的索引

无 论在任何时候向表中插入记录时,同时也会在该表上定义的每一个noncluster index插入一条记录(注意,filetered index有可能会例外 ),这就意味着多余的日志记录的产生;在表中删除记录也是同样的,在noncluster index相应的记录也必须被删除,而更新数据也会同样的对noncluster index中的记录进行修改。要保持每一个noncluster index和相关的表之间的正确关系(真实反映),这些操作是必要的,但是如果noncluster index在查询计划中未必使用,但为维护他们所产生的操作和日志记录也会是多余的费用,随着noncluster index碎片的增长,就需要定期的对他们进行维护,维护同样也会产生更多的日志记录也是完全不需要的。

未被 使用的索引有可能是你错误的在表上创建了一个索引,或者是按照SQL Server的丢失索引的DMV的建议创建的,或者是按照数据库的优化顾问创建的,也有可能是业务的改变导致原先使用的索引不再被使用。

无论如何,这些未被使用的索引都应该被清除以便减少负荷,首先要确定哪些索引是未被使用过的,可以通过sys.dm_db_index_usage_stats这个DMV来查看。

索引碎片

在许多人看来,索引碎片会导致要求读取更多的数据页,实际上索引碎片也会导致多余日志记录的产生而原因就在于产生碎片的原因。

碎片是由于页拆分page split这种现象的发生而导致的,简单的解释就是当插入记录而空间不足导致了页拆分,这种过程是这样子的:

一个新的索引被分配和格式化

从装满数据的页中移出一半的记录到新页

新页链接到索引结构中

新的记录被插入到页面中

这些所有的操作都会产生日志记录,你可以想象的到,要远比你插入一条记录所产生的日志记录要多。

减 少额外耗费的第一步就是清除未被使用的索引,目的就是杜绝其再产生页拆分,所以要找出那些被分割成碎片的索引,第二步决定使用哪种碎片整理方法的是分析索 引以确定碎片程度。通过使用系统函数 sys.dm_db_index_physical_stats,您可以检测特定索引、表或索引视图的所有索引、数据库中所有索引或所有数据库中所有索引 中的碎片。对于已分区索引,sys.dm_db_index_physical_stats 还提供每个分区的碎片信息。SQL Server 2005 中计算碎片的算法比 SQL Server 2000 中的算法更精确。因此,碎片值显得更高。例如,在 SQL Server 2000 中,如果某表的页 11 和页 13 在同一区,而页 12 不在该区,则不会将该表视为碎片。但若要访问这两页,却需要两个物理 I/O 操作,因此在 SQL Server 2005 中,此表被计为碎片。使用索引填充因子重建或重新组织索引,以便在索引中保留部分空的空间为后续插入的记录使用,这样就减少了页拆分现象的发生,因而也就 减少了额外的日志记录的产生。(请参考另一篇文章:发现那些未被使用的数据库索引)

当 然,天下没有免费的午餐,任何对一方有利的东西对另一方可能就会有害。当使用填充因子fillfactors时会降低页面密度,过低的页面密度同样也会带 来一些性能问题,当然过高会带来页拆分,所以这是一个需要权衡的问题,具体要参考你的环境,比如说是OLTP还是OLAP等。

总结

减少事务日志的写等待时间不总是要升级你的I/O子系统,在数据库中使用简单的索引分析,就能显著的减少大量的事务日志记录的产生,也就同样的减少写等待时间。

当然,这仅仅是影响事务日志性能的一个方面,只有对事务日志的机制有更深入的了解,你才会发现,和事务日志性能方面的问题的更多方面。

关于作者

姜传华,长期从事数据库的教学、设计、开发和应用管理工作,有着20年以上的IT工作经历,深刻理解关系数据库原理及SQL Server体系架构。同时也活跃于Microsoft的各大论坛网站。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

以上是关于如何为你的数据库事务日志减肥?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理SQL Server事务复制中的大事务操作

sql server 2000中,如何查询事务日志?事务日志有啥作用?

如何为事务管理编写自定义过滤器

如何为多个并发事务请求正确处理 JPA ObjectOptimisticLockException?

数据库 之 事务控制和隔离级别

SqlServer 复制中将大事务分成小事务分发