标签: transaction-log

SQL Server如何解决将列更新为int时填满的事务日志

我有一个名为 SQL Server 2005 的表BRITTNEY_SPEARS_MARRIAGES,它具有以下列:

MarrigeId tinyint, 
HusbandName varchar(500),
MarrigeLength int
Run Code Online (Sandbox Code Playgroud)

现在我有另一张桌子 BRITTNEY_SPEARS_MARRIAGE_STORIES

StoryId int, 
MarriageId tinyint, 
StoryText nvarchar(max)
Run Code Online (Sandbox Code Playgroud)

问题是我们想将MarrigeId列int从 a更新为a tinyint。我们只是觉得布兰妮在一切都说完和做完之前会有很多婚姻。

现在BRITTNEY_SPEARS_MARRIAGE_STORIES表中有 1800 万行(嘿,这个女孩有一些问题),所以当我们进行更新时,事务日志填满了,我们的 SQL Server 框就死了。

我们怎样才能解决这个问题?

无论如何,是否可以说“嘿 SQL Server,我将更新此列并使其更大。相信我在此 SQL Server 上。请不要在尝试验证所有内容时填写事务日志?”

sql-server-2005 sql-server transaction-log

18
推荐指数
2
解决办法
6965
查看次数

使用 AlwaysOn 可用性组时收缩事务日志

我们正在使用AlwaysOn Availability GroupSQL Server 2012 的功能。每天都会在辅助数据库上进行定期的完整数据库备份和事务日志备份。

我在这里读到在主副本或辅助副本上执行事务日志备份会将两个副本的事务日志标记为可重用。无论如何,事务日志备份大小很大,可以使用收缩文件来减少:

在此处输入图片说明

我已经在本地恢复了数据库并执行了收缩操作。日志文件大小减少到 160 MB。

我的问题是我应该在哪个数据库上对事务日志文件(主要、次要或两者)执行收缩操作?


我猜过去几年没有备份日志文件,所以它变得如此庞大。执行DBCC SQLPERF (LOGSPACE)我可以看到只0.06%使用了文件 - 我没有必要保留这么大的日志文件。在[sys].[database_files]我检查其max_size设置为-1与growth对65536,所以我想,当它需要更多的空间,它会得到。无论如何,我可以将其缩小到例如 5% 以防止未来的增长。我试图找到一些确认,我这样做不是坏主意。


实际上,备份(对数据库和日志文件)仅在辅助数据库上执行,因此对它们执行收缩文件会更容易,但是主日志文件的大小也会减小吗?

sql-server shrink sql-server-2012 transaction-log

17
推荐指数
2
解决办法
7万
查看次数

MySQL中事务日志和重做日志的区别

我已经阅读了有关 MySQL 的内容。在我看来,我认为两种日志类型非常相似。MySQL 在日志中保存数据更改的方式和时间。信息用于 MySQL 的恢复。我混淆了两种日志类型的功能。

mysql transaction-log

16
推荐指数
1
解决办法
2万
查看次数

Transaction Log 不会收缩,DB 认为它在复制

我有一个运行 Kaspersky Security Center 的 SQL Server 2008 R2 Express 数据库,我不知道安装是在什么情况下发生的,但数据库似乎认为它正在被复制并且不会从事务日志中释放任何空间。例如:

USE master;

SELECT 
    name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
FROM 
    sys.databases 
WHERE 
    name = 'KAV';

SELECT DATABASEPROPERTYEX('KAV', 'IsPublished');
Run Code Online (Sandbox Code Playgroud)

返回:

name | log_reuse_wait | log_reuse_wait_desc | is_cdc_enabled
-----|----------------|---------------------|---------------
KAV  | 6              | REPLICATION         | 0 
Run Code Online (Sandbox Code Playgroud)
DATABASEPROPERTYEX('KAV', 'IsPublished')
----------------------------------------
0 [not published]
Run Code Online (Sandbox Code Playgroud)

ReplicationSSMS的部分中也没有列出任何内容。

到目前为止,我已经尝试了从 Google 结果中收集到的几个语句:

USE KAV;
EXEC sp_repldone null, null, 0,0,1;
EXEC sp_removedbreplication KAV;
Run Code Online (Sandbox Code Playgroud)

但是我没有运气让这个数据库停止认为它正在被复制。

完整sys.databases信息:

USE master;

SELECT 
    name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
FROM 
    sys.databases 
WHERE 
    name = …
Run Code Online (Sandbox Code Playgroud)

replication sql-server transaction-log

16
推荐指数
2
解决办法
2万
查看次数

为什么 CHECKDB 读取具有内存优化表的数据库上的事务日志文件?

tl; dr:为什么 CHECKDB 读取具有内存优化表的用户数据库的事务日志?


CHECKDB 在检查我的一个数据库时似乎正在读取用户数据库的事务日志文件 - 特别是使用内存中 OLTP 表的数据库。

这个数据库的 CHECKDB 仍然在合理的时间内完成,所以我主要只是对这种行为感到好奇;但这绝对是该实例上所有数据库中 CHECKDB 持续时间最长的。

在查看 Paul Randal 的史诗“ CHECKDB From Every Angle:所有 CHECKDB 阶段的完整描述”时,我看到 SQL 2005 之前的 CHECKDB用于读取日志以获得一致的数据库视图。但由于这是 2016 年,它使用内部数据库快照。

但是,快照的先决条件之一是:

源数据库不得包含 MEMORY_OPTIMIZED_DATA 文件组

我的用户数据库有这些文件组之一,所以看起来快照不在表中。

根据CHECKDB 文档:

如果无法创建快照,或者指定了 TABLOCK,DBCC CHECKDB 将获取锁以获得所需的一致性。在这种情况下,需要一个排他数据库锁来执行分配检查,并且需要共享表锁来执行表检查。

好的,所以我们正在做数据库和表锁定而不是快照。但这仍然不能解释为什么它必须读取事务日志。那么什么给呢?

我在下面提供了一个脚本来重现该场景。它用于sys.dm_io_virtual_file_stats识别日志文件读取。

请注意,大多数时候它读取日志的一小部分 (480 KB),但偶尔读取更多 (48.2 MB)。在我的生产场景中,当我们运行 CHECKDB 时,它会在每晚午夜读取大部分日志文件(2 GB 文件中的约 1.3 GB)。

以下是我目前使用脚本获得的输出示例:

collection_time            num_of_reads     num_of_bytes_read
2018-04-04 15:12:29.203    106              50545664
Run Code Online (Sandbox Code Playgroud)

或这个:

collection_time            num_of_reads     num_of_bytes_read …
Run Code Online (Sandbox Code Playgroud)

sql-server transaction-log dbcc-checkdb sql-server-2016

16
推荐指数
1
解决办法
815
查看次数

无法从完整备份恢复 SQL Server 数据库,日志处理失败,数据库处于“正在恢复”状态

我正在尝试在我 PC 的本地 SQL Server Developer Edition 12.0.2000.8 上设置用于开发目的的数据库。我有一个完整的数据库备份和单独的事务日志备份文件,它们通过网络发送给我。

尝试从完整备份恢复时,一段时间后(大约 1 小时,数据库大小约为 270 GB),出现错误:

System.Data.SqlClient.SqlError: 处理数据库“数据库名称”的日志时出错。如果可能,从备份中恢复。如果备份不可用,则可能需要重建日志。(Microsoft.SqlServer.SmoExtended)

在此之后,数据库处于“正在恢复..”状态。

我想运行类似的东西(从这个问题中得到)

ALTER DATABASE recovery_test_2 SET EMERGENCY;
ALTER DATABASE recovery_test_2 SET SINGLE_USER;

DBCC CHECKDB (recovery_test_2, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS, ALL_ERRORMSGS;
Run Code Online (Sandbox Code Playgroud)

反对它,但自然我不能,因为数据库处于“正在恢复......”状态。重新启动恢复过程会导致相同的错误消息,再次删除和恢复也无济于事。

我如何启动数据库并开始工作?事务一致性对我来说并不重要。

SSMS 自动生成的恢复脚本:

  USE [master]
  RESTORE DATABASE [database_name] FROM  DISK = N'D:\database_name.bak' WITH  FILE = 1,
  MOVE N'database_name' TO N'D:\MSSQL\MSSQL12.MSSQLSERVER\MSSQL\DATA\database_name.mdf',
  MOVE N'database_name_index' TO N'D:\MSSQL\MSSQL12.MSSQLSERVER\MSSQL\DATA\database_name_index.ndf',
  MOVE N'database_name_log' TO N'D:\MSSQL\MSSQL12.MSSQLSERVER\MSSQL\DATA\database_name_log.ldf',
  NOUNLOAD,
  STATS = 5

  GO
Run Code Online (Sandbox Code Playgroud)

@Craig Efrein 建议的查询结果

无法重建日志,因为在数据库关闭时有打开的事务/用户,数据库没有发生检查点,或者数据库是只读的。如果由于硬件或环境故障手动删除或丢失事务日志文件,则可能会发生此错误。

sql-server restore transaction-log sql-server-2014

15
推荐指数
1
解决办法
2985
查看次数

为什么在插入索引表时没有获得最少的日志记录

我正在测试不同场景中的最少日志记录插入,并且从我读到的 INSERT INTO SELECT 到带有非聚集索引的堆中,使用 TABLOCK 和 SQL Server 2016+ 应该最少记录,但是在我的情况下,这样做时我得到完整记录。我的数据库处于简单恢复模型中,我成功地在没有索引和 TABLOCK 的堆上获得了最少记录的插入。

我正在使用 Stack Overflow 数据库的旧备份进行测试,并使用以下架构创建了 Posts 表的副本...

CREATE TABLE [dbo].[PostsDestination](
    [Id] [int] NOT NULL,
    [AcceptedAnswerId] [int] NULL,
    [AnswerCount] [int] NULL,
    [Body] [nvarchar](max) NOT NULL,
    [ClosedDate] [datetime] NULL,
    [CommentCount] [int] NULL,
    [CommunityOwnedDate] [datetime] NULL,
    [CreationDate] [datetime] NOT NULL,
    [FavoriteCount] [int] NULL,
    [LastActivityDate] [datetime] NOT NULL,
    [LastEditDate] [datetime] NULL,
    [LastEditorDisplayName] [nvarchar](40) NULL,
    [LastEditorUserId] [int] NULL,
    [OwnerUserId] [int] NULL,
    [ParentId] [int] NULL,
    [PostTypeId] [int] NOT NULL,
    [Score] [int] NOT NULL,
    [Tags] …
Run Code Online (Sandbox Code Playgroud)

sql-server transaction-log

14
推荐指数
2
解决办法
1690
查看次数

在日志备份期间,数据是备份到操作开始还是结束?

假设我正在运行日志备份,并且该日志备份需要 10 分钟才能完成。在这 10 分钟的窗口中,将运行进一步的事务。鉴于以下示例,日志备份实际上包含哪些事务?

  1. 事务 A 提交
  2. 事务 B 打开
  3. 日志备份开始
  4. 交易 C 开启
  5. 事务 B 提交
  6. 日志备份完成
  7. 事务 C 提交

sql-server backup sql-server-2012 transaction-log

14
推荐指数
2
解决办法
715
查看次数

DBCC CHECKDB 每 20 - 60 秒触发一次

我有一个开发环境,它正在快速部署到生产环境中,并且在日志中注意到大约每 20 秒我就会看到一条消息:

Starting up database 'dbname'
CHECKDB for database 'dbname' finished without errors
Run Code Online (Sandbox Code Playgroud)

我注意到这一点是因为正在测试它的最终用户有一个问题,我将其与我在 Windows 事件日志(应用程序日志)中注意到的错误隔离开来:

The log for database 'dbname' is not available. Check event log for related messages.
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我没有发现相关消息,但通过离线/在线循环解决了。

我唯一能想到的是,这个应用程序每 1 毫秒收集一次数据,但所有这些数据都没有插入到数据库中。作为一个开发服务器,它被配置为日志和数据在同一个驱动器上。考虑到这两条信息,我倾向于这是一个 IO 问题,并且服务器正试图从与存储 (SAN) 的连接丢失中恢复。然而,即使这对我来说也没有意义,因为它并没有丢失所有 dbs,只是丢失了这个。还有什么可能导致这种情况?

平台:Windows Server 2008 R2 (Std.) 上的 SQL Server 2008 R2 (Ent.)

sql-server sql-server-2008-r2 transaction-log

13
推荐指数
1
解决办法
5746
查看次数

这两个 SQL Server 回滚有何不同?

在 SQL Server 2008 R2 中,这两种回滚有何不同:

  1. 运行一条ALTER语句几分钟,然后点击“取消执行”。完全回滚需要几分钟时间。

  2. 运行相同的ALTER语句,但这要确保LDF文件不够大,无法成功完成。一旦达到LDF限制并且不允许“自动增长”,查询执行将立即停止(或发生回滚)并显示以下错误消息:

The statement has been terminated.
Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'SampleDB' is full. 
To find out why space in the log cannot be reused, see the 
log_reuse_wait_desc column in sys.databases
Run Code Online (Sandbox Code Playgroud)

这两者在以下几点上有何不同?

  1. 为什么第二次“回滚”是瞬时的?我不完全确定它是否可以称为回滚。我的猜测是,事务日志是随着执行的进行而写入的,一旦它意识到没有足够的空间来完全完成任务,它就会停止并显示一些“结束”消息,而不提交。

  2. 当第一次回滚花费这么多时间(回滚单线程)时会发生什么?
    2.1. SQL Server 会返回并撤消LDF文件中的条目吗?
    2.2. 该LDF文件大小在回滚结束变得更小(从DBCC SQLPERF(LOGSPACE))

  3. 另一个问题:在第二种情况下,SQL Server 开始使用LDF文件的速度非常快。就我而言,它在前几分钟(< 4 分钟)内从 18% 的使用率增加到 90% …

sql-server sql-server-2008-r2 database-internals rollback transaction-log

13
推荐指数
1
解决办法
543
查看次数