分享工作中遇到的问题积累经验 事务日志太大导致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]

步骤四:下面检查 VLF

DBCC LOGINFO

有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 

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

  1. 第16周翻译:SQL Server中的事务日志管理,级别3:事务日志、备份和恢复

    源自: http://www.sqlservercentral.com/articles/Stairway+Series/73779/ 作者: Tony Davis, 2011/09/07 翻译:刘琼 ...

  2. SQL Server中的事务日志管理(7/9):处理日志过度增长

    当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...

  3. 内存中OLTP(Hekaton)里的事务日志记录

    在今天的文章里,我想详细讨论下内存中OLTP里的事务日志如何写入事务日志.我们都知道,对于你的内存优化表(Memory Optimized Tables),内存中OLTP提供你2个持久性(durabi ...

  4. 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

    SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列   本文是Stairway系列的一部分:SQL ...

  5. SQL Server中的事务日志管理的阶梯,级别1:事务日志概述

    SQL Server中的事务日志管理的阶梯,级别1:事务日志概述 翻译:刘琼滨 谢雪妮 许雅莉 赖慧芳 级别1:事务日志概述 事务日志是一个文件,其中SQL服务器存储了所有与日志文件关联的数据库执行的 ...

  6. 浅谈SQL Server中的事务日志(四)----在完整恢复模式下日志的角色

    简介 生产环境下的数据是如果可以写在资产负债表上的话,我想这个资产所占的数额一定不会小.而墨菲定律(事情如果有变坏的可能,无论这种可能性有多小,它总会发生)仿佛是给DBA量身定做的.在上篇文章介绍的简 ...

  7. 工作中比较重要的经验分享-2016-bypkm

    工作中总有一些经验能让人记忆深刻,能让人终生受用,相比技术而言,经验是宝贵的.无价的.在我的博客中,主要是技术类的博文,那些东西是相对死板的,价值也相对低廉.今天就记录一下我在工作中一次比较重要的经验 ...

  8. 【开源】【前后端分离】【优雅编码】分享我工作中的一款MVC+EF+IoC+Layui前后端分离的框架——【NO.1】框架概述

    写博客之前总想说点什么,但写的时候又忘了想说点什么,算了,不说了,还是来送福利吧. 今天是来分享我在平时工作中搭建的一套前后端分离的框架. 平时工作大多时候都是在做管理类型的软件开发,无非就是增.删. ...

  9. 分享php工作中遇到的一些探究和技巧【2】

    1 如何定义linux和window通用的文件分隔符号 DIRECTORY_SEPARATOR :  目录分隔符,是定义php的内置常量.在调试机器上,在windows我们习惯性的使用"\& ...

随机推荐

  1. 一图搞定【实战Java高并发程序设计】

    来了解下java并发的技术点吧.这里面包括了并发级别.算法.定律,还有开发包.在过去单核CPU时代,单任务在一个时间点只能执行单一程序,随着多核CPU的发展,并行程序开发就显得尤为重要.这本书主要介绍 ...

  2. T-SQL存储过程、游标

    Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø ...

  3. 浅谈C++多态性

    本文转载至http://blog.csdn.net/hackbuteer1/article/details/7475622 总结: (1)区分概念:    重载----同一个类中,相同的函数名字,不同 ...

  4. ubuntu12.04 修复Grub2

    电脑双系统,但是把win7重装了之后,会发现grub坏了,只能进入win7. 遇到过好几次,虽然每次都成功解决问题了,但是都花费了不少时间. 所以,总结一下,基本是从网上找到的方法,有的行不通,有的可 ...

  5. iOS开发 -- 发送JSON数据给服务器

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.URL NSURL *url = [NSURL URLW ...

  6. Javascript的简介和使用

    摘要:先讨论JavaScript的由来和一些比较容易混淆的概念,又讨论了JavaScript的实现,紧接着说明了在网页中怎么有效地更好地引入js代码. JavaScript的由来 是从一个简单的输入验 ...

  7. Web Scraper使用

    { "selectors": [{ "parentSelectors": ["_root"], "type": &quo ...

  8. js前段开发工具

    http://runjs.cn/?token=e87dac453af5caed08d1771682b0c3f5

  9. 从零开始学 Web 之 DOM(六)为元素绑定与解绑事件

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... +-------------------------------------------------------- ...

  10. ural1469

    题解: 从左往右加入每一个点 判断一下和,pre,nxt是否相交 删除得时候也要判断 代码: #pragma GCC optimize(2) #include<cstdio> #inclu ...