The MSDN ALTER INDEX page says "An index cannot be reorganized when ALLOW_PAGE_LOCKS is set to OFF."
I'm modifying our index reorg/rebuild process to be sensitive to indexes that have ALLOW_PAGE_LOCKS
turned OFF
. When I detect the index has the option turned off, I perform the following steps:
BEGIN TRANSACTION
BEGIN TRY
ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = ON);
ALTER INDEX [MyIndex] ON [dbo].[MyTable] REBUILD
WITH (
SORT_IN_TEMPDB = ON
, MAXDOP = 1
, PAD_INDEX = OFF
, FILLFACTOR = 90
, ALLOW_PAGE_LOCKS = OFF
, ALLOW_ROW_LOCKS = ON
, IGNORE_DUP_KEY = OFF
, DATA_COMPRESSION = NONE
);
ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = OFF);
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
Presuming the database is not actually "in-use" at the time this rebuild process starts, does this pattern present any issues? Does setting PAGE LOCKS ON
cause any side-effects?
Note – the options, such as FILLFACTOR = 90
are taken from the current definition of the index just prior to starting the reorg/rebuild process, and a decision is made whether to reorg or rebuild based on the number of pages in the index and the degree of fragmentation. This question is NOT about these settings being "good" or "bad", it is ONLY about the impact of temporarily turning ALLOW_PAGE_LOCKS
to `ON', to allow the index to be defragmented.
Also, I realize the ALTER INDEX ... REBUILD
statement has ALLOW_PAGE_LOCKS = OFF
, while the very next statement also turns it off… this is to allow the ALTER INDEX ... REORG
statement, which does not have any options present, to run properly, while also resetting the ALLOW_PAGE_LOCKS
setting off once it's completed.
I've wrapped the alter index statements in a transaction for only the indexes that have ALLOW_PAGE_LOCKS OFF
so that if anything goes wrong during the rebuild process the index is not modified.
Also, note, we are not using Ola Hallengren's solution due to corporate policy.
EDIT:
From @Shanky's comment, I've confirmed that ALTER INDEX ... REBUILD
does NOT require ALLOW_PAGE_LOCKS ON
; this option is only required when reorganizing an index. I've modified my code to do the transaction-wrapping shown above only when performing a reorganize where the index already has ALLOW_PAGE_LOCKS
turned off.
Best Answer
Assuming what you are presuming, I don't what side-effect it could have, outside of the obvious allowing for index REORG to happen :-).
Of course, I have no proof, but not sure what proof to look for that nothing bad will happen when nothing is happening in the DB outside of this REORG operation.
I am also not aware of there being any analogy here to Foreign Keys being untrusted, and hence not considered by the Query Optimizer, if created using the
WITH NOCHECK
option to skip validation (and not trusted until altering usingWITH CHECK
).Regarding the notion of index property vs structure of the index pages: I would say that this could be answered by altering a large index to just turn this option ON and OFF. If it happens instantly, then it is not writing the change to all pages. And, it is also probably a moot point since even if there is a change, it will be handled via the
ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = OFF);
and completed before theCOMMIT
. Still, I can't imagine this being anything other than a simple index property, since it can't change on a per-page basis. Of course, this can also be seen by usingDBCC PAGE
to view the contents of an index before and after you make this change.