记录今天客户的SQLSERVER启动不起来( 错误9003)的解决过程2013-11-26

今天一大早上班就接到客户的电话,说:SQLSERVER启动不起来,业务系统使用不了

于是我就使用QQ远程,帮客户解决问题


环境

先说一下环境

客户环境:Windows2003企业版SP2 32位 SQL2005企业版 32位 SP4

自己笔记本电脑环境:Windows7 SP1  32位  SQL2005个人开发者版 32位

我的笔记本电脑的计算机名:joe

客户电脑的计算机名:hs

客户那边的master数据库大小:几MB

业务系统是winform系统

客户的环境是单机系统没有使用到域

网络环境:客户那边的网速比较慢,用远程协助的时候比较卡

为什麽要说明我自己笔记本电脑的环境呢?请大家继续耐心看下去


检查

先打开SQLSERVER配置管理器,启动SQLSERVER,发现SQLSERVER启动不起来

于是我打开Windows EventLog,发现了下面错误

SQLSERVER 错误9003:LSN无效(日志扫描号无效)
"传递给数据库 'master' 中的日志扫描操作的日志扫描号 (2806:120:1) 无效。
此错误可能指示数据损坏,或者日志文件(.ldf)与数据文件(.mdf)不匹配。
如果此错误是在复制期间出现的,请重新创建发布。否则,如果该问题导致启动期间出错,请从备份还原。

于是我就在自己的电脑上百度了一下这个错误

搜索到这篇文章:sql server 错误9003:LSN无效(日志扫描号无效),对数据库的修复

这篇文章里的数据库是用户数据库,用rebuild log,dbcc checkdb解决了问题

悲催的是客户那边损坏的是master数据库


想办法

作为一个好的数据库工程师,一定要快速知道有哪些方法可以解决当前客户的问题

这些方法有什么利弊,因为延迟一秒钟,就会造成客户更多的损失,客户的业务系统无法正常运作,后果可想而知

由下面几个因素,我作出了一个选择

网速比较慢,不方便在客户的电脑上写SQL语句

客户那边的master数据库大小:几MB

业务系统是winform系统

选择:以前项目经理教我的一个方法,遇到SQLSERVER启动不起来

可以用刚刚安装好的SQLSERVER的master数据库替换掉客户那边的master数据库

这种方法有下面的弊端

(1)你所用的数据库版本一定要和客户的一样

(2)将SQLSERVER2012的master数据库给客户是不行的

(3)服务器触发器,证书,链接服务器,登录用户等信息会丢失

为什麽会有这些弊端,大家可以看一下下面的文章

SQL Server 2008中的Service SID 介绍

【SERVICE SID的引入】
NT SERVICE\MSSQL$KATMAI, NT SERVICE\SQLAgent$KATMAI和NT SERVICE\ClusSvc 其实都是Service SID所对应的名字。

Service SID的引入,是为了解决多个Service可能同用一个service帐号所带来的安全隐患。

如IIS 使用Network Service帐号,可能其他服务也使用Network Service帐号。

为了使得IIS能够连接到SQL Server, 我们可能会把Network Service作为SQL Server的login, 但是这是不安全的。

因为其他服务如果以Network Service做为启动帐号的话,也能访问SQL Server。

为了解决这个问题,在SQL Server 2008/Windows Server 2008及以后

我们有了SID这个概念,这样,不同的服务,即使服务启动帐号是相同的,它们的SID也是不同的。

SQLSERVER2005
 
SQLSERVER2012
因为登录用户的机制在SQLSERVER2008的时候发生了变化,所以你所用的数据库版本不和客户的一样是不行的
但是就算一样,也有弊端,客户的登录用户原本是下面的样子
builtin\administrators
hs\administrators
hs\SQLServer2005MSFTEUser$hs$MSSQLSERVER
hs\SQLServer2005MSSQLUser$hs$MSSQLSERVER
hs\SQLServer2005SQLAgentUser$hs$MSSQLSERVER
 

但是如果我把自己的master数据库给客户的话,就会变成下面的样子

如果客户的业务系统是B/S系统,会用到IIS,或者客户的环境是域环境,

登录SQLSERVER需要使用Windows登录验证不是SQL登录验证,那么这样做就很麻烦了

还有一个我自己电脑的SQLSERVER是个人开发者,客户的是企业版,不过之前也这样做过,发现没有什么问题


开始实施

弊端说完了,开始实施了

第一步:先把我自己笔记本电脑上的SQLSERVER所有用户数据库全部分离,

删除一些安装时候没有的登录用户只保留默认的登录用户,停止自己电脑的SQL服务,然后把master.mdf和mastlog.ldf复制出来,发给客户

第二步:使用远程协助,把客户电脑里的master数据库master.mdf文件改名为master22.mdf

mastlog.ldf文件改名为mastlog22.ldf

然后把发过来的master数据库放进去data文件夹里

第三步:启动SQLSERVER,由于当时没有截图,这里就不放截图了,这时候可以发现SQLSERVER成功启动了

第四步:把我们的业务库重新附加进来

第五步:删除原来业务库里的那个数据库用户gxhtsyrain

第六步:新建登录用户gxhtsyrain并且映射到我们的业务库

第七步:禁用sa用户

由于不是替换msdb数据库,所以维护计划没有丢失


错误日志

我查看SQL ERRORLOG,发现了下面的错误

无法启用数据库 "msdb" 中的 Service Broker,因为master与msdb 的 Service Broker 的ID不一样

NT AUTHORITY\SYSTEM登录失败

由于我们没有用到 Service Broker技术,所以“无法启用数据库 "msdb" 中的 Service Broker”这个错误可以忽略

而NT AUTHORITY\SYSTEM登录失败,在文章SQL Server 2008中的Service SID 介绍中说到

但是我们也不能认为有这几个SID的帐号,就能随便把其他的登录如NT AUTHORITY\SYSTEM给删除。

某些应用,如VSS Writer,Windows自动更新等,还是需要用服务启动帐号来进行处理。

因为客户的SQLSERVER已经打了SP4补丁,不会再打补丁,所以就算用不了Windows自动更新也没有关系


如果客户那边有做SQLSERVER的系统数据库备份

我会这样做:

第一步:先备份我自己笔记本电脑里的master数据库出来

第二步:将客户那边的master.bak拿到自己的电脑里

第三步:还原客户的master.bak到自己的SQLSERVER

第四步:停止SQL服务,然后把master.mdf和mastlog.ldf复制出来发送给客户

第五步:把客户电脑里的master数据库master.mdf文件改名为master22.mdf,mastlog.ldf文件改名为mastlog22.ldf

第六步:然后把发过来的master数据库放进去data文件夹里

第七步:启动SQLSERVER


总结
其实除了备份用户数据库之外,系统数据库的备份也是很重要的

我们需要备份master和msdb这两个数据库

我们当时部署业务系统的时候没有备份系统数据库,其实也是一个反面教材

我的方法是基于我们的业务系统使用到SQLSERVER的功能就只有维护计划,所以作出上面的的解决方法

如果用到很多SQLSERVER的相关技术的话,可能我的解决方法不是最好的

我也希望大家能够提出您的意见和见解,或者您使用的方法比我还要好,更快速

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

记录今天客户的SQLSERVER启动不起来( 错误9003)的解决过程2013-11-26的更多相关文章

  1. 记录一次MySQL两千万数据的大表优化解决过程,提供三种解决方案(转)

    问题概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死.严重影响业务 ...

  2. Apache 启动失败没有错误信息的解决办法

    在cmd命令行 进入到apache安装bin目录 执行以下 httpd.exe -w -n "apache2.2" -k start 注意apache2.2是你安装的apache服 ...

  3. 转载:记录一次MySQL两千万数据的大表优化解决过程

    地址:https://database.51cto.com/art/201902/592522.htm 虽然是广告文,但整体可读性尚可.

  4. 启动Tomcat一闪而过——分析及解决过程

    启动Tomcat一闪而过--分析及解决过程 嗯,昨天将有关JDK的知识稍微整理了一下,现在稍微整理一下有关Tomcat的! 1:Tomcat是什么? Tomcat是当今世界上使用最为广泛的.开源免费的 ...

  5. SQLServer启动和关闭bat脚本

    原文:SQLServer启动和关闭bat脚本   安装完毕SQL SERVER 2005后,会默认自动启动SQL Server等几个服务,这几个服务比较占用系统资源.当不运行SQL Server时,最 ...

  6. 记录一次sshd服务启动失败

    记录一次sshd服务启动失败 问题描述: 服务器开机之后发现无法通过远程连接服务器终端,但是服务器并未宕机,于是考虑到sshd服务出现异常 解决思路: 查看服务器sshd服务运行情况 [root@ha ...

  7. Intellij IDEA debug模式下项目启动慢/无法启动的事件解决过程记录

    项目无法启动了 简单的介绍一下事件过程:周一的早上,收到前端同事抛过来的一个任务,说是一个接口无法正常返回数据,于是就让他把参数发过来,我想试着在本地重现一下并且将问题修复掉,这种情况肯定是要通过de ...

  8. 安装oracle 11g时,报启动服务出现错误,找不到OracleMTSRecoveryService的解决方法

    很多人在安装orcl数据库时,出现很多报错,我也不例外,因上次数据库出现问题,无法修复,只能从新安装,无奈的是,安装时报启动服务出现错误,找不到OracleMTSRecoveryService错MMP ...

  9. [转]线上GC故障解决过程记录

    排查了三四个小时,终于解决了这个GC问题,记录解决过程于此,希望对大家有所帮助.本文假定读者已具备基本的GC常识和JVM调优知识,关于JVM调优工具使用可以查看我在同一分类下的另一篇文章: http: ...

随机推荐

  1. PreparedStatement插入values

    public interface PreparedStatementextends Statement 表示预编译的 SQL 语句的对象. SQL 语句被预编译并存储在 PreparedStateme ...

  2. spring boot整合RabbitMQ(Topic模式)

    1.Topic交换器介绍 Topic Exchange 转发消息主要是根据通配符. 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发 ...

  3. Zookeeper在Centos7上搭建单节点应用

    (默认机器上已经安装并配置好了jdk) 1.下载zookeeper并解压 $ tar -zxvf zookeeper-3.4.6.tar.gz 2.将解压后的文件夹移动到 /usr/local/ 目录 ...

  4. 【转】Entity framework 6 编写的通用数据类

    原文:http://blog.csdn.net/laokaizzz/article/details/25730813 准备参考

  5. eclipse maven插件创建maven项目

    1.下载好maven压缩包http://maven.apache.org/ ,解压后放到想要安装的目录,如E:/server/maven,然后配置好maven环境变量,找到maven安装目录下conf ...

  6. ID3、C4.5和CART决策树对比

    ID3决策树:利用信息增益来划分节点 信息熵是度量样本集合纯度最常用的一种指标.假设样本集合D中第k类样本所占的比重为pk,那么信息熵的计算则为下面的计算方式 当这个Ent(D)的值越小,说明样本集合 ...

  7. java-双大括号实例初始化的反模式

    今天在看springboot的batch时, 看到这样一段代码, 直接把我看懵了, 于是找了一下, 发现这 两个大括号 {{  叫实例初始化器 FlatFileItemReader<Person ...

  8. firefox native extension -- har export trigger

    这两天想学习下如何在运行自动化脚本时去capture http traffic,google看到一篇博客介绍用browser mob proxy或者firefox+firebug+netexport, ...

  9. Python---战机小游戏,学习pygame

    import pygame # 导入游戏包 pygame.init() # 导入并初始化所有pygame模块,使用其他模块之前必须先调用init()方法 print('下面是游戏代码:') # 绘制矩 ...

  10. [javaSE] 数组(排序-选择排序)

    两层嵌套循环,外层循环控制次数,内层循环进行比较 for(int x=0;x<arr.length;x++){ for(int y=0;y<arr.length;y++){ if(arr[ ...