patternsqlMinor
Database is happily available even during log growth?
Viewed 0 times
availablelogduringdatabasehappilygrowtheven
Problem
I’ve been creating a process to go through all our databases and analyze the log structure, backup, shrink, and resize appropriately taking operational requirements and VLF sizing/amount into account. My code is working beautifully, but I encountered something in testing today I wasn’t expecting.
I have a good sized DB with a 104GB log and around 900 VLFs. I backed up the log and shrank down to next to nothing during a period of low activity. I then began to grow it back out to it’s original size in 8GB iterations, keeping VLFs around 512MB. During regrowth (somewhere between 48GB and 56GB), I was curious about DB availability and started running random SELECTS against different tables. Results returned without issue. I then created a table in the DB and looped a bunch of inserts.
I was surprised when the log continued to grow and the table creation and inserts completed without issue or delay. I was under the impression the DB would somehow be locked down, blocking DDL and DML, until regrowth completed. Of course, considering the circular nature of the log, I can see how this would be a false assumption. But I can’t find anything on the web one way or the other.
Can someone shed some light or point me int he right direction on what is going on? Thanks!
I have a good sized DB with a 104GB log and around 900 VLFs. I backed up the log and shrank down to next to nothing during a period of low activity. I then began to grow it back out to it’s original size in 8GB iterations, keeping VLFs around 512MB. During regrowth (somewhere between 48GB and 56GB), I was curious about DB availability and started running random SELECTS against different tables. Results returned without issue. I then created a table in the DB and looped a bunch of inserts.
I was surprised when the log continued to grow and the table creation and inserts completed without issue or delay. I was under the impression the DB would somehow be locked down, blocking DDL and DML, until regrowth completed. Of course, considering the circular nature of the log, I can see how this would be a false assumption. But I can’t find anything on the web one way or the other.
Can someone shed some light or point me int he right direction on what is going on? Thanks!
Solution
I ended up solving my own question with the below code:
--Using the AdventureWorks2012 database in Full mode with log shrunk to 64MB
--setup test table
USE AdventureWorks2012
go
IF OBJECT_ID('TestTbl') IS NOT NULL
DROP TABLE TestTbl
GO
CREATE TABLE TestTbl
(
RowID INT IDENTITY(100,100)
, RightNow DATETIME
, SomeField VARCHAR(255)
, SomeOtherField VARCHAR(255)
, CONSTRAINT PK_TESTTBL_ROWID_RIGHTNOW
PRIMARY KEY CLUSTERED (RowID, RIGHTNOW)
WITH (IGNORE_DUP_KEY = OFF)
)
GO
--grow the log out to roughly 50GB and write to the test table in between each grow
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 1','8193 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 8193)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 2','16386 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 16386)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 3','24579 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 24579)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 4','32772 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 32772)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 5','40965 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 40965)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 6','49158 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 49158)
--in a separate session insert to the test table, i did this after the first 8GB was grown
INSERT TestTbl
VALUES (GETDATE(),'SomeValue'+CAST(DATEPART(MILLISECOND,GETDATE()) AS VARCHAR(25)), 'SomeOtherValue'+CAST(DATEPART(MICROSECOND,GETDATE()) AS VARCHAR(25)))
GO 50000
--monitor growth iterations
SELECT * FROM TestTbl WITH (NOLOCK)
WHERE SomeOtherField LIKE '%MB%'
--monitor log
SELECT DB_NAME(database_id) DatabaseName,name LogName,size*8/1024 SizeInMB
FROM sys.master_files
WHERE database_id = DB_ID('AdventureWorks2012')
and type_desc = 'LOG'
DBCC LOGINFO ('AdventureWorks2012') WITH NO_INFOMSGS
USE AdventureWorks2012
GO
SELECT
[Current LSN],
[Transaction ID],
[Operation],
[Transaction Name],
[Description],
[CONTEXT],
[AllocUnitName],
[Page ID],
[Slot ID],
[Begin Time],
[End Time],
[Number of Locks],
[Lock Information]
FROM sys.fn_dblog(NULL,NULL)
--modify the rowIDs to span a growth iteration and observe short pause and continue
SELECT * FROM TestTbl
WHERE RowID BETWEEN 239500 AND 241000Code Snippets
--Using the AdventureWorks2012 database in Full mode with log shrunk to 64MB
--setup test table
USE AdventureWorks2012
go
IF OBJECT_ID('TestTbl') IS NOT NULL
DROP TABLE TestTbl
GO
CREATE TABLE TestTbl
(
RowID INT IDENTITY(100,100)
, RightNow DATETIME
, SomeField VARCHAR(255)
, SomeOtherField VARCHAR(255)
, CONSTRAINT PK_TESTTBL_ROWID_RIGHTNOW
PRIMARY KEY CLUSTERED (RowID, RIGHTNOW)
WITH (IGNORE_DUP_KEY = OFF)
)
GO
--grow the log out to roughly 50GB and write to the test table in between each grow
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 1','8193 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 8193)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 2','16386 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 16386)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 3','24579 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 24579)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 4','32772 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 32772)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 5','40965 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 40965)
INSERT TestTbl
VALUES (GETDATE(),'GROWING ITERATION 6','49158 MB')
USE AdventureWorks2012
ALTER DATABASE [AdventureWorks2012] MODIFY FILE (NAME = N'AdventureWorks2012_Log', SIZE = 49158)
--in a separate session insert to the test table, i did this after the first 8GB was grown
INSERT TestTbl
VALUES (GETDATE(),'SomeValue'+CAST(DATEPART(MILLISECOND,GETDATE()) AS VARCHAR(25)), 'SomeOtherValue'+CAST(DATEPART(MICROSECOND,GETDATE()) AS VARCHAR(25)))
GO 50000
--monitor growth iterations
SELECT * FROM TestTbl WITH (NOLOCK)
WHERE SomeOtherField LIKE '%MB%'
--monitor log
SELECT DB_NAME(database_id) DatabaseName,name LogName,size*8/1024 SizeInMB
FROM sys.master_files
WHERE database_id = DB_ID('AdventureWorks2012')
and type_desc = 'LOG'
DBCC LOGINFO ('AdventureWorks2012') WITH NO_INFOMSGS
USE AdventureWorks2012
GO
SELECT
[Current LSN],
[Transaction ID],
[Operation],
[Transaction Name],
[Description],
[CONTEXT],
[AllocUnitName],
[Page ID],
[Slot ID],
[Begin Time],
[End Time],
[Number of Locks],
[Lock Information]
FROM sys.fn_dblog(NULL,NULL)
--modify the rowIDs to span a growth iteration and observe short pause and continue
SELECT * FROM TestTbl
WContext
StackExchange Database Administrators Q#80764, answer score: 2
Revisions (0)
No revisions yet.