Sql-server – the impact of temporarily setting ALLOW_PAGE_LOCKS ON

fragmentationlockingsql serversql-server-2012

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

Presuming the database is not actually "in-use" at the time this rebuild process starts

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 using WITH 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 the COMMIT. 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 using DBCC PAGE to view the contents of an index before and after you make this change.