分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 原文:分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据 今天开发找我,说数据库insert不进数据,叫我看一下 他发了一个截图给我 然后我登录上服务器,发现了可疑的地方,而且这个数据库之前有一段经历 在...
原文: 分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据

分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据

今天开发找我,说数据库insert不进数据,叫我看一下

他发了一个截图给我

然后我登录上服务器,发现了可疑的地方,而且这个数据库之前有一段经历

在月初的时候这个数据库曾经置疑过,启动不起来

Could not redo log record (163041:116859:5), for transaction ID (0:-1175226963), on page (17:20633999), database 'xxrchives' (database ID 7). Page: LSN = (162930:20671:38), type = 2. Log: OpCode = 2, context 3, PrevPageLSN: (163041:116230:18). Restore from a backup of the database, or repair the database.

During redoing of a logged operation in database 'xxxrchives', an error occurred at log record ID (163041:116859:5). Typically, the specific failure is previously logged as an error in the Windows Event Log service. Restore the database from a full backup, or repair the database.

An error occurred during recovery, preventing the database 'xxxrchives' (database ID 7) from restarting. Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not corrected or expected, contact Technical Support.

Setting database option EMERGENCY to ON for database xxxchives.

The database 'xxxxchives' is marked EMERGENCY_MODE and is in a state that does not allow recovery to be run.

由于一些特殊的原因没有做备份,数据库大小差不多3TB,这里3TB是已经除去可用空间的了,里面只有几张表,其中只有一张大表

修复语句如下

USE MASTER
GO
ALTER DATABASE [xxxrchives] SET EMERGENCY
GO
ALTER DATABASE [xxxxchives] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
DBCC CHECKDB('xxxxchives','REPAIR_ALLOW_DATA_LOSS') with tablock
GO
ALTER DATABASE [xxxxchives] SET ONLINE
GO
ALTER DATABASE [xxxxchives] SET MULTI_USER
GO

数据相对来说不是非常重要,允许丢失一些数据

结果运行了差不多7天,业务也一度中断了

其实有数据库完整备份的话可以使用页面还原的方法还原有问题的页面,加上日志备份,而不用这么大工程的。。。

 

有经验的SQLSERVER管理员应该知道最后我使用的方法如何抛弃有824错误的页面,只保留正常的数据页面,这个大表是做了表分区的,由于篇幅关系这里不具体说了

消息 824,级别 24,状态 2,第 3 行
SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 6:33780000,但实际为 0:0)。在文件 'E:\DataBase\FG_xxxxive\FG_xxxxhive_Id_04_data.ndf' 中、偏移量为 0x0000406e240000 的位置对数据库 ID 7 中的页 (6:33780000) 执行 读取 期间,发生了该错误。SQL Server 错误日志或系统事件日志中的其他消息可能提供了更详细信息。这是一个威胁数据库完整性的严重错误条件,必须立即纠正。请执行完整的数据库一致性检查(DBCC CHECKDB)。此错误可以由许多因素导致;有关详细信息,请参阅 SQL Server 联机丛书。

 


问题所在

这个数据库运行在SQL2008上面,一直都是简单模式,那么问题来了,由于当时checkdb的时间很长,积累了大量事务日志

但是,按道理处于简单模式会自动截断日志的,但是当时本人也没有看,心里只想着数据库马上online

 

步骤一:今天开发找我插不进去数据也是因为这个,我运行了下面语句,这个语句是我找问题的时候一般都先用这个语句,因为在徐海蔚老师的书里面也建议先使用这个语句

SELECT * FROM sys.[sysprocesses] 

结果发现

相当多的log等待

 

步骤二:我再运行下面脚本

-- =============================================
-- Author:      <桦仔>
-- Blog:        <http://www.cnblogs.com/lyhabc/>
-- Create date: <2014/4/18>
-- Description: <统计各个数据库的总大小V2 不包含数据文件>
-- =============================================
SET NOCOUNT ON 
USE master
GO

DECLARE @DBNAME NVARCHAR(MAX)
DECLARE @SQL NVARCHAR(MAX)



--临时表保存数据
CREATE TABLE #DataBaseServerData
(
  ID INT IDENTITY(1, 1) ,
  DBNAME NVARCHAR(MAX) ,
  Log_Total_MB DECIMAL(18, 1) NOT NULL ,
  Log_FREE_SPACE_MB DECIMAL(18, 1) NOT NULL 
)



--游标
DECLARE @itemCur CURSOR
SET 
@itemCur = CURSOR FOR 
SELECT name from   SYS.[sysdatabases] WHERE [name] NOT IN ('MASTER','MODEL','TEMPDB','MSDB','ReportServer','ReportServerTempDB')


OPEN @itemCur
FETCH NEXT FROM @itemCur INTO @DBNAME
WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @SQL=N'USE ['+@DBNAME+'];'+CHAR(10)
    +
    'INSERT  [#DataBaseServerData]
                ( [DBNAME] ,
                  [Log_Total_MB] ,
          [Log_FREE_SPACE_MB ] 
                )
                SELECT '''+@DBNAME+''', str(sum(convert(dec(17,2),sysfiles.size)) / 128,10,2) AS Total_MB,
                SUM(( database_files.size - FILEPROPERTY(database_files.name, ''SpaceUsed'') )) / 128.0 AS free_space_mb
                FROM    dbo.sysfiles as sysfiles INNER JOIN sys.database_files as database_files ON sysfiles.[fileid]=database_files.[file_id] WHERE sysfiles.[groupid]  =0
                AND database_files.[type] = 1;'
        EXEC (@SQL)
        FETCH NEXT FROM @itemCur INTO @DBNAME
    END 

CLOSE @itemCur
DEALLOCATE @itemCur

SELECT  *  FROM    [#DataBaseServerData]
DROP TABLE [#DataBaseServerData]

结果发现

上百G的日志文件

 

 

步骤三:我使用数据分析脚本也发现表里面的数据没有增加,按F5刷新了很多次

--数据分析

CREATE TABLE #tablespaceinfo
    (
      nameinfo VARCHAR(50) ,
      rowsinfo BIGINT ,
      reserved VARCHAR(20) ,
      datainfo VARCHAR(20) ,
      index_size VARCHAR(20) ,
      unused VARCHAR(20)
    )  
 
DECLARE @tablename VARCHAR(255);  
 
DECLARE Info_cursor CURSOR
FOR
    SELECT  '[' + [name] + ']'
    FROM    sys.tables
    WHERE   type = 'U';  
 
OPEN Info_cursor  
FETCH NEXT FROM Info_cursor INTO @tablename  
 
WHILE @@FETCH_STATUS = 0
    BEGIN 
        INSERT  INTO #tablespaceinfo
                EXEC sp_spaceused @tablename  
        FETCH NEXT FROM Info_cursor  
    INTO @tablename  
    END 
 
CLOSE Info_cursor  
DEALLOCATE Info_cursor  
 
--创建临时表
CREATE TABLE [#tmptb]
    (
      TableName VARCHAR(50) ,
      DataInfo BIGINT ,
      RowsInfo BIGINT ,
      Spaceperrow  AS ( CASE RowsInfo
                         WHEN 0 THEN 0
                         ELSE CAST(DataInfo AS decimal(18,2))/CAST(RowsInfo AS decimal(18,2))
                       END ) PERSISTED
    )

--插入数据到临时表
INSERT  INTO [#tmptb]
        ( [TableName] ,
          [DataInfo] ,
          [RowsInfo]
        )
        SELECT  [nameinfo] ,
                CAST(REPLACE([datainfo], 'KB', '') AS BIGINT) AS 'datainfo' ,
                [rowsinfo]
        FROM    #tablespaceinfo
        ORDER BY CAST(REPLACE(reserved, 'KB', '') AS BIGINT) DESC  


--汇总记录
SELECT  [tbspinfo].* ,
        [tmptb].[Spaceperrow] AS '每行记录大概占用空间(KB)'
FROM    [#tablespaceinfo] AS tbspinfo ,
        [#tmptb] AS tmptb
WHERE   [tbspinfo].[nameinfo] = [tmptb].[TableName]
ORDER BY CAST(REPLACE([tbspinfo].[reserved], 'KB', '') AS BIGINT) DESC  

DROP TABLE [#tablespaceinfo]
DROP TABLE [#tmptb]
View Code

 

 

步骤四下面检查 VLF

DBCC LOGINFO
View Code

有400多个VLF

 

 

步骤五:检查一下log为什么不能重用的原因

SELECT  DB_NAME([database_id]) AS dbname ,
        [log_reuse_wait] ,
        [log_reuse_wait_desc]
FROM    sys.[databases]

结果发现 数据库做了复制,我接手的时候这个数据库是不需要复制的,可能是以前的同事弄的

 

步骤六:我使用博客园里面i6first大牛的文章把复制干掉《你还可以再诡异点吗——SQL日志文件不断增长

EXEC sp_removedbreplication [xxxchives]

 

步骤七:然后再来收缩日志

USE [xxxxchives]
GO
DBCC SHRINKFILE (N'xxxxxchives_log' , 5000)
GO

 

弄完之后,数据库正常了,没有log等待,数据也在不断增加


总结

简单几个步骤:从发现问题到解决问题,有些人可能半天才能解决,有些人几分钟就可以解决,这就是积累经验的重要性

我自己的做法是多看书,多看博客园,在QQ群里看一下大家的问题,这就是经验了,快速解决问题的经验

 

本人也喜欢将工作中遇到的问题写在博客里面,以供大家参考,大家一起进步o(∩_∩)o 

 

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
21天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1585 14
|
25天前
|
数据采集 机器学习/深度学习 存储
使用 Python 清洗日志数据
使用 Python 清洗日志数据
28 2
|
2月前
|
SQL 人工智能 运维
在阿里云日志服务轻松落地您的AI模型服务——让您的数据更容易产生洞见和实现价值
您有大量的数据,数据的存储和管理消耗您大量的成本,您知道这些数据隐藏着巨大的价值,但是您总觉得还没有把数据的价值变现出来,对吗?来吧,我们用一系列的案例帮您轻松落地AI模型服务,实现数据价值的变现......
180 3
|
2月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
96 0
|
3月前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
119 0
|
3月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
96 0
|
3月前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
50 0
|
3月前
|
开发者 前端开发 编解码
Vaadin解锁移动适配新境界:一招制胜,让你的应用征服所有屏幕!
【8月更文挑战第31天】在移动互联网时代,跨平台应用开发备受青睐。作为一款基于Java的Web应用框架,Vaadin凭借其组件化设计和强大的服务器端渲染能力,助力开发者轻松构建多设备适应的Web应用。本文探讨Vaadin与移动设备的适配策略,包括响应式布局、CSS媒体查询、TouchKit插件及服务器端优化,帮助开发者打造美观且实用的移动端体验。通过这些工具和策略的应用,可有效应对屏幕尺寸、分辨率及操作系统的多样性挑战,满足广大移动用户的使用需求。
53 0
|
3月前
|
存储 运维 监控
Entity Framework Core 实现审计日志记录超棒!多种方法助你跟踪数据变化、监控操作,超实用!
【8月更文挑战第31天】在软件开发中,审计日志记录对于跟踪数据变化、监控用户操作及故障排查至关重要。Entity Framework Core (EF Core) 作为强大的对象关系映射框架,提供了多种实现审计日志记录的方法。例如,可以使用 EF Core 的拦截器在数据库操作前后执行自定义逻辑,记录操作类型、时间和执行用户等信息。此外,也可通过在实体类中添加审计属性(如 `CreatedBy`、`CreatedDate` 等),并在保存实体时更新这些属性来记录审计信息。这两种方法都能有效帮助我们追踪数据变更并满足合规性和安全性需求。
55 0
|
3月前
|
SQL 安全 测试技术
【数据守护者必备】SQL数据备份与恢复策略全解析:从全量到日志备份,手把手教你确保企业信息万无一失的实战技巧!
【8月更文挑战第31天】数据库是企业核心业务数据的基石,为防止硬件故障、软件错误或人为失误导致的数据丢失,制定可靠的备份与恢复策略至关重要。本文通过一个在线购物平台的案例,详细介绍了使用 SQL Server 进行全量备份、差异备份及事务日志备份的方法,并演示了如何利用 SQL Server Agent 实现自动化备份任务。此外,还提供了数据恢复的具体步骤和测试建议,确保数据安全与业务连续性。
112 0