
1. 先搞清楚SQL Server 2019到底装了些什么很多人卸载SQL Server 2019失败问题从第一步就埋下了把它当成一个普通软件以为点一下“卸载”就完事。实际上SQL Server 2019是一整套组件家族控制面板里可能同时躺着七八个甚至十几个带“SQL Server”字样的条目卸载哪个、先卸哪个直接决定了后面是否要跟注册表搏斗。1.1 它不是一个软件而是一组相互依赖的组件SQL Server 2019 安装完成后机器上的组件大致分成三类。第一类是实例级组件也就是数据库引擎、SQL Server 代理、全文检索、复制、机器学习服务这些挂在某个实例名下的功能第二类是共享功能比如 SQL Server Browser、客户端连接组件、SQL Server Native Client、各类 ODBC 驱动第三类是独立工具比如 SQL Server Management StudioSSMS和 SQL Server 配置管理器相关的管理外壳。这三类东西的卸载顺序完全不一样混着卸就等着报错。我见过太多人直接在“应用和功能”里从上往下勾一次全选然后点卸载。结果安装程序在检查依赖时发现某个共享组件还被别的功能引用当场翻脸弹出一串英文错误码。所以动手前先花两分钟打开控制面板把带“SQL Server”“SQL Native Client”“ODBC Driver”的条目截图记下来确认自己装了哪些。这一步不用技术含量但能省下后面一小时的排查时间。1.2 卸载不干净到底会留下什么残留主要集中在四个地方注册表、安装目录、服务和计划任务、WMI和性能计数器。注册表里HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server这一支会记录所有实例的安装信息如果只删了数据库引擎却留着这些键下次重装到命名实例那一步就会提示“实例名已被占用”。安装目录下的Program Files\Microsoft SQL Server和ProgramData\Microsoft\Microsoft SQL Server也会留下大量配置文件和日志。服务和计划任务的残留更隐蔽。数据库引擎服务删掉了SQL Server 代理、全文筛选器启动器、VSS Writer 可能还挂在服务列表里开机照样启动。WMI 命名空间root\Microsoft\SqlServer下的性能计数器如果没清系统日志里会持续出现事件ID报错。这些东西单个看都不致命但叠在一起会让新装的实例行为诡异——端口冲突、性能监控读不到数据、备份软件识别到两个同名实例。提示判断是否“彻底”的标准很简单卸载后重启一次注册表搜不到相关主键、服务列表里没有任何 MSSQL 或 SQL 开头的服务、安装目录可以整个删掉三条全满足才算干净。1.3 哪些场景必须做到彻底卸载日常开发机上装错了版本想换一个功能组合重装这种情况表面卸载加手工清理就够。但有两类场景必须做完整流程一是生产或测试服务器上要换实例名、换端口、换排序规则残留会导致新实例继承旧配置二是机器要转作他用或者交付给别人留着半套SQL Server既占资源也不安全。还有一种容易被忽视的情况是安装中途失败。安装程序跑到一半崩了控制面板里可能根本没出现条目但服务、注册表和目录已经写进去了。这种“半成品”状态用常规卸载根本找不到入口只能走深度清理路线。我在一台测试机上遇到过安装到“安装程序支持文件”阶段断电重启后控制面板里空空如也但Program Files\Microsoft SQL Server\150目录躺在那里服务列表里多了三个残缺项最后是靠手动删除加命令行清理才恢复干净。2. 动手之前必须做的四件事卸载这种事准备阶段比执行阶段重要。我习惯把准备工作拆成四步走完再碰卸载按钮后面基本不会翻车。2.1 数据和密钥先落地数据库文件、备份文件、SSIS 包、作业脚本、链接服务器配置这些是卸载后不可再生的。默认实例的数据目录通常在安装时自己指定的盘不一定是C盘先去SQL Server 配置管理器或者注册表里把实例的SQLDataRoot查出来把.mdf、.ldf、.bak全部转移或者确认已有备份。作业和链接服务器配置可以直接生成脚本在 SSMS 里右键“编写为 CREATE 脚本”就行。顺带把产品密钥记下来。用sql server2019 key这类关键词搜到的东西不靠谱正确的做法是在已安装的实例上查或者翻自己的采购记录和微软账户。很多人卸载完想重装才发现密钥找不到了只能重新申请。卸载前多花三十秒查一下比事后补救省事。SSMS 里执行SELECT SERVERPROPERTY(ProductKey)有时候能拿到拿不到就去安装介质或账户后台找。2.2 记录实例名、组件清单和安装路径打开“SQL Server 2019 安装中心”里的“已安装的 SQL Server 功能”或者直接看控制面板的条目列表把所有组件名抄下来。重点记三类信息实例名默认实例是 MSSQLSERVER命名实例是自定义的名字、功能列表数据库引擎、复制、全文、分析服务、报表服务分别装没装、安装目录和共享功能目录。这些信息决定了卸载顺序和注册表清理范围。比如你装了两个命名实例注册表里会有两套实例键清理时少删一个重装同名实例就会失败。再比如共享功能目录如果被改到了非默认盘清理时容易漏掉。我一般直接把这些信息写在一个临时文本文件里清理阶段对照着一条条划掉避免边想边删。2.3 停服务、断连接、关掉拦路的软件卸载前先把所有 SQL Server 相关服务停掉。服务不停卸载程序会提示文件被占用尤其是数据库引擎和代理服务。命令行一条net stop MSSQLSERVER搞定默认实例命名实例把服务名换成MSSQL$实例名。代理、Browser、全文启动器同理。然后断开所有客户端连接包括 SSMS、应用连接池、定时任务、监控探针。我遇到过卸载到一半失败查日志发现是某个报表订阅任务在后台连库。最简单的办法是卸载前把相关服务停掉后等两分钟用netstat -ano | findstr :1433确认端口没有活跃连接再动手。最后各类安全防护软件、主机入侵检测、文件加密工具最好临时停掉或者退出。它们拦截安装程序写注册表和删服务是常事。卸载动作本身是系统级操作容易被这类软件判定为异常行为。我测试时遇到过防护软件把卸载程序删注册表的动作拦下来结果卸载“成功”了注册表纹丝不动重装时才发现问题。3. 主卸载流程控制面板里的顺序学问准备工作做完正式进入卸载。控制面板的“应用和功能”是主战场但顺序不能乱来。核心原则一句话先卸依赖别人的再卸被别人依赖的先卸功能组件再卸引擎最后卸共享组件。3.1 先卸业务功能组件再卸数据库引擎如果你装了分析服务、报表服务、机器学习服务、Master Data Services、Data Quality Services 这些它们都依赖数据库引擎或者共享组件必须排在最前面卸。顺序上先卸报表服务和机器学习服务这类外围功能再卸复制、全文检索、Data Quality Services最后才轮到数据库引擎。数据库引擎的卸载是整个流程里最耗时的一步安装程序要回滚大量注册表项和文件。这一步如果卡住不要强杀进程等它自己报错。强杀的结果是留下一堆半删状态比不卸还难处理。正常情况十分钟内能走完超过二十分钟没动静多半是有文件被占用或者注册表项权限有问题这时候去看安装日志找具体卡在哪。3.2 共享功能和客户端的卸载顺序数据库引擎卸完接下来是 SQL Server Browser、SQL Server 复制、客户端连接组件、SQL Native Client、ODBC Driver 这些。Browser 服务容易被忽略它负责实例发现不卸的话重装时可能提示端口被占。ODBC 驱动和 Native Client 建议放在最后卸因为有些第三方工具依赖它们先卸可能导致其他软件报错虽然不影响卸载本身但会多出一堆无关的错误提示。SSMS 是单独安装的不在SQL Server 安装程序的卸载范围内需要单独在“应用和功能”里找到“Microsoft SQL Server Management Studio”卸载。SQL Server 2019 配套的 SSMS 是 18.x 版本卸载它跟卸载数据库引擎是两回事顺序上放最后就行。有几次我发现卸载完引擎后 SSMS 打不开了这是正常的它依赖的对象没了直接卸掉即可。3.3 卸载报错时的第一反应控制面板卸载过程中最常见的两个错误是 1603安装程序遇到致命错误和 2711找不到安装程序包。1603 通常是权限或者文件占用问题用管理员身份运行“程序和功能”再看一次或者去安装日志里定位具体失败的文件。2711 一般是安装缓存被清理过卸载程序找不到原始 msi 包这种情况下控制面板这条路基本堵死只能走手动清理加微软的卸载工具。微软官方提供过一个 SQL Server 卸载清理工具可以处理常规卸载失败的残留。但这类工具不是万能的它主要清注册表和服务目录和 WMI 还得手工。我个人的经验是控制面板能卸掉的就别用工具工具留给彻底卸载失败的极端情况。顺序上还是控制面板优先报错再考虑工具工具之后再手工补刀。4. 深度清理注册表、目录、服务和WMI控制面板走完只是完成了七成。剩下三成才是决定“彻底”与否的关键。这一阶段的操作要谨慎注册表删错会伤及系统目录删错会丢数据所以每一步都要带着确认动作走。4.1 注册表清理先导出再动手注册表清理的第一步永远是备份。打开regedit定位到要删的主键右键“导出”存成.reg文件。别嫌麻烦我见过删完注册表系统某个功能异常靠备份回滚才救回来的。SQL Server 2019 相关的注册表主键主要有这几处注册表路径内容说明处理建议HKLM\SOFTWARE\Microsoft\Microsoft SQL Server实例配置、功能清单、版本信息整个键删除前确认没有其他版本共存HKLM\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server32位组件配置同上64位系统上必查HKLM\SOFTWARE\Microsoft\MSSQLServer默认实例的客户端和协议配置有命名实例时注意区分HKLM\SYSTEM\CurrentControlSet\Services服务注册项只删 MSSQL、SQL 开头的服务键HKCU\Software\Microsoft\Microsoft SQL Server当前用户配置多用户机器上逐个用户检查HKLM\SOFTWARE\Microsoft\Microsoft SQL Server这个键下面会按版本号分子键SQL Server 2019 对应的是150。如果机器上只有2019整个删掉问题不大如果还有2016或者2017删之前先看清版本号别把别的版本一起端了。命名实例的键名里带实例名删除时确认清楚。服务键在Services下面名字通常是MSSQLSERVER、MSSQL$实例名、SQLSERVERAGENT、SQLBrowser、MSSQLFDLauncher$实例名这些。4.2 文件和目录哪些能删哪些要留安装目录和共享目录是残留的重灾区。SQL Server 2019 的默认安装路径是C:\Program Files\Microsoft SQL Server共享功能目录可能是C:\Program Files (x86)\Microsoft SQL Server配置和日志在C:\ProgramData\Microsoft\Microsoft SQL Server。卸载后这些目录里通常还剩空的版本文件夹和日志可以整个删掉前提是确认里面没有你手动放进去的东西。数据目录要特别小心。如果安装时把数据目录设在了D:\SQLData或者别的盘卸载程序不会动它里面的数据库文件还在。删之前必须确认这些库不再需要或者已经有完整备份。我有次帮人清理差点把还在用的一个归档库跟着目录一起删了幸好删之前顺手看了一眼文件日期发现最近还有写入。养成习惯删目录前先按修改时间排序看看有没有近期变动的文件。比删目录更麻烦的是文件被占用。卸载后某些.dll删不掉提示“文件正在被另一个程序使用”。这种情况用handle.exeSysinternals 工具集里的查一下是哪个进程占用通常是残留的服务或者某个还活着的进程。找到后停服务或者结束进程再删。删除顺序上先删自己能确认的遇到删不掉的记下来处理完占用再回头删。4.3 服务、WMI 和性能计数器的收尾服务残留用sc query或者 PowerShell 的Get-Service列出来看重点看MSSQL、SQL、MsDtsServer开头的项。确认是SQL Server相关的用sc delete 服务名删掉。删之前先sc stop 服务名停掉直接删运行中的服务有时会失败。SQL Server VSS Writer 服务名是SQLWriter也别忘了。WMI 命名空间在root\Microsoft\SqlServer下面按版本分子命名空间比如ComputerManagement15对应2019。常规卸载会清掉但卸载失败的情况下这些 WMI 类会残留导致性能监控和某些管理工具读数据报错。清理可以用mofcomp重新编译对应的 mof 文件或者用 WMI 工具删除命名空间。这一步风险高不确定的话可以跳过影响没那么致命。性能计数器残留表现为性能监视器里还能看到 SQL Server 相关的计数器但读不出数据。修复办法是命令行执行lodctr /R重建计数器缓存然后重启。这个操作对系统整体计数器也有影响执行前知道自己在干什么。防火墙规则里如果还留着 SQL Server 的入站规则一并删掉免得重装时端口规则冲突。5. 卸载后怎么验证才算干净清理完不验证等于白干。我习惯做五项检查全过了才认为这台机器可以重装或者交付。5.1 五项验证动作第一步重启机器。重启是检验残留的最直接手段很多问题在重启后才会暴露比如残留服务自动启动失败、驱动加载异常。第二步看服务列表用services.msc或者命令行过滤确认没有任何 SQL 相关服务。第三步看注册表搜Microsoft SQL Server和MSSQL关键词确认没有指向2019的主键。第四步看目录。确认Program Files、Program Files (x86)、ProgramData下的 Microsoft SQL Server 目录已经不存在或者为空。第五步看端口。netstat -ano | findstr :1433确认没有进程监听数据库端口默认实例和命名实例的端口都要查。这五步走完基本可以放心。注意如果机器上还装着其他版本的 SQL Server验证时要区分版本别把2016或者2017的残留当成2019的清掉了那会导致别的实例异常。5.2 重装前的环境复位验证通过后如果是要重装还有两件小事要做。一是清理临时文件安装程序会在C:\Windows\Temp和用户临时目录留安装缓存清理掉避免干扰新安装。二是确认hosts文件里没有之前为实例加的解析记录有的话删掉。这两步不影响大方向但能避免重装后连不上实例这类小麻烦。6. 常见问题与排查实录卸载SQL Server 2019遇到的坑翻来覆去就那么几个。我把自己和同事踩过的整理成一张表遇到问题先对号入座。现象大概率原因处理办法控制面板卸载报错1603权限不足或文件被占用管理员运行、停服务、查安装日志定位文件卸载后重装提示实例名已存在注册表实例键没删干净清HKLM\SOFTWARE\Microsoft\Microsoft SQL Server下对应键服务删不掉提示拒绝访问服务正在运行或权限不够先sc stop再sc delete用管理员权限某dll文件删不掉被进程占用handle.exe定位占用进程结束后再删重装后性能监控读不到数据WMI或性能计数器残留重建WMI命名空间执行lodctr /R卸载后其他软件报ODBC错误先卸了Native Client重装对应ODBC驱动或恢复客户端组件6.1 卸载卡在“正在配置”不动这个现象多半是安装程序在回滚注册表时遇到权限问题或者某个后台进程在读写安装目录。别急着强杀先打开任务管理器看安装程序的CPU占用如果接近0大概率是卡在等待。这时候可以去看C:\Program Files\Microsoft SQL Server\150\Setup Bootstrap\Log下的日志找最后一个写入的日志文件里面会记录卡在哪一步。日志里常见的是某个注册表项的权限被改过安装程序删不掉。解决办法是给对应注册表键加上当前用户的完全控制权限再重新跑卸载。这种情况在装过安全加固软件的机器上很常见加固策略把注册表权限收紧了。6.2 重装时提示“已存在同名实例”这是注册表没清干净的典型表现。定位到HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL这里记录了所有实例名到实例ID的映射。如果旧实例名还在这里新安装就会冲突。删掉对应的键值顺便去HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\实例ID把整个实例键删掉。还有一种情况是文件系统里的实例目录没删安装程序扫描到MSSQL15.实例名这样的目录判定实例已存在。这种就把Program Files\Microsoft SQL Server下对应的实例目录删掉再装。顺序上先删注册表再删目录或者反过来都行关键是两处都清。6.3 端口被占导致新实例装不上卸载后netstat发现1433还被监听多半是残留服务没删干净或者别的软件占用了这个端口。先用netstat -ano找到 PID再用tasklist确认进程。如果是残留服务删服务如果是别的软件改它的端口或者装SQL Server时指定别的端口。命名实例的端口是动态的通过 SQL Server Browser 分配Browser 服务残留也会导致端口冲突。确认 Browser 服务已经彻底删除或者至少停止了。这个问题在处理多实例环境时特别常见两个实例抢同一个动态端口表现是客户端连接时好时坏。6.4 卸载后系统启动变慢残留服务设置了自动启动开机时尝试启动失败每次都要等超时拖慢启动。去服务列表里把残留的 SQL 服务启动类型改成“禁用”再删或者直接用sc config 服务名 start disabled。根治办法还是把服务删掉光禁用只是缓解。另一个原因是残留的启动项或者计划任务。SQL Server 安装时可能会加计划任务比如某些维护作业卸载不彻底就会留着。去任务计划程序里搜 SQL 相关的任务确认无用后删掉。7. 把重复劳动交给脚本和工具如果你只是偶尔卸一次手工操作就够了。但如果经常装删、或者手里有一批机器要处理写点脚本能省不少事。7.1 一个用来验证残留的 PowerShell 脚本卸载完成后跑一段脚本一次性检查服务、注册表和端口比手工翻快得多。下面这段只是验证不做删除动作安全。# 检查残留服务 Get-Service | Where-Object { $_.Name -match MSSQL|SQLBrowser|SQLWriter|MsDtsServer } | Select-Object Name, Status, StartType # 检查注册表主键 $paths ( HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server, HKLM:\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server, HKLM:\SOFTWARE\Microsoft\MSSQLServer ) foreach ($p in $paths) { if (Test-Path $p) { Write-Host 残留: $p } } # 检查端口占用 Get-NetTCPConnection -LocalPort 1433 -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, State, OwningProcess脚本输出的每一条都对应一个需要处理的对象。服务列表为空、注册表路径不存在、端口没监听三条都满足就干净了。这套检查思路对卸载MySQL、Oracle这类数据库同样适用区别只是服务名和注册表路径不同。7.2 命令行卸载的参数怎么写控制面板点不动的时候可以用安装介质里的setup.exe走命令行卸载。基本语法是这样setup.exe /ActionUninstall /FEATURESSQLENGINE,REPLICATION,FULLTEXT /INSTANCENAMEMSSQLSERVER /QS/FEATURES后面跟要卸载的功能/INSTANCENAME指定实例/QS是安静模式不弹界面。功能名要写对写错了会报参数无效。安静模式适合批量处理但不适合第一次操作因为你不知道它到底删了什么。我建议先手工走一遍摸清自己机器上的功能列表再用命令行批量处理同类机器。7.3 批量环境的做法批量卸载时先在样板机上手工卸干净记录下完整的组件列表和清理步骤把注册表清理和目录清理写成脚本服务删除也写进去。然后在其他机器上跑安装程序卸载加清理脚本。脚本里要加确认逻辑比如检查实例名是否匹配避免误删其他版本。脚本不是万能的遇到权限问题、文件占用问题还是得手工介入。脚本的价值在于把确定性的重复动作固化下来把人的精力留给真正需要判断的地方。我在几台测试机上跑下来准备工作加脚本清理一台机器四十分钟左右能处理干净比纯手工快一半。最后分享一个我个人踩坑换来的经验卸载之前把整个Program Files\Microsoft SQL Server目录复制一份到临时盘再动手。遇到卸载失败要回滚的时候这份副本能帮你对比出哪些文件是原装的、哪些是卸载程序新写进去的排查起来方向清楚很多。等确认卸载干净、重装成功之后再把副本删掉。多占几十个G的临时空间换的是出问题时心里不慌。