Всеки екземпляр на SQL Server съдържа системната база данни на SQL Server, наречена TempDB. Това е типично за всички връзки към базата данни и почти всяка заявка използва базата данни TempDB. Това е като сърце за екземпляра на SQL Server. На практика не можем да работим без базата данни TempDB.
Нека имаме кратко обобщение на операциите, при които SQL Server използва TempDB.
- Подреждане по и Групиране по клауза
- Създаване на индекс и възстановяване на онлайн индекс
- Съхранението на временни таблици и променливи на таблици е в базата данни TempDB.
- Изолиране на моментна снимка и изолиране на завършена моментна снимка
- DBCC команди
- Хешът обединява статични курсори, продължителни транзакции.
- XML заявки
- Вътрешни обекти, създадени от базата данни на SQL Server.
- Съхранение на версии
- Множество активни набори записи (MARS)
Можете да прочетете повече за TempDB в тази статия.
SQL Server пресъздава тази база данни TempDB при рестартиране на услугата на двигателя на базата данни. Това рестартиране може да се дължи на автоматично или ръчно рестартиране на SQL Service. Можем да потърсим sys.databases за преглед на датата на създаване на TempDB, която също е начално време на услугата за база данни:
SELECT create_date AS 'SQL Service Startup Time'
FROM sys.databases
WHERE name = 'tempdb';
Конфигурации на база данни на TempDB SQL Server и най-добри практики
Понякога забелязваме неочакван растеж на базата данни TempDB. Първата стъпка за избягване на това е да го конфигурирате според най-добрите практики. В този раздел нека разгледаме конфигурацията на TempDB е различни версии на SQL Server.
Конфигурирайте TempDB за множество DATA файлове с равномерен растеж
Според най-добрата практика трябва да имаме множество файлове с данни с равномерен растеж на всички файлове. Броят на файловете зависи от логическите процесори.
Процесори | Брой TempDB файлове с данни |
Логически процесори, по-малки или равни на осем | Осем |
Логически процесори, по-големи от осем | Започнете с осем файла с данни. Увеличете файловете с данни кратно на четири и наблюдавайте броячите на производителността за съревнование TempDB. |
За версии на SQL Server преди 2016 г. нямаме налична конфигурация по време на инсталационния процес.
По подразбиране той създава само един файл с данни и журнал със следните конфигурации:
Основен файл на TempDB | Автоматично увеличаване на файла с данни с десет процента (докато дискът се напълни) |
TempDB регистрационен файл | Автоматично увеличаване на файла с данни с десет процента (докато дискът се напълни или максималният размер на регистрационния файл достигне 2 TB) |
Конфигурация на база данни на SQL Server 2014 TempDB SQL Server
SQL Server 2016 предоставя подобрения за конфигурацията на TempDB по време на инсталационния процес според най-добрата практика:
Основни и вторични файлове на TempDB | Автоматично увеличаване с 64 MB (докато дискът се напълни) |
TempDB регистрационен файл | Автоматично нарастване с 64 MB (докато дискът се напълни или максималният размер на регистрационния файл достигне 2 TB) |
Конфигурация на TempDB от SQL Server 2016 нататък
Неравномерно автоматично нарастване на базата данни на SQL Server TempDB
SQL Server използва кръгов метод за попълване на множество файлове с данни, ако те нямат еднакъв размер. Понякога виждаме, че един файл нараства огромен, но други файлове остават минимален растеж. В случай на неравномерни файлове, SQL Server използва по-големия файл за повечето от заявките и ще продължи да расте:
- Използвайте същото автоматично нарастване на TempDB файлове (както беше обсъдено в предишната точка).
- Активиране на флаг за проследяване 1117 за увеличаване на всички файлове с данни заедно в база данни.
Втората точка е фиксирана автоматично в SQL Server 2016 нататък, но трябва да я активирате в по-ранни версии. Не изискваме този флаг за проследяване в SQL Server 2016 и по-нови версии.
Сценарии за растеж на TempDB
В този раздел ще видим няколко сценария за растеж TempDB на база данни на SQL Server. В моя SQL екземпляр имам осем файла с данни със следната конфигурация:
Сега изпълнете следната заявка, за да създадете временна таблица и да извършите вмъкване на данни. Местоположението за временно съхранение на таблицата е базата данни TempDB. Тази заявка използва оператор CROSS JOIN с множество колони и допълнително сортира резултатите с помощта на клаузата ORDER BY.
Забележка: Не изпълнявайте тази заявка в производствената система; Използвам го само за демонстрационни цели.
SELECT *
FROM sys.configurations
CROSS JOIN sys.configurations SCA
CROSS JOIN sys.configurations SCB
CROSS JOIN sys.configurations SCC
CROSS JOIN sys.configurations SCD
CROSS JOIN sys.configurations SCE
CROSS JOIN sys.configurations SCF
CROSS JOIN sys.configurations SCG
CROSS JOIN sys.configurations SCH
ORDER BY SCA.name,
SCA.value,
SCC.value_in_use DESC;
Тази заявка ще отнеме много време и може да доведе до високо използване на процесора във вашата система. Докато заявката се изпълнява, отворете друг прозорец за заявка и използвайте DMV sys.dm_db_task_space_usage, за да получите информация за дейност по разпределение и освобождаване на страници от задачата. Присъединяваме се към този DMV с други DMV, за да получим необходимата информация за базата данни на SQL Server TempDB:
SELECT s.session_id, dbu.database_id
В изхода виждаме броя на страниците на вътрешния обект и техните размери (kbytes_used_internal) за идентификатор на сесията 55. Оптимизаторът на заявки на SQL Server изпълнява тази заявка в паралелен модел; следователно можем да видим множество ID на сесия 71 в изхода:
, dbu.internal_objects_alloc_page_count, dbu.internal_objects_dealloc_page_count
, (dbu.internal_objects_alloc_page_count - dbu.internal_objects_dealloc_page_count) * 8192 / 1024 kbytes_used_internal
, r.total_elapsed_time
FROM sys.dm_Exec_requests r
INNER JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
LEFT JOIN sys.dm_db_task_space_usage dbu ON dbu.session_id = r.session_id
AND dbu.request_id = r.request_id
WHERE internal_objects_alloc_page_count > 0
ORDER BY kbytes_used_internal DESC;
Можете също да видите прогнозния план за изпълнение и, както е показано по-долу, получаваме два скъпи оператора:
- Паралелизъм:47,3%
- Сортиране:52,3%
В оператора за сортиране можем да видим висока прогнозна цена на оператора 138 576,5:
Следната заявка използва DMV sys.dm_db_file_space_usage и го присъединява с sys.master_files, за да провери броя на разпределените и неразпределените екстенти в базата данни на SQL Server TempDB, докато заявката се изпълнява:
select mf.physical_name, mf.size as entire_file_page_count,
dfsu.unallocated_extent_page_count,
dfsu.user_object_reserved_page_count,
dfsu.internal_object_reserved_page_count,
dfsu.mixed_extent_page_count
from sys.dm_db_file_space_usage dfsu
join sys.master_files as mf
on mf.database_id = dfsu.database_id
and mf.file_id = dfsu.file_id
Можем да наблюдаваме изпълнението на заявката, нейното използване в базата данни TempDB и ако е необходимо, да прекратим процеса, за да освободим мястото незабавно. Трябва също така да оптимизираме заявката, причинявайки огромен растеж на TempDB.
Наблюдавайте използването на TempDB на базата данни на SQL Server с помощта на разширени събития
Разширените събития са полезни за мониторинг на база данни на TempDB. Можем да добавим следните разширени събития с помощта на заявката:
- database_file_size_change
- databases_log_file_used_size_changed
Създаване на разширено събитие
CREATE EVENT SESSION [TempDB Usage] ON SERVER
ADD EVENT sqlserver.database_file_size_change(
ACTION(sqlserver.client_hostname,sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text)),
ADD EVENT sqlserver.databases_log_file_used_size_changed(
ACTION(sqlserver.client_hostname,sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text))
ADD TARGET package0.event_file(SET filename=N'TempDBUsage',max_rollover_files=(0))
WITH (STARTUP_STATE=OFF)
GO
Стартиране на разширена сесия на събитие
ALTER EVENT SESSION [TempDBTest] ON SERVER STATE = START;
Сега изпълнете работното си натоварване, за да използвате базата данни TempDB и да разширите файловете с данни. Разширените събития улавят растежа на файла с данни и заявката, която е причинила този растеж.
Можете или да прегледате файла с разширена сесия на събитие в режим SSMS GUI или да използвате следната заявка, за да наблюдавате растежа на TempDB.
Наблюдавайте растежа на TempDB
SELECT [eventdata].[event_data].[value]('(event/action[@name="session_id"]/value)[1]', 'INT') AS [SessionID],
[eventdata].[event_data].[value]('(event/action[@name="client_hostname"]/value)[1]', 'VARCHAR(100)') AS [ClientHostName],
DB_NAME([eventdata].[event_data].[value]('(event/action[@name="database_id"]/value)[1]', 'BIGINT')) AS [GrowthDB],
[eventdata].[event_data].[value]('(event/data[@name="file_name"]/value)[1]', 'VARCHAR(200)') AS [GrowthFile],
[eventdata].[event_data].[value]('(event/data[@name="file_type"]/text)[1]', 'VARCHAR(200)') AS [DBFileType],
[eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(MAX)') AS [EventName],
[eventdata].[event_data].[value]('(event/data[@name="size_change_kb"]/value)[1]', 'BIGINT') AS [SizeChangedKb],
[eventdata].[event_data].[value]('(event/data[@name="total_size_kb"]/value)[1]', 'BIGINT') AS [TotalSizeKb],
[eventdata].[event_data].[value]('(event/data[@name="duration"]/value)[1]', 'BIGINT') AS [DurationInMS],
[eventdata].[event_data].[value]('(event/@timestamp)[1]', 'VARCHAR(MAX)') AS [GrowthTime],
[eventdata].[event_data].[value]('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(MAX)') AS [QueryText]
FROM
(
SELECT CAST([event_data] AS XML) AS [TargetData]
FROM [sys].[fn_xe_file_target_read_file]('C:\TEMP\TempDBusage*.xel', NULL, NULL, NULL)
) AS [eventdata]([event_data])
WHERE [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(100)') = 'database_file_size_change'
OR [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(100)') = 'databases_log_file_used_size_changed'
AND [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(MAX)') <> 'databases_log_file_used_size_changed'
ORDER BY [GrowthTime] ASC;
Изолиране на моментна снимка
Може да използвате изолация на моментни снимки за вашите заявки. В този модел на изолация SQL Server съхранява актуализираните версии на редове на всяка транзакция в TempDB. В случай на голяма или продължителна транзакция, можете да видите огромна база данни TempDB.
Можете да изпълните транзакцията с командата SET и да посочите изолация на моментна снимка:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN;
UPDATE [AdventureWorks].[Person].[Person]
SET
[Title] = 'Mr.';
COMMIT TRAN;
Можете също да направите заявка за sys.databases системен изглед, за да проверите дали някоя потребителска база данни има изолация на моментни снимки.
Запитване за активиране на изолиране на моментни снимки в базата данни на AdventureWorks
ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO
Запитване за проверка на потребителска база данни с изолация на моментни снимки
SELECT *
FROM sys.databases
WHERE(snapshot_isolation_state = 1
OR is_read_committed_snapshot_on = 1)
AND database_id > 4;
На следващата екранна снимка можете да видите, че базата данни AdventureWorks има изолация на моментни снимки. Базата данни TempDB също има изолация на моментна снимка, но в заявката сме пропуснали database_id по-малко от 4:
Можем да използваме DMV sys.dm_db_file_space_usage, за да наблюдаваме съхранението на версии във TempDB:
SELECT GETDATE() AS runtime,
SUM(user_object_reserved_page_count) * 8 AS usr_obj_kb,
SUM(internal_object_reserved_page_count) * 8 AS internal_obj_kb,
SUM(version_store_reserved_page_count) * 8 AS version_store_kb,
SUM(unallocated_extent_page_count) * 8 AS freespace_kb,
SUM(mixed_extent_page_count) * 8 AS mixedextent_kb
FROM sys.dm_db_file_space_usage;
Тук можем да видим размерът на магазина на версията е 67968 KB. За голяма или продължителна транзакция можете да видите огромен TempDB размер на базата данни на SQL Server поради това хранилище на версии:
Друг случай, който може да причини огромен размер на хранилището на версиите, е Винаги на вторична реплика само за четене. Ако изпълните каквато и да е заявка към вторичната база данни, тя автоматично използва нивото на изолация на моментна снимка. Както знаете, нивото на изолация на моментна снимка копира версията на реда в TempDB.
Трябва да наблюдавате следните броячи на perfmon:
- SQLServer:Transactions\Най-дълго време за изпълнение на транзакциите – Той улавя най-разширената активна транзакция.
- SQLServer:Transactions\Version Store Size (KB) – Той улавя текущия размер на всички съхранявани версии в TempDB.
- SQLServer:Transactions\Version Cleanup rate (KB/s) ) – Можете да използвате този брояч, за да покажете скоростта на изчистване на версията в TempDB
- SQLServer:Транзакции\Скорост на генериране на версия (KB/s) – Можете да уловите скоростта на улавяне на магазина на версиите, като използвате този брояч.
Трябва също така да наблюдавате растежа на TempDB за управлението на версиите във винаги във вторичната база данни. Прекратете продължителните сесии, за да може да изчисти версията и да възстанови пространството в базата данни TempDB.
Заключение
В тази статия научихме за най-добрите практики на базата данни TempDB на базата данни на SQL Server и различни методи за откриване и предотвратяване на неочакван растеж. Трябва да наблюдавате TempDB редовно и да конфигурирате различни сигнали, за да бъдат проактивни.
- Наблюдение на размера на TempDB
- Наблюдение на пространството в диска
- Дългосрочни транзакции