微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – ALTER INDEX ALL REBUILD是否使用简单恢复模型的事务日志空间多于单独重建每个索引?

sql Server 2012上的“ALTER INDEX ALL REBUILD”操作失败,因为事务日志空间不足.索引从未被重组或重建,因此几乎所有索引的碎片都超过80%.

DB使用简单的恢复模型.我假设在命令的“ALL”形式执行每个索引操作之后,将在下一个索引重建之前刷新事务日志数据.它是如何实际工作的,还是将索引重建记录为好像它们是单个事务的一部分?

换句话说,我可以通过编写脚本来单独执行每次重建来减少事务日志增长吗?还有其他因素需要考虑吗?

解决方法

I assumed that following each index operation performed by the “ALL” form of the command,the transaction log data would be flushed prior to the next index rebuild. Is that how it actually works,or are the index rebuilds logged as if they are part of a single transaction?

1)日志刷新:SIMPLE恢复模型不会在每次事务后清除日志,而是在检查点. (link更多信息)

2a)REBUILD ALL:是的,REBUILD ALL作为单笔交易工作.内部的索引重建有自己的事务,但整个操作直到最后才完全提交.所以,是的,您可以通过重建单个索引(并可能发出CHECKPOINT命令)来限制日志文件的增长.

2b)证明!在这里,有一个演示脚本. (建于2016年开发)
首先,使用表和索引设置测试数据库

USE master
GO

CREATE DATABASE Test_RebuildLog
GO

ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO

USE Test_RebuildLog
GO

CREATE TABLE IndexTest
(ID int identity(1,1),a char(1),b char(1))

CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)

INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')

现在,您可以比较REBUILD ALL和单独重建之间的日志活动

CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

请注意,在REBUILD ALL结束之前,第一个打开的事务(事务ID 0000:000002fa)是如何提交的,但是对于逐个索引的重建,它们是连续提交的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐