Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Проактивни проверки на състоянието на SQL Server, част 3:Настройки на инстанция и база данни

Нашата дискусия за проактивни задачи, които поддържат вашата база данни здрава, продължава в тази публикация, докато се занимаваме с опциите за сървър и база данни. Може би вече си мислите, че това ще бъде бърза публикация – кой променя опциите на сървъра или базата данни толкова често? Ще се изненадате, особено ако имате много хора, които имат достъп до SQL Server. Опциите на сървъра и базата данни трябва да се променят рядко – в по-голямата си част те се задават при инсталиране и се оставят сами. Но от време на време има добра причина да направите промяна – било то свързана с производителността, поради промяна в кода на приложението или може би защото нещо е било зададено неправилно първия път. Тествайте първо тези промени и запишете подходящи показатели преди и след промяната. Изглежда доста просто и очевидно, нали? Може да мислите така, но ако не разполагате с процес за управление на промените, който да се спазва стриктно, не е така.

В повечето среди повече от едно лице има достъп до SQL Server и повече от едно лице има привилегиите, необходими за промяна на опциите на сървъра или базата данни. Ако се промени грешната настройка, въздействието върху производителността може да бъде значително. (Случвало ли ви се е да зададете по невнимание настройката за максимална памет на стойност в GB вместо в MB? В случай, че се чудите, 128 MB не е достатъчно памет, необходима за стартиране на екземпляр на SQL Server. Вижте публикацията на Ted Krueger за това как да коригирате това , ако някога направите тази грешка.) Други промени могат да създадат по-малки проблеми, които все още са обезпокоителни и понякога трудни за проследяване (деактивирането на Auto Create Statistics е добър пример). Може да мислите, че тези промени ще бъдат добре комуникирани (понякога сте толкова заети с гасене на пожари, че забравяте) или лесни за забелязване (не винаги). За да избегнем това, ние проследяваме настройките и след това, когато изпълняваме нашите редовни проверки (или когато отстраняваме проблем), проверяваме дали нищо не се е променило.

Улавяне на данните

За разлика от предишната публикация за задачи по поддръжка, където разчитахме на msdb, за да задържи данните, които ни интересуваха, трябва да настроим улавяне на данни например и настройки на базата данни. Ще правим моментни снимки sys.configurations и sys.database_info ежедневно в таблици в нашата база данни Baselines, след което ще използваме заявки, за да видим дали нещо се е променило и кога.

USE [Baselines];
GO
 
IF OBJECT_ID(N'dbo.SQLskills_ConfigData', N'U') IS NULL
BEGIN
  CREATE TABLE [dbo].[SQLskills_ConfigData] 
  (
    [ConfigurationID] [int] NOT NULL ,
    [Name] [nvarchar](35) NOT NULL ,
    [Value] [sql_variant] NULL ,
    [ValueInUse] [sql_variant] NULL ,
    [CaptureDate] [datetime] NOT NULL DEFAULT SYSDATETIME()
  ) ON [PRIMARY];
GO
 
CREATE CLUSTERED INDEX [CI_SQLskills_ConfigData] 
  ON [dbo].[SQLskills_ConfigData] ([CaptureDate],[ConfigurationID]);
GO
 
IF OBJECT_ID(N'dbo.SQLskills_DBData', N'U') IS NULL
BEGIN
  CREATE TABLE [dbo].[SQLskills_DBData]
  (
    [name] [sysname] NOT NULL,
    [database_id] [int] NOT NULL,
    [source_database_id] [int] NULL,
    [owner_sid] [varbinary](85) NULL,
    [create_date] [datetime] NOT NULL,
    [compatibility_level] [tinyint] NOT NULL,
    [collation_name] [sysname] NULL,
    [user_access] [tinyint] NULL,
    [user_access_desc] [nvarchar](60) NULL,
    [is_read_only] [bit] NULL,
    [is_auto_close_on] [bit] NOT NULL,
    [is_auto_shrink_on] [bit] NULL,
    [state] [tinyint] NULL,
    [state_desc] [nvarchar](60) NULL,
    [is_in_standby] [bit] NULL,
    [is_cleanly_shutdown] [bit] NULL,
    [is_supplemental_logging_enabled] [bit] NULL,
    [snapshot_isolation_state] [tinyint] NULL,
    [snapshot_isolation_state_desc] [nvarchar](60) NULL,
    [is_read_committed_snapshot_on] [bit] NULL,
    [recovery_model] [tinyint] NULL,
    [recovery_model_desc] [nvarchar](60) NULL,
    [page_verify_option] [tinyint] NULL,
    [page_verify_option_desc] [nvarchar](60) NULL,
    [is_auto_create_stats_on] [bit] NULL,
    [is_auto_update_stats_on] [bit] NULL,
    [is_auto_update_stats_async_on] [bit] NULL,
    [is_ansi_null_default_on] [bit] NULL,
    [is_ansi_nulls_on] [bit] NULL,
    [is_ansi_padding_on] [bit] NULL,
    [is_ansi_warnings_on] [bit] NULL,
    [is_arithabort_on] [bit] NULL,
    [is_concat_null_yields_null_on] [bit] NULL,
    [is_numeric_roundabort_on] [bit] NULL,
    [is_quoted_identifier_on] [bit] NULL,
    [is_recursive_triggers_on] [bit] NULL,
    [is_cursor_close_on_commit_on] [bit] NULL,
    [is_local_cursor_default] [bit] NULL,
    [is_fulltext_enabled] [bit] NULL,
    [is_trustworthy_on] [bit] NULL,
    [is_db_chaining_on] [bit] NULL,
    [is_parameterization_forced] [bit] NULL,
    [is_master_key_encrypted_by_server] [bit] NOT NULL,
    [is_published] [bit] NOT NULL,
    [is_subscribed] [bit] NOT NULL,
    [is_merge_published] [bit] NOT NULL,
    [is_distributor] [bit] NOT NULL,
    [is_sync_with_backup] [bit] NOT NULL,
    [service_broker_guid] [uniqueidentifier] NOT NULL,
    [is_broker_enabled] [bit] NOT NULL,
    [log_reuse_wait] [tinyint] NULL,
    [log_reuse_wait_desc] [nvarchar](60) NULL,
    [is_date_correlation_on] [bit] NOT NULL,
    [is_cdc_enabled] [bit] NOT NULL,
    [is_encrypted] [bit] NULL,
    [is_honor_broker_priority_on] [bit] NULL,
    [replica_id] [uniqueidentifier] NULL,
    [group_database_id] [uniqueidentifier] NULL,
    [default_language_lcid] [smallint] NULL,
    [default_language_name] [nvarchar](128) NULL,
    [default_fulltext_language_lcid] [int] NULL,
    [default_fulltext_language_name] [nvarchar](128) NULL,
    [is_nested_triggers_on] [bit] NULL,
    [is_transform_noise_words_on] [bit] NULL,
    [two_digit_year_cutoff] [smallint] NULL,
    [containment] [tinyint] NULL,
    [containment_desc] [nvarchar](60) NULL,
    [target_recovery_time_in_seconds] [int] NULL,
    [CaptureDate] [datetime] NOT NULL DEFAULT SYSDATETIME()
) ON [PRIMARY];
GO
 
CREATE CLUSTERED INDEX [CI_SQLskills_DBData] 
  ON [dbo].[SQLskills_DBData] ([CaptureDate],[database_id]);
GO

Скриптът за създаване на таблицата SQLskills_DBData е съвместим със SQL Server 2014. За по-ранни версии може да се наложи да промените основната таблица и заявката за моментна снимка (вижте следващия набор от код).

След като създадете таблиците, създайте задание, което ще изпълнява следните две заявки ежедневно. Отново не бихме очаквали, че тези опции ще се променят повече от веднъж на ден и макар да се надяваме, че никой няма да промени настройка, след което да я промени обратно (следователно тя няма да се покаже в заснемане), това винаги е възможност . Ако установите, че това събиране на данни не отговаря на нуждите ви, тъй като настройките се променят често или временно, може да искате да внедрите задействане или да използвате одит.

За да редактирате опциите на сървъра чрез (sp_configure), входът се нуждае от разрешение на ниво сървър ALTER SETTINGS, което е включено, ако сте член на ролите sysadmin или serveradmin. За да редактирате повечето настройки на базата данни (ALTER DATABASE SET), имате нужда от разрешението ALTER в базата данни, въпреки че някои опции изискват допълнителни права, като CONTROL SERVER или опцията на ниво сървър ALTER ANY DATABASE.

/* Statements to use in scheduled job */
 
INSERT INTO [dbo].[SQLskills_ConfigData]
(
  [ConfigurationID] ,
  [Name] ,
  [Value] ,
  [ValueInUse]
)
SELECT 
  [configuration_id] ,
  [name] ,
  [value] ,
  [value_in_use]
FROM [sys].[configurations];
GO
 
INSERT INTO [dbo].[SQLskills_DBData]
(
  [name],
  [database_id],
  [source_database_id],
  [owner_sid],
  [create_date],
  [compatibility_level],
  [collation_name],
  [user_access],
  [user_access_desc],
  [is_read_only],
  [is_auto_close_on],
  [is_auto_shrink_on],
  [state],
  [state_desc],
  [is_in_standby],
  [is_cleanly_shutdown],
  [is_supplemental_logging_enabled],
  [snapshot_isolation_state],
  [snapshot_isolation_state_desc],
  [is_read_committed_snapshot_on],
  [recovery_model],
  [recovery_model_desc],
  [page_verify_option],
  [page_verify_option_desc],
  [is_auto_create_stats_on],
  [is_auto_update_stats_on],
  [is_auto_update_stats_async_on],
  [is_ansi_null_default_on],
  [is_ansi_nulls_on],
  [is_ansi_padding_on],
  [is_ansi_warnings_on],
  [is_arithabort_on],
  [is_concat_null_yields_null_on],
  [is_numeric_roundabort_on],
  [is_quoted_identifier_on],
  [is_recursive_triggers_on],
  [is_cursor_close_on_commit_on],
  [is_local_cursor_default],
  [is_fulltext_enabled],
  [is_trustworthy_on],
  [is_db_chaining_on],
  [is_parameterization_forced],
  [is_master_key_encrypted_by_server],
  [is_published],
  [is_subscribed],
  [is_merge_published],
  [is_distributor],
  [is_sync_with_backup],
  [service_broker_guid],
  [is_broker_enabled],
  [log_reuse_wait],
  [log_reuse_wait_desc],
  [is_date_correlation_on],
  [is_cdc_enabled],
  [is_encrypted],
  [is_honor_broker_priority_on],
  [replica_id],
  [group_database_id],
  [default_language_lcid],
  [default_language_name],
  [default_fulltext_language_lcid],
  [default_fulltext_language_name],
  [is_nested_triggers_on],
  [is_transform_noise_words_on],
  [two_digit_year_cutoff],
  [containment],
  [containment_desc],
  [target_recovery_time_in_seconds]
)
SELECT
  [name],
  [database_id],
  [source_database_id],
  [owner_sid],
  [create_date],
  [compatibility_level],
  [collation_name],
  [user_access],
  [user_access_desc],
  [is_read_only],
  [is_auto_close_on],
  [is_auto_shrink_on],
  [state],
  [state_desc],
  [is_in_standby],
  [is_cleanly_shutdown],
  [is_supplemental_logging_enabled],
  [snapshot_isolation_state],
  [snapshot_isolation_state_desc],
  [is_read_committed_snapshot_on],
  [recovery_model],
  [recovery_model_desc],
  [page_verify_option],
  [page_verify_option_desc],
  [is_auto_create_stats_on],
  [is_auto_update_stats_on],
  [is_auto_update_stats_async_on],
  [is_ansi_null_default_on],
  [is_ansi_nulls_on],
  [is_ansi_padding_on],
  [is_ansi_warnings_on],
  [is_arithabort_on],
  [is_concat_null_yields_null_on],
  [is_numeric_roundabort_on],
  [is_quoted_identifier_on],
  [is_recursive_triggers_on],
  [is_cursor_close_on_commit_on],
  [is_local_cursor_default],
  [is_fulltext_enabled],
  [is_trustworthy_on],
  [is_db_chaining_on],
  [is_parameterization_forced],
  [is_master_key_encrypted_by_server],
  [is_published],
  [is_subscribed],
  [is_merge_published],
  [is_distributor],
  [is_sync_with_backup],
  [service_broker_guid],
  [is_broker_enabled],
  [log_reuse_wait],
  [log_reuse_wait_desc],
  [is_date_correlation_on],
  [is_cdc_enabled],
  [is_encrypted],
  [is_honor_broker_priority_on],
  [replica_id],
  [group_database_id],
  [default_language_lcid],
  [default_language_name],
  [default_fulltext_language_lcid],
  [default_fulltext_language_name],
  [is_nested_triggers_on],
  [is_transform_noise_words_on],
  [two_digit_year_cutoff],
  [containment],
  [containment_desc],
  [target_recovery_time_in_seconds]
FROM [sys].[databases];
GO

Проверка за промени

Сега, когато улавяме тази информация, как да открием промени? Знаейки, че може да има множество променени настройки и на различни дати, се нуждаем от метод, който разглежда всеки ред. Това не е трудно да се направи, но не генерира най-красивия код. За опциите на сървъра не е лошо:

;WITH [f] AS
( 
  SELECT
    ROW_NUMBER() OVER (PARTITION BY [ConfigurationID] ORDER BY [CaptureDate] ASC) AS [RowNumber],
    [ConfigurationID] AS [ConfigurationID],
    [Name] AS [Name],
    [Value] AS [Value],
    [ValueInUse] AS [ValueInUse],
    [CaptureDate] AS [CaptureDate]
  FROM [Baselines].[dbo].[ConfigData]
)
SELECT 
  [f].[Name] AS [Setting], 
  [f].[CaptureDate] AS [Date], 
  [f].[Value] AS [Previous Value], 
  [f].[ValueInUse] AS [Previous Value In Use],
  [n].[CaptureDate] AS [Date Changed], 
  [n].[Value] AS [New Value], 
  [n].[ValueInUse] AS [New Value In Use]
FROM [f]
LEFT OUTER JOIN [f] AS [n]
ON [f].[ConfigurationID] = [n].[ConfigurationID]
AND [f].[RowNumber] + 1 = [n].[RowNumber]
WHERE ([f].[Value] <> [n].[Value] OR [f].[ValueInUse] <> [n].[ValueInUse]);
GO

Променени настройки на екземпляра

За опциите на базата данни заявката е в съхранена процедура (защото беше толкова тромава), която можете да изтеглите тук. За да стартирате съхранената процедура:

EXEC dbo.usp_FindDBSettingChanges

Резултатът ще изброи базата данни и настройката, която е променена, както и датата:

Променени настройки на базата данни

Можете да стартирате тези заявки, когато възникнат проблеми с производителността, за да проверите бързо дали някои настройки са се променили, или бихте могли да бъдете малко по-активни и да ги изпълнявате редовно в планирано задание, което ви уведомява, ако нещо се е променило. Не включих T-SQL кода за изпращане на имейл чрез поща от базата данни, ако има промяна, но това няма да е трудно да се направи въз основа на предоставения тук код.

Използване на съветника за производителност

SQL Sentry Performance Advisor не проследява тази информация по подразбиране, но все пак можете да улавяте информацията в база данни, след което да проверите PA, за да видите дали някои настройки са се променили, и да ви уведоми, ако са. За да настроите това, създайте таблиците SQLskills_ConfigData и SQLskillsDBData и настройте планираното задание за редовно вмъкване в тези таблици. В рамките на клиента SQL Sentry задайте персонализирано условие, както направихме в по-ранна публикация от тази серия, Проактивни проверки на състоянието на SQL Server, част 1:Публикация на дисковото пространство.

В рамките на персонализираното условие имате две опции. Първо, можете просто да изпълните предоставения код, който проверява исторически данни, за да видите дали нещо се е променило (и след това да изпратите известие, ако е така). Проверката на исторически данни за промяна е нещо, което бихте изпълнявали ежедневно, както бихте направили с работа за агент. Като алтернатива можете да бъдете по-активни и да сравнявате текущите текущи стойности с най-новите данни на по-честа основа, напр. веднъж на час, за да търсите промени. Примерен код за проверка на текущите настройки за екземпляра спрямо най-новото заснемане:

;WITH [lc] AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY [ConfigurationID] ORDER BY [CaptureDate] ASC) AS [RowNumber],
    [ConfigurationID] AS [ConfigurationID],
    [Name] AS [Name],
    [Value] AS [Value],
    [ValueInUse] AS [ValueInUse],
    [CaptureDate] AS [CaptureDate]
  FROM [Baselines].[ConfigData]
  WHERE [CaptureDate] = (SELECT MAX([CaptureDate]) FROM [Baselines].[ConfigData])
)
SELECT 
  [lc].[Name] AS [Setting], 
  [lc].[CaptureDate] AS [Date], 
  [lc].[Value] AS [Last Captured Value],
  [lc].[ValueInUse] AS [Last Captured Value In Use], 
  CURRENT_TIMESTAMP AS [Current Time],
  [c].[Value] AS [Current Value], 
  [c].[value_in_use] AS [Current Value In Use]
FROM [sys].[configurations] AS [c]
LEFT OUTER JOIN [lc]
ON [lc].[ConfigurationID] = [c].[configuration_id]
WHERE ([lc].[Value] <> [c].[Value] OR [lc].[ValueInUse] <> [c].[value_in_use]);
GO

Резюме

Проверката на опциите за екземпляр и база данни е ясна и очевидна и в някои ситуации тази историческа информация може да ви спести значително време при отстраняване на неизправности. Ако не улавяте тази информация никъде, препоръчвам ви да започнете; винаги е по-добре проактивно да търсите проблеми, отколкото да реагирате, когато се борите с пожари и сте потенциално стресирани, несигурни какво причинява проблем във вашата производствена среда.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Не може да се свърже със сървъра - грешка, свързана с мрежата или специфична за екземпляр

  2. Пет водещи съображения за дизайна на индекс на база данни в SQL Server

  3. ABS() Примери в SQL Server

  4. Как да промените стойностите за редактиране на най-горния X и избор на най-горните X редове в SQL Server Management Studio (SSMS) - SQL Server / TSQL урок, част 20

  5. Как да копирате огромни данни от таблица в друга таблица в SQL Server