Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A következőkre vonatkozik:SQL Server
Ez a cikk az SQL Server-példányokra vonatkozik.
Megjegyzés:
Ez a cikk az SQL Serverre összpontosít. Az Azure SQL-platformokon fellépő hibával kapcsolatos további információkért tekintse meg az Azure SQL Database tranzakciónapló-hibáinak hibaelhárítását és a felügyelt Azure SQL-példány tranzakciónapló-hibáinak hibaelhárítását. Az Azure SQL Database és a felügyelt Azure SQL-példány a Microsoft SQL Server adatbázismotor legújabb stabil verzióján alapul, így a tartalom nagy része hasonló, bár a hibaelhárítási lehetőségek és eszközök eltérőek lehetnek.
1. lehetőség: A lépések futtatása közvetlenül egy végrehajtható jegyzetfüzetben az Azure Data Studióval
A jegyzetfüzet megnyitása előtt ellenőrizze, hogy az Azure Data Studio telepítve van-e a helyi gépen. A telepítéshez nyissa meg az Azure Data Studio letöltését és telepítését.
2. lehetőség: Kövesse a lépéseket manuálisan
Ez a cikk a teljes tranzakciónaplóra adott lehetséges válaszokat ismerteti, és azt ismerteti, hogyan kerülheti el a jövőben.
Amikor a tranzakciónapló megtelik, az SQL Server adatbázismotor 9002-s hibát ad ki. A napló kitölthető, ha az adatbázis online állapotban van, vagy helyreállítás alatt áll. Ha a napló akkor telik meg, amikor az adatbázis online állapotban van, az adatbázis elérhető marad, de csak olvasható, és nem frissíthető. Ha a napló a helyreállítás során kitöltődik, az adatbázismotor az adatbázist RESOURCE PENDINGa következőképpen jelöli meg: . Mindkét esetben felhasználói művelet szükséges a naplóterület elérhetővé tétele érdekében.
A teljes tranzakciónapló gyakori okai
A teljes tranzakciónaplóra adott megfelelő válasz attól függ, hogy milyen feltételek miatt történt a napló kitöltése. A gyakori kiváltó okok között a következőket találjuk:
- A napló nem került rövidítésre
- A lemezkötet megtelt
- A naplóméret rögzített maximális értékre van állítva, vagy az automatikus kitöltés le van tiltva
- Replikáció vagy rendelkezésre állási csoport szinkronizálása, amely nem fejezhető be
Az alábbi lépéseket követve megtalálhatja a teljes tranzakciónapló okát, és megoldhatja a problémát.
- A napló csonkálása
- Teljes lemezkötet feloldása
- A napló méretkorlátjának módosítása vagy az automatikus skálázás engedélyezése
1. A napló csonkálása
A probléma gyakori megoldása a tranzakciónaplók biztonsági mentésének biztosítása az adatbázishoz, amely biztosítja a napló csonkítását. Ha a tranzakciónaplók legutóbbi előzményei nem láthatók a teljes tranzakciónaplóval rendelkező adatbázis esetében, a probléma megoldása egyszerű: folytassa az adatbázis tranzakciónaplóinak rendszeres mentéseit.
További információ: A tranzakciónapló-fájl méretének kezelése és a fájl zsugorítása.
A napló csonkolásának magyarázata
Különbség van a tranzakciónapló csonkolása és zsugorítása között. A napló csonkolása általában a tranzakciónapló biztonsági mentése során történik, és egy logikai művelet, amely eltávolítja a naplóban lévő véglegesített rekordokat, míg a naplók zsugorítása a fájlméret csökkentésével visszanyeri a fájlrendszer fizikai területét. A napló csonkolása egy virtuális naplófájl (VLF) határán történik, és egy naplófájl sok virtuális naplófájlt tartalmazhat. A naplófájlok csak akkor zsugorodhatnak, ha üres terület van a naplófájlban a visszaigényléshez. A naplófájlok zsugorítása önmagában nem oldja meg a teljes naplófájlok problémáját. Ehelyett fel kell derítenie, hogy miért van tele a naplófájl, és miért nem csonkítható.
Figyelmeztetés
A fájl zsugorításához áthelyezett adatok a fájl bármely elérhető helyére szétszórhatók. Ez az index töredezettségét okozza, és lelassíthatja az index egy tartományában kereső lekérdezések teljesítményét. A töredezettség megszüntetéséhez fontolja meg a fájl indexeinek újraépítését a zsugorítás után. További információ: Adatbázis zsugorítása.
Mi akadályozza meg a napló csonkolását?
Ha szeretné felderíteni, hogy mi akadályozza meg a napló csonkolását egy adott esetben, használja a log_reuse_wait és a log_reuse_wait_desc oszlopokat a sys.databases katalógusnézetben. További információ: sys.databases. A napló csonkítását késleltető tényezők leírását a tranzakciónaplóban találja.
Az alábbi T-SQL-parancsok segítségével megállapíthatja, hogy az adatbázis tranzakciónaplója nem csonkolt-e, és hogy mi az oka. A következő szkript a probléma megoldásának lépéseit is javasolja:
SET NOCOUNT ON;
DECLARE
@SQL AS VARCHAR (8000),
@log_reuse_wait AS TINYINT,
@log_reuse_wait_desc AS NVARCHAR (120),
@dbname AS SYSNAME,
@database_id AS INT,
@recovery_model_desc AS VARCHAR (24);
IF (OBJECT_id(N'tempdb..#CannotTruncateLog_Db') IS NOT NULL)
BEGIN
DROP TABLE #CannotTruncateLog_Db;
END
--get info about transaction logs in each database.
IF (OBJECT_id(N'tempdb..#dm_db_log_space_usage') IS NOT NULL)
BEGIN
DROP TABLE #dm_db_log_space_usage;
END
SELECT *
INTO #dm_db_log_space_usage
FROM sys.dm_db_log_space_usage
WHERE 1 = 0;
DECLARE log_space CURSOR
FOR SELECT NAME
FROM sys.databases;
OPEN log_space;
FETCH NEXT FROM log_space INTO @dbname;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = '
INSERT INTO #dm_db_log_space_usage (
database_id,
total_log_size_in_bytes,
used_log_space_in_bytes,
used_log_space_in_percent,
log_space_in_bytes_since_last_backup
)
SELECT database_id,
total_log_size_in_bytes,
used_log_space_in_bytes,
used_log_space_in_percent,
log_space_in_bytes_since_last_backup
FROM ' + QUOTENAME(@dbname) + '.sys.dm_db_log_space_usage;';
BEGIN TRY
EXECUTE (@SQL);
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage;
END CATCH
FETCH NEXT FROM log_space INTO @dbname;
END
CLOSE log_space;
DEALLOCATE log_space;
--select the affected databases
SELECT
sdb.name AS DbName,
sdb.log_reuse_wait,
sdb.log_reuse_wait_desc,
CASE
WHEN log_reuse_wait = 1 THEN 'No checkpoint has occurred since the last log truncation, or the head of the log has not yet moved beyond'
WHEN log_reuse_wait = 2 THEN 'A log backup is required before the transaction log can be truncated.'
WHEN log_reuse_wait = 3 THEN 'A data backup or a restore is in progress (all recovery models). Please wait or cancel backup'
WHEN log_reuse_wait = 4 THEN 'A long-running active transaction or a deferred transaction is keeping log from being truncated. You can attempt a log backup to free space or complete/rollback long transaction'
WHEN log_reuse_wait = 5 THEN 'Database mirroring is paused, or under high-performance mode, the mirror database is significantly behind the principal database. (Full recovery model only)'
WHEN log_reuse_wait = 6 THEN 'During transactional replication, transactions relevant to the publications are still undelivered to the distribution database. Investigate the status of agents involved in replication or Changed Data Capture (CDC). (Full recovery model only.)'
WHEN log_reuse_wait = 7 THEN 'A database snapshot is being created. This is a routine, and typically brief, cause of delayed log truncation.'
WHEN log_reuse_wait = 8 THEN 'A transaction log scan is occurring. This is a routine, and typically a brief cause of delayed log truncation.'
WHEN log_reuse_wait = 9 THEN 'A secondary replica of an availability group is applying transaction log records of this database to a corresponding secondary database. (Full recovery model only.)'
WHEN log_reuse_wait = 13 THEN 'If a database is configured to use indirect checkpoints, the oldest page on the database might be older than the checkpoint log sequence number (LSN).'
WHEN log_reuse_wait = 16 THEN 'An In-Memory OLTP checkpoint has not occurred since the last log truncation, or the head of the log has not yet moved beyond a VLF.'
ELSE 'None'
END AS log_reuse_wait_explanation,
sdb.database_id,
sdb.recovery_model_desc,
lsu.used_log_space_in_bytes / 1024. / 1024. AS Used_log_size_MB,
lsu.total_log_size_in_bytes / 1024. / 1024. AS Total_log_size_MB,
100 - lsu.used_log_space_in_percent AS Percent_Free_Space
INTO #CannotTruncateLog_Db
FROM sys.databases AS sdb
INNER JOIN #dm_db_log_space_usage AS lsu
ON sdb.database_id = lsu.database_id
WHERE log_reuse_wait > 0;
SELECT * FROM #CannotTruncateLog_Db;
DECLARE no_truncate_db CURSOR FOR
SELECT
log_reuse_wait,
log_reuse_wait_desc,
DbName,
database_id,
recovery_model_desc
FROM #CannotTruncateLog_Db;
OPEN no_truncate_db;
FETCH NEXT FROM no_truncate_db
INTO
@log_reuse_wait,
@log_reuse_wait_desc,
@dbname,
@database_id,
@recovery_model_desc;
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@log_reuse_wait > 0)
BEGIN
SELECT '-- ' + QUOTENAME(@dbname) + ' database has log_reuse_wait = ' + @log_reuse_wait_desc + ' --' AS 'Individual Database Report';
END
IF (@log_reuse_wait = 1)
BEGIN
SELECT 'Consider running the checkpoint command to attempt resolving this issue or further t-shooting may be required on the checkpoint process. Also, examine the log for active VLFs at the end of file' AS Recommendation;
SELECT 'USE ' + QUOTENAME(@dbname) + '; CHECKPOINT' AS CheckpointCommand;
SELECT 'SELECT * FROM sys.dm_db_log_info(' + CONVERT (VARCHAR, @database_id) + ')' AS VLF_LogInfo;
END
ELSE IF (@log_reuse_wait = 2)
BEGIN
SELECT 'Is ' + @recovery_model_desc + ' recovery model the intended choice for ' + QUOTENAME(@dbname) + ' database? Review recovery models and determine if you need to change it. https://learn.microsoft.com/sql/relational-databases/backup-restore/recovery-models-sql-server' AS RecoveryModelChoice;
SELECT 'To truncate the log consider performing a transaction log backup on database ' + QUOTENAME(@dbname) + ' which is in ' + @recovery_model_desc + ' recovery model. Be mindful of any existing log backup chains that could be broken' AS Recommendation;
SELECT 'BACKUP LOG ' + QUOTENAME(@dbname) + ' TO DISK = ''some_volume:\some_folder\' + QUOTENAME(@dbname) + '_LOG.trn '';' AS BackupLogCommand;
END
ELSE IF (@log_reuse_wait = 3)
BEGIN
SELECT 'Either wait for or cancel any active backups currently running for database ' + QUOTENAME(@dbname) + '. To check for backups, run this command:' AS Recommendation;
SELECT 'SELECT * FROM sys.dm_exec_requests WHERE command LIKE ''backup%'' OR command LIKE ''restore%''' AS FindBackupOrRestore;
END
ELSE IF (@log_reuse_wait = 4)
BEGIN
SELECT 'Active transactions currently running for database ' + QUOTENAME(@dbname) + '. To check for active transactions, run these commands:' AS Recommendation;
SELECT 'DBCC OPENTRAN (' + QUOTENAME(@dbname) + ')' AS FindOpenTran;
SELECT 'SELECT database_id, db_name(database_id) AS dbname, database_transaction_begin_time, database_transaction_state, database_transaction_log_record_count, database_transaction_log_bytes_used, database_transaction_begin_lsn, stran.session_id FROM sys.dm_tran_database_transactions dbtran LEFT OUTER JOIN sys.dm_tran_session_transactions stran ON dbtran.transaction_id = stran.transaction_id WHERE database_id = ' + CONVERT (VARCHAR, @database_id) AS FindOpenTransAndSession;
END
ELSE IF (@log_reuse_wait = 5)
BEGIN
SELECT 'Database Mirroring for database ' + QUOTENAME(@dbname) + ' is behind on synchronization. To check the state of DBM, run the commands below:' AS Recommendation;
SELECT 'SELECT db_name(database_id), mirroring_state_desc, mirroring_role_desc, mirroring_safety_level_desc FROM sys.database_mirroring WHERE mirroring_guid IS NOT NULL and mirroring_state <> 4 AND database_id = ' + CONVERT (sysname, @database_id) AS CheckMirroringStatus;
SELECT 'Database Mirroring for database ' + QUOTENAME(@dbname) + ' may be behind: check unsent_log, send_rate, unrestored_log, recovery_rate, average_delay in this output' AS Recommendation;
SELECT 'EXECUTE msdb.sys.sp_dbmmonitoraddmonitoring 1; EXECUTE msdb.sys.sp_dbmmonitorresults ' + QUOTENAME(@dbname) + ', 5, 0; WAITFOR DELAY ''00:01:01''; EXECUTE msdb.sys.sp_dbmmonitorresults ' + QUOTENAME(@dbname) + '; EXECUTE msdb.sys.sp_dbmmonitordropmonitoring' AS CheckMirroringStatusAnd;
END
ELSE IF (@log_reuse_wait = 6)
BEGIN
SELECT 'Replication transactions still undelivered FROM publisher database ' + QUOTENAME(@dbname) + ' to Distribution database. Check the oldest non-distributed replication transaction. Also check if the Log Reader Agent is running and if it has encountered any errors' AS Recommendation;
SELECT 'DBCC OPENTRAN (' + QUOTENAME(@dbname) + ')' AS CheckOldestNonDistributedTran;
SELECT 'SELECT top 5 * FROM distribution..MSlogreader_history WHERE runstatus in (6, 5) OR error_id <> 0 AND agent_id = find_in_mslogreader_agents_table ORDER BY time desc ' AS LogReaderAgentState;
END
ELSE IF (@log_reuse_wait = 9)
BEGIN
SELECT 'Always On transactions still undelivered FROM primary database ' + QUOTENAME(@dbname) + ' to Secondary replicas. Check the Health of AG nodes and if there is latency is Log block movement to Secondaries' AS Recommendation;
SELECT 'SELECT availability_group = CAST(ag.name AS VARCHAR(30)), primary_replica = CAST(ags.primary_replica AS VARCHAR(30)), primary_recovery_health_desc = CAST(ags.primary_recovery_health_desc AS VARCHAR(30)), synchronization_health_desc = CAST(ags.synchronization_health_desc AS VARCHAR(30)), ag.failure_condition_level, ag.health_check_timeout, automated_backup_preference_desc = CAST(ag.automated_backup_preference_desc AS VARCHAR(10)) FROM sys.availability_groups ag join sys.dm_hadr_availability_group_states ags on ag.group_id=ags.group_id' AS CheckAGHealth;
SELECT 'SELECT group_name = CAST(arc.group_name AS VARCHAR(30)), replica_server_name = CAST(arc.replica_server_name AS VARCHAR(30)), node_name = CAST(arc.node_name AS VARCHAR(30)), role_desc = CAST(ars.role_desc AS VARCHAR(30)), ar.availability_mode_Desc, operational_state_desc = CAST(ars.operational_state_desc AS VARCHAR(30)), connected_state_desc = CAST(ars.connected_state_desc AS VARCHAR(30)), recovery_health_desc = CAST(ars.recovery_health_desc AS VARCHAR(30)), synchronization_health_desc = CAST(ars.synchronization_health_desc AS VARCHAR(30)), ars.last_connect_error_number, last_connect_error_description = CAST(ars.last_connect_error_description AS VARCHAR(30)), ars.last_connect_error_timestamp, primary_role_allow_connections_desc = CAST(ar.primary_role_allow_connections_desc AS VARCHAR(30)) FROM sys.dm_hadr_availability_replica_cluster_nodes arc join sys.dm_hadr_availability_replica_cluster_states arcs on arc.replica_server_name=arcs.replica_server_name join sys.dm_hadr_availability_replica_states ars on arcs.replica_id=ars.replica_id join sys.availability_replicas ar on ars.replica_id=ar.replica_id join sys.availability_groups ag on ag.group_id = arcs.group_id and ag.name = arc.group_name ORDER BY CAST(arc.group_name AS VARCHAR(30)), CAST(ars.role_desc AS VARCHAR(30))' AS CheckReplicaHealth;
SELECT 'SELECT database_name = CAST(drcs.database_name AS VARCHAR(30)), drs.database_id, drs.group_id, drs.replica_id, drs.is_local, drcs.is_failover_ready, drcs.is_pending_secondary_suspend, drcs.is_database_joined, drs.is_suspended, drs.is_commit_participant, suspend_reason_desc = CAST(drs.suspend_reason_desc AS VARCHAR(30)), synchronization_state_desc = CAST(drs.synchronization_state_desc AS VARCHAR(30)), synchronization_health_desc = CAST(drs.synchronization_health_desc AS VARCHAR(30)), database_state_desc = CAST(drs.database_state_desc AS VARCHAR(30)), drs.last_sent_lsn, drs.last_sent_time, drs.last_received_lsn, drs.last_received_time, drs.last_hardened_lsn, drs.last_hardened_time, drs.last_redone_lsn, drs.last_redone_time, drs.log_send_queue_size, drs.log_send_rate, drs.redo_queue_size, drs.redo_rate, drs.filestream_send_rate, drs.end_of_log_lsn, drs.last_commit_lsn, drs.last_commit_time, drs.low_water_mark_for_ghosts, drs.recovery_lsn, drs.truncation_lsn, pr.file_id, pr.error_type, pr.page_id, pr.page_status, pr.modification_time FROM sys.dm_hadr_database_replica_cluster_states drcs join sys.dm_hadr_database_replica_states drs on drcs.replica_id=drs.replica_id and drcs.group_database_id=drs.group_database_id left outer join sys.dm_hadr_auto_page_repair pr on drs.database_id=pr.database_id order by drs.database_id' AS LogMovementHealth;
SELECT 'For more information see https://learn.microsoft.com/troubleshoot/sql/availability-groups/error-9002-transaction-log-large' AS OnlineDOCResource;
END
ELSE IF (@log_reuse_wait IN (10, 11, 12, 14))
BEGIN
SELECT 'This state is not documented and is expected to be rare and short-lived' AS Recommendation;
END
ELSE IF (@log_reuse_wait = 13)
BEGIN
SELECT 'The oldest page on the database might be older than the checkpoint log sequence number (LSN). In this case, the oldest page can delay log truncation.' AS Finding;
SELECT 'This state should be short-lived, but if you find it is taking a long time, you can consider disabling Indirect Checkpoint temporarily' AS Recommendation;
SELECT 'ALTER DATABASE ' + QUOTENAME(@dbname) + ' SET TARGET_RECOVERY_TIME = 0 SECONDS;' AS DisableIndirectCheckpointTemporarily;
END
ELSE IF (@log_reuse_wait = 16)
BEGIN
SELECT 'For memory-optimized tables, an automatic checkpoint is taken when transaction log file becomes bigger than 1.5 GB since the last checkpoint (includes both disk-based and memory-optimized tables)' AS Finding;
SELECT 'Review https://learn.microsoft.com/archive/blogs/sqlcat/logging-and-checkpoint-process-for-memory-optimized-tables-2' AS ReviewBlog;
SELECT 'USE ' + QUOTENAME(@dbname) + '; CHECKPOINT;' AS RunCheckpoint;
END
FETCH NEXT FROM no_truncate_db INTO
@log_reuse_wait,
@log_reuse_wait_desc,
@dbname,
@database_id,
@recovery_model_desc;
END
CLOSE no_truncate_db;
DEALLOCATE no_truncate_db;
Fontos
Ha az adatbázis a 9002-s hiba bekövetkezésekor helyreállítás alatt állt, a probléma megoldása után állítsa helyre az adatbázist az ALTER DATABASE database_name SET ONLINE használatával.
LOG_BACKUP log_reuse_wait
A leggyakrabban megfontolandó művelet, ha látja LOG_BACKUP vagy log_reuse_wait, az adatbázis helyreállítási modelljének áttekintése, és az adatbázis tranzakciónaplójának biztonsági mentése.
Fontolja meg az adatbázis helyreállítási modelljét
Előfordulhat, hogy a tranzakciónaplót nem sikerül csonkítani LOG_BACKUP vagy log_reuse_wait kategóriával, mert még soha nem készítette el a biztonsági másolatát. Sok esetben az adatbázis a FULL vagy BULK_LOGGED helyreállítási modellt használja, de nem készített biztonsági másolatot a tranzakciónaplóról. Gondosan vegye figyelembe az egyes helyreállítási modelleket: végezzen rendszeres tranzakciónapló-mentéseket az összes adatbázison FULL vagy BULK_LOGGED helyreállítási modellben, hogy minimalizálja a 9002-s hiba előfordulását. További információ: Recovery-modellek.
A napló biztonsági mentése
A FULL vagy BULK_LOGGED helyreállítási modell szerint, ha a tranzakciónaplóról nem készült biztonsági másolat a közelmúltban, a biztonsági mentés lehet az, amely megakadályozza a napló csonkolását. A tranzakciós naplóról biztonsági másolatot kell készítenie a naplórekordok felszabadítása és a napló csonkítása lehetővé tétele érdekében. Ha a naplóról még nem készült biztonsági másolat, két biztonsági másolatot kell létrehoznia , hogy az adatbázismotor a naplót az utolsó biztonsági mentés pontjára csonkíthassa. A napló csonkolásával logikai területet szabadít fel az új naplórekordok számára. Ha meg szeretné tartani, hogy a napló újra megteljen, rendszeresen és gyakrabban készítsen biztonsági másolatot a naplókról. További információ: Recovery-modellek.
A rendszer a rendszeradatbázisban tárolja az SQL Server biztonsági mentési és visszaállítási műveleteinek teljes előzményeit.msdb Egy adatbázis teljes biztonsági mentési előzményeinek áttekintéséhez használja a következő példaszkriptet:
SELECT bs.database_name,
CASE
WHEN bs.type = 'D' AND bs.is_copy_only = 0 THEN 'Full Database'
WHEN bs.type = 'D' AND bs.is_copy_only = 1 THEN 'Full Copy-Only Database'
WHEN bs.type = 'I' THEN 'Differential database backup'
WHEN bs.type = 'L' THEN 'Transaction Log'
WHEN bs.type = 'F' THEN 'File or filegroup'
WHEN bs.type = 'G' THEN 'Differential file'
WHEN bs.type = 'P' THEN 'Partial'
WHEN bs.type = 'Q' THEN 'Differential partial'
END + ' Backup' AS backuptype,
bs.recovery_model,
bs.Backup_Start_Date AS BackupStartDate,
bs.Backup_Finish_Date AS BackupFinishDate,
bf.physical_device_name AS LatestBackupLocation,
bs.backup_size / 1024. / 1024. AS backup_size_mb,
bs.compressed_backup_size / 1024. / 1024. AS compressed_backup_size_mb,
database_backup_lsn, -- For tlog and differential backups, this is the checkpoint_lsn of the FULL backup it is based on.
checkpoint_lsn,
begins_log_chain
FROM msdb.dbo.backupset AS bs
LEFT OUTER JOIN msdb.dbo.backupmediafamily AS bf
ON bs.[media_set_id] = bf.[media_set_id]
WHERE recovery_model IN ('FULL', 'BULK-LOGGED')
AND bs.backup_start_date > DATEADD(month, -2, SYSDATETIME()) --only look at last two months
ORDER BY bs.database_name ASC, bs.Backup_Start_Date DESC;
A rendszer a rendszeradatbázisban tárolja az SQL Server biztonsági mentési és visszaállítási műveleteinek teljes előzményeit.msdb A biztonsági mentési előzményekről további információt a Biztonsági mentési előzmények és fejlécadatok (SQL Server) című témakörben talál.
Tranzakciónapló biztonsági mentésének létrehozása
Példa a napló biztonsági mentésére:
BACKUP LOG [dbname] TO DISK = 'some_volume:\some_folder\dbname_LOG.trn';
Fontos
Ha az adatbázis sérült, lásd: Tail-log backups (SQL Server).
Aktív tranzakció log_újrahasználati_várakozás
Az ok elhárításának ACTIVE_TRANSACTION lépései közé tartozik a hosszú ideig futó tranzakció felderítése és feloldása (bizonyos esetekben a KILL parancs használatával).
Hosszú ideig futó tranzakciók felderítése
Egy hosszú ideig futó tranzakció a tranzakciónapló kitöltését okozhatja. A hosszú ideig futó tranzakciók kereséséhez használja az alábbi lehetőségek egyikét:
sys.dm_tran_database_transactions:
Ez a dinamikus felügyeleti nézet az adatbázis szintjén visszaadja a tranzakciók adatait. Hosszú ideig futó tranzakció esetén a fontos oszlopok közé tartozik az első naplórekord (
database_transaction_begin_time), a tranzakció aktuális állapota (database_transaction_state) és a tranzakciónaplóban (LSN) szereplőBEGINrekord naplóütemezési száma (database_transaction_begin_lsnLSN).-
Ez az utasítás lehetővé teszi a tranzakció tulajdonosának felhasználói azonosítójának azonosítását, így a tranzakció forrását is nyomon követheti egy rendezettebb leállítás érdekében (véglegesíti a tranzakciót ahelyett, hogy visszagörgeti).
Tranzakció megszüntetése
Néha csak be kell fejeznie a tranzakciót; lehet, hogy a KILL utasítást kell használnia. Használja az KILL utasítást rendkívül óvatosan, különösen akkor, ha kritikus folyamatok futnak, amelyeket nem szeretne befejezni.
ELLENŐRZŐ PONT log_reuse_wait
Az utolsó naplócsonolás óta nem történt ellenőrzőpont, vagy a napló feje még nem lépte túl a virtuális naplófájlt (VLF) az összes helyreállítási modellben.
Ez egy rutinszerű ok a napló csonkolásának késleltetésére. Ha késik, fontolja meg a CHECKPOINT parancs végrehajtását az adatbázisban, vagy vizsgálja meg a napló virtuális naplófájlokat.
USE dbname;
CHECKPOINT;
SELECT * FROM sys.dm_db_log_info(db_id('dbname'));
ELÉRHETŐSÉGI_PÉLDÁNY napló_újrafelhasználási_várakozás
Ha az elsődleges Always On rendelkezésre állási csoport replikájában végrehajtott tranzakcióváltozások még nem lettek megerősítve a másodlagos replikán, akkor az elsődleges replika tranzakciónaplóját nem lehet csonkolni. Ez a napló növekedéséhez vezethet, és előfordulhat, hogy a másodlagos replika szinkron vagy aszinkron véglegesítési módra van beállítva. Az ilyen típusú hibák elhárításáról a 9002-es hiba című témakörben olvashat. Az adatbázis tranzakciónaplója AVAILABILITY_REPLICA hiba miatt megtelt.
Replikáció, változáskövetés vagy CDC
Az olyan funkciók, mint a replikáció, a változáskövetés és a változásadat-rögzítés (CDC) a tranzakciónaplóra támaszkodnak, így ha a tranzakciók vagy módosítások nem érkeznek meg, megakadályozhatja a tranzakciónapló csonkolását.
DBCC OPENTRAN, Replication Monitor vagy a tárolt eljárások használatával vizsgálja meg és oldja meg a funkciókkal kapcsolatos problémákat változáskövetés és CDC esetén.
Információk a log_reuse_wait tényezőkről
További információkért lásd: A napló csonkítását késleltető tényezők.
2. Teljes lemezkötet feloldása
Bizonyos esetekben előfordulhat, hogy a tranzakciónapló-fájlt tároló lemezkötet megtelik. Az alábbi műveletek egyikével oldhatja meg a napló telítettségét, amit a megtelt lemez okoz:
Szabad lemezterület
Előfordulhat, hogy más fájlok törlésével vagy áthelyezésével szabadíthat fel lemezterületet azon a lemezmeghajtón, amely az adatbázis tranzakciónapló-fájlját tartalmazza. A felszabadított lemezterület lehetővé teszi, hogy a helyreállítási rendszer automatikusan megnövelje a naplófájlt.
A naplófájl áthelyezése másik lemezre
Ha nem tud elegendő lemezterületet felszabadítani azon a meghajtón, amely jelenleg tartalmazza a naplófájlt, fontolja meg a fájl áthelyezését egy másik, elegendő helytel rendelkező meghajtóra.
Fontos
A naplófájlokat soha nem szabad tömörített fájlrendszerekre helyezni.
A naplófájlok helyének módosításáról az adatbázisfájlok áthelyezése című témakörben olvashat.
Naplófájl hozzáadása másik lemezen
Adjon hozzá egy új naplófájlt az adatbázishoz egy másik lemezen, amelyen elegendő hely áll rendelkezésre a használatával ALTER DATABASE <database_name> ADD LOG FILE. Egy adatbázis több naplófájljának ideiglenes feltételnek kell tekinteni a helyproblémák megoldásához, nem pedig hosszú távú feltételnek. A legtöbb adatbázisnak csak egy tranzakciónapló-fájllal kell rendelkeznie. Folytassa a vizsgálatot annak érdekében, hogy megértse, miért telt meg a tranzakciónapló, és miért nem csonkolható. Fontolja meg, hogy csak speciális hibaelhárítási lépésként adjon hozzá további ideiglenes tranzakciónapló-fájlokat.
További információ: Adatok vagy naplófájlok hozzáadása adatbázishoz.
Segédprogramszkript az ajánlott műveletekhez
Ezek a lépések részben automatizálhatók a következő T-SQL-szkript futtatásával a lemezterület nagy százalékát használó naplófájlok azonosításához, és műveleteket javasolnak:
DECLARE @log_reached_disk_size AS BIT = 0;
SELECT [name] AS LogName,
physical_name,
CONVERT (BIGINT, size) * 8 / 1024 AS LogFile_Size_MB,
volume_mount_point,
available_bytes / 1024 / 1024 AS Available_Disk_space_MB,
(CONVERT (BIGINT, size) * 8.0 / 1024) / (available_bytes / 1024 / 1024) * 100 AS file_size_as_percentage_of_disk_space,
db_name(mf.database_id) AS DbName
FROM sys.master_files AS mf
CROSS APPLY sys.dm_os_volume_stats(mf.database_id, file_id)
WHERE mf.[type_desc] = 'LOG'
AND (CONVERT (BIGINT, size) * 8.0 / 1024) / (available_bytes / 1024 / 1024) * 100 > 90 --log is 90% of disk drive
ORDER BY size DESC;
IF @@ROWCOUNT > 0
BEGIN
SET @log_reached_disk_size = 1;
-- Discover if any logs have filled the volume they reside on, or are close to filling the volume.
-- Either add a new file to a new drive, or shrink an existing file.
-- If it cannot shrink, direct the script to recommend next steps.
DECLARE @db_name_filled_disk AS sysname, @log_name_filled_disk AS sysname, @go_beyond_size AS BIGINT;
DECLARE log_filled_disk CURSOR
FOR SELECT db_name(mf.database_id),
name
FROM sys.master_files AS mf
CROSS APPLY sys.dm_os_volume_stats(mf.database_id, file_id)
WHERE mf.[type_desc] = 'LOG'
AND (CONVERT (BIGINT, size) * 8.0 / 1024) / (available_bytes / 1024 / 1024) * 100 > 90 --log is 90% of disk drive
ORDER BY size DESC;
OPEN log_filled_disk;
FETCH NEXT FROM log_filled_disk INTO @db_name_filled_disk, @log_name_filled_disk;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT 'Transaction log for database "' + @db_name_filled_disk + '" has nearly or completely filled disk volume it resides on!' AS Finding;
SELECT 'Consider using one of the below commands to shrink the "' + @log_name_filled_disk + '" transaction log file size or add a new file to a NEW volume' AS Recommendation;
SELECT 'DBCC SHRINKFILE(''' + @log_name_filled_disk + ''')' AS Shrinkfile_Command;
SELECT 'ALTER DATABASE ' + @db_name_filled_disk + ' ADD LOG FILE ( NAME = N''' + @log_name_filled_disk + '_new'', FILENAME = N''NEW_VOLUME_AND_FOLDER_LOCATION\' + @log_name_filled_disk + '_NEW.LDF'', SIZE = 81920KB , FILEGROWTH = 65536KB )' AS AddNewFile;
SELECT 'If shrink does not reduce the file size, likely it is because it has not been truncated. Please review next section below. See https://learn.microsoft.com/sql/t-sql/database-console-commands/dbcc-shrinkfile-transact-sql' AS TruncateFirst;
SELECT 'Can you free some disk space on this volume? If so, do this to allow for the log to continue growing when needed.' AS FreeDiskSpace;
FETCH NEXT FROM log_filled_disk INTO @db_name_filled_disk, @log_name_filled_disk;
END
CLOSE log_filled_disk;
DEALLOCATE log_filled_disk;
END
3. A napló méretkorlátjának módosítása vagy az automatikus méretezés engedélyezése
A 9002-es hiba akkor hozható létre, ha a tranzakciónapló mérete felső korlátra van állítva, vagy ha az automatikus növekedési funkció nem engedélyezett. Ebben az esetben az automatikus feltöltés engedélyezése vagy a naplóméret manuális növelése segíthet a probléma megoldásában. Ezzel a T-SQL-paranccsal keresse meg az ilyen naplófájlokat, és kövesse a megadott javaslatokat:
SELECT DB_NAME(database_id) AS DbName,
name AS LogName,
physical_name,
type_desc,
CONVERT (BIGINT, SIZE) * 8 / 1024 AS LogFile_Size_MB,
CONVERT (BIGINT, max_size) * 8 / 1024 AS LogFile_MaxSize_MB,
(SIZE * 8.0 / 1024) / (max_size * 8.0 / 1024) * 100 AS percent_full_of_max_size,
CASE WHEN growth = 0 THEN 'AUTOGROW_DISABLED' ELSE 'Autogrow_Enabled' END AS AutoGrow
FROM sys.master_files
WHERE file_id = 2
AND (SIZE * 8.0 / 1024) / (max_size * 8.0 / 1024) * 100 > 90
AND max_size NOT IN (-1, 268435456)
OR growth = 0;
IF @@ROWCOUNT > 0
BEGIN
DECLARE @db_name_max_size AS sysname, @log_name_max_size AS sysname, @configured_max_log_boundary AS BIGINT, @auto_grow AS INT;
DECLARE reached_max_size CURSOR
FOR SELECT db_name(database_id),
name,
CONVERT (BIGINT, SIZE) * 8 / 1024,
growth
FROM sys.master_files
WHERE file_id = 2
AND ((SIZE * 8.0 / 1024) / (max_size * 8.0 / 1024) * 100 > 90
AND max_size NOT IN (-1, 268435456)
OR growth = 0);
OPEN reached_max_size;
FETCH NEXT FROM reached_max_size INTO @db_name_max_size, @log_name_max_size, @configured_max_log_boundary, @auto_grow;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @auto_grow = 0
BEGIN
SELECT 'The database "' + @db_name_max_size + '" contains a log file "' + @log_name_max_size + '" whose autogrow has been DISABLED' AS Finding;
SELECT 'Consider enabling autogrow or increasing file size via these ALTER DATABASE commands' AS Recommendation;
SELECT 'ALTER DATABASE ' + @db_name_max_size + ' MODIFY FILE ( NAME = N''' + @log_name_max_size + ''', FILEGROWTH = 65536KB)' AS AutoGrowth;
END
ELSE
BEGIN
SELECT 'The database "' + @db_name_max_size + '" contains a log file "' + @log_name_max_size + '" whose max limit is set to ' + CONVERT (VARCHAR (24), @configured_max_log_boundary) + ' MB and this limit has been reached!' AS Finding;
SELECT 'Consider using one of the below ALTER DATABASE commands to either change the log file size or add a new file' AS Recommendation;
END
SELECT 'ALTER DATABASE ' + @db_name_max_size + ' MODIFY FILE ( NAME = N''' + @log_name_max_size + ''', MAXSIZE = UNLIMITED)' AS UnlimitedSize;
SELECT 'ALTER DATABASE ' + @db_name_max_size + ' MODIFY FILE ( NAME = N''' + @log_name_max_size + ''', MAXSIZE = something_larger_than_' + CONVERT (VARCHAR (24), @configured_max_log_boundary) + 'MB )' AS IncreasedSize;
SELECT 'ALTER DATABASE ' + @db_name_max_size + ' ADD LOG FILE ( NAME = N''' + @log_name_max_size + '_new'', FILENAME = N''SOME_FOLDER_LOCATION\' + @log_name_max_size + '_NEW.LDF'', SIZE = 81920KB , FILEGROWTH = 65536KB )' AS AddNewFile;
FETCH NEXT FROM reached_max_size INTO @db_name_max_size, @log_name_max_size, @configured_max_log_boundary, @auto_grow;
END
CLOSE reached_max_size;
DEALLOCATE reached_max_size;
END
ELSE
SELECT 'Found no files that have reached max log file size' AS Findings;
A naplófájl méretének növelése vagy az automatikus kitöltés engedélyezése
Ha a naplólemezen szabad hely áll rendelkezésre, növelheti a naplófájl méretét. A naplófájlok maximális mérete naplófájlonként 2 terabájt (TB).
Ha az automatikus helyreállítás le van tiltva, az adatbázis online állapotban van, és elegendő hely áll rendelkezésre a lemezen, fontolja meg a következő lépéseket:
Manuálisan növelje a fájlméretet egy egyszeri növekedési fázis létrehozásához. Ezek általános javaslatok a naplóméret növekedésével és méretével kapcsolatban.
Kapcsolja be az automatikus növekedést az
ALTER DATABASEutasítással, hogy aFILEGROWTHopcióhoz nem nulla növekedési növekményt állítson be. Tekintse meg az SQL Server automatikus növelési és zsugorítási beállításaira vonatkozó szempontokat ismertető cikket.
Megjegyzés:
Ha eléri az aktuális méretkorlátot, mindkét esetben növelje az MAXSIZE értéket.