web-dev-qa-db-ja.com

tempdbはセカンダリレプリカで大きくする必要がありますか?

SQL Server 2012と可用性グループに取り組んでいます。

セカンダリレプリカでは、tempdbデータファイルのサイズはプライマリのサイズの約2倍です。これが正常かどうかの情報を見つけるのに苦労していますか?

セカンダリレプリカは読み取り専用レプリカとして設定されます。セカンダリでのみ実行されるバックアップジョブを除き、すべてのサーバーエージェントジョブは、実行時にプライマリノードで実行されているかどうかを確認します。私が知る限り、セカンダリレプリカに直接アクセスするクライアントアプリケーションはありません。

サイズの例(sp_helpfileから):

  • プライマリレプリカ-tempdev:12259456 KB
  • セカンダリレプリカ-tempdev:24828992 KB
3
user75158

セカンダリノードで、読み取り専用クエリに使用すると、SQLは背後でReadCommitedスナップショットを有効にします。読み取りを実行するトランザクションを長時間実行している場合、そのセカンダリノードでtempdbをより多く使用した理由が説明される可能性があります。

3

tempDBをセカンダリレプリカで大きくする必要がありますか?

それはワークロードに依存します。

Tempdbファイルのサイズを頻繁に収集して保存することをお勧めします。しばらく収集して、それが完全なワークロードサイクルを表したら、それをグラフ化してベースラインを見つけます。これが、すべてのノードでtempdbデータベースのサイズを決定する方法です。以下は、使用できるコードの一部です。最初にテストしてください。また、「Always On可用性グループ」のデータベースと、データベースがセカンダリであるかどうかも処理します。

DECLARE @SQL varchar(MAX);
DECLARE @DBname varchar(MAX);

IF OBJECT_ID('tempdb..#DBs') IS NOT NULL
BEGIN
DROP TABLE #DBs;
END
CREATE TABLE #DBs (dbname sysname);


CREATE TABLE #DB_SizeData(
    [Servername] [nvarchar](50) NOT NULL,
    [DatabaseName] [nvarchar](260) NOT NULL,
    [FileName] [nvarchar](100) not null,
    [Type_Description] [nvarchar] (50),
    [CurrentFileSizeGB] [decimal](18, 1) NULL,
    [FileUsedSpaceGB] [decimal](18, 1) NULL,
    [FileFreeSpaceGB] [decimal](18, 1) NULL,
    [FilePercentFree] [decimal](18, 2) NULL,
    [RecCreateDt] [datetime] NOT NULL
) ON [PRIMARY];

INSERT INTO #DBs
--only choose online databases
SELECT name FROM sys.databases 
--looking for online only 
WHERE [STATE] = 0
--excluding single_user and restricted user
AND   [user_access]=0
AND   [is_read_only]=0
--uncomment below line if you want to exclude system databases
AND   [NAME] NOT IN ('master','model','msdb','tempdb') ; 

--get secondary replica db list
IF OBJECT_ID('tempdb..#AGdatabases') IS NOT NULL
BEGIN
DROP TABLE #AGdatabases;
END

CREATE TABLE #AGdatabases
(dbname SYSNAME);

IF EXISTS (SELECT
AG.name AS [Name],
ISNULL(agstates.primary_replica, '') AS [PrimaryReplicaServerName],
ISNULL(arstates.role, 3) AS [LocalReplicaRole]
FROM master.sys.availability_groups AS AG
LEFT OUTER JOIN master.sys.dm_hadr_availability_group_states as agstates
    ON AG.group_id = agstates.group_id
INNER JOIN master.sys.availability_replicas AS AR
    ON AG.group_id = AR.group_id
INNER JOIN master.sys.dm_hadr_availability_replica_states AS arstates
    ON AR.replica_id = arstates.replica_id AND arstates.is_local = 1
)

BEGIN
INSERT INTO #AGdatabases
SELECT DISTINCT
dbcs.database_name AS [DatabaseName]
FROM master.sys.availability_groups AS AG
LEFT OUTER JOIN master.sys.dm_hadr_availability_group_states as agstates
   ON AG.group_id = agstates.group_id
INNER JOIN master.sys.availability_replicas AS AR
   ON AG.group_id = AR.group_id
INNER JOIN master.sys.dm_hadr_availability_replica_states AS arstates
   ON AR.replica_id = arstates.replica_id AND arstates.is_local = 1
INNER JOIN master.sys.dm_hadr_database_replica_cluster_states AS dbcs
   ON arstates.replica_id = dbcs.replica_id
LEFT OUTER JOIN master.sys.dm_hadr_database_replica_states AS dbrs
   ON dbcs.replica_id = dbrs.replica_id AND dbcs.group_database_id = dbrs.group_database_id
WHERE ISNULL(arstates.role, 3) = 2 AND ISNULL(dbcs.is_database_joined, 0) = 1
ORDER BY  dbcs.database_name;
END
--exclude secondary replica databases
DELETE FROM #DBs WHERE dbname in
(SELECT dbname FROM #AGdatabases);

WHILE exists (SELECT * FROM #DBs)
BEGIN

SELECT TOP 1 @DBname = dbname
FROM #DBs

SELECT @SQL = '
USE '  +  QUOTENAME(@DBname) +' --to account for space or special characters in a datbase name
SELECT @@Servername,
DB_NAME() AS DbName, 
name AS FileName, 
type_desc AS Type_Description,
size/128.0/1024 AS CurrentSizeGB, 
CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0/1024 AS UsedSpaceGB ,
size/128.0/1024 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0/1024 AS FreeSpaceGB ,
((size/128.0/1024 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0/1024)/(size/128.0/1024))*100 as LogFilePercentFree
,getdate()
from [' + @DBname+ '].sys.database_files 
; 
'
INSERT INTO  #DB_SizeData
EXEC (@SQL)

DELETE FROM  #DBs
WHERE @DBname = dbname
END  

SELECT * FROM #DB_SizeData
DROP TABLE #DB_SizeData
DROP TABLE #DBs
1
SqlWorldWide