首页 / 资讯中心 / 文章详情

SQL Server 18456错误排查指南:状态码解析与修复方法

SQL Server 18456错误排查指南:状态码解析与修复方法 ★ FEATURED ARTICLE
遇到 SQL Server 登录报 18456我估计每一位 DBA 和做后端开发的同事都经历过几个不眠之夜。你可能会看到两种完全不同的现象一种是客户端直接弹一个“用户 ‘sa’ 登录失败”另一种是错误日志里一大段文字看得人头大。其实 18456 这个错误码本身只是一个“壳子”真正决定问题方向的是它后面跟着的状态码。只要会读状态码80% 的登录问题都能在几分钟内定位剩下的就是按方子抓药的事。这篇文章我会把 18456 错误的来龙去脉讲透包括状态码怎么读、错误日志去哪里翻、每种状态码背后的修复步骤以及我这些年实际踩过的坑。不管你是刚接手 SQL Server 的新手运维还是被测试环境折腾到怀疑人生的开发同学只要你手里有能登录操作系统的权限照着下面的方法一步步来基本都能解决。1. 先搞清楚报错“身份”状态码和错误日志怎么读1.1 为什么都是18456原因可能完全不一样很多人在搜索引擎里输入“SQL Server 18456”然后照着网上说的“启用混合身份验证模式”“重置 sa 密码”试了一圈结果问题没解决。原因很简单18456 只是一个总错误号就像医院里的“发热门诊”引起发热的原因可能是感冒、可能是肺炎、也可能是其他问题你得先分诊。SQL Server 真正告诉我们“病因”的是错误消息里打印出来的状态码。我整理了一份日常最高频的状态码对照表建议你收藏起来状态码含义最常见的场景1错误信息本身的问题或信息不足极少见先看完整错误日志2无效的用户标识登录名不存在或连接串写错了登录名5无效的用户标识或密码密码错误、账号不存在、认证模式不匹配6尝试使用已禁用的登录名sa 被禁用或新建的 SQL 登录名是禁用状态7登录名已锁定连续输错密码触发了账户锁定策略8密码已过期开启了密码过期策略9密码必须更改强制修改密码后尚未修改11有效登录但服务器访问失败登录名没有 CONNECT 权限或服务器处于特殊状态12登录名被映射到了禁用的凭据证书/对称密钥映射类问题18密码必须更改请求不被允许密码策略与账户状态冲突这里要注意你从 SSMS 图形界面上看到的“错误: 18456”并不带状态码真正带状态码的是 SQL Server 错误日志和 Windows 事件日志中的原文。所以第一步不是去乱改配置而是先打开错误日志把里面那行带状态码的记录捞出来。1.2 三分钟找到SQL Server错误日志的原文SQL Server 错误日志的默认位置一般在安装目录的 Log 文件夹下比如 SQL Server 2019 默认实例的路径是C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Log\ERRORLOG注意实例名不同中间的目录名也会不一样。MSSQL15 对应 2019MSSQL14 对应 2017MSSQL16 对应 2022。如果你不确定路径最简单的办法是在 SSMS 里连接上服务器哪怕用 Windows 身份在“管理→SQL Server 日志”里直接查看当前日志。但很多时候我们就是登录不上才来排查所以直接用记事本打开 ERRORLOG 文件更靠谱。打开文件后拉到最底部找包含 “Login failed” 的行。一个典型的登录失败记录长这样2025-01-06 23:15:31.01 Logon 错误: 18456严重性: 14状态: 5。 2025-01-06 23:15:31.01 Logon 登录失败。原因: 为所提供的登录名提供的密码不匹配。[客户端: 192.168.1.101]看到状态: 5和密码不匹配就可以放心往密码和认证模式方向去查了。再比如错误: 18456严重性: 14状态: 6。 登录失败。原因: 尝试使用禁用的登录名。 [客户端: 192.168.1.101]这就是典型的状态 6登录名被禁用了。补充一个关键点错误日志里的 [客户端: xxx] 表示连接的来源 IP如果显示的是本地 IP 或者 127.0.0.1说明请求是本机发出的。这能帮我们判断是客户端连不上还是服务端在拒绝认证。2. 动手改配置前先做好这些基础检查2.1 服务真的在监听吗端口和协议排查有一次帮朋友看问题他折腾了半天 sa 密码最后我发现数据库服务压根没起来。所以在看认证之前先确认三件事服务是否在运行、网络协议是否启用、端口是否正常监听。先打开 Windows 服务管理器services.msc找到以 SQL Server (实例名) 开头的服务确认状态是“正在运行”。如果服务没起来后面的所有排查都白搭。服务正常之后打开 SQL Server 配置管理器展开“SQL Server 网络配置”找到对应实例的协议确认 TCP/IP 是“已启用”状态。SQL Server 默认安装时TCP/IP 协议有时是禁用状态尤其是仅安装了数据库引擎、没做网络配置的机器本地能用 Windows 身份连远程一律 18456。TCP/IP 启用后还需要确认端口。默认实例一般监听 1433命名实例默认动态端口。在配置管理器的“TCP/IP 属性→IP 地址→IPAll”里可以找到 TCP 动态端口和 TCP 端口。如果要固定端口就把“TCP 动态端口”里的值清空在“TCP 端口”里填 1433然后重启 SQL Server 服务。验证端口是否真的在监听用命令netstat -ano | findstr 1433如果看到LISTENING状态说明端口没问题。没看到的话要么 TCP/IP 协议没启用要么服务没起来要么端口被改了。这时候再去翻协议设置。还要提一嘴 SQL Server Browser 服务。如果你用的是命名实例比如计算机名\SQLEXPRESS客户端需要通过 Browser 服务的 UDP 1434 端口获得实例的端口号。这个服务默认可能是“手动”或“已停止”连不上时记得确认它已经启动。2.2 身份验证模式到底选的哪个这是 18456 里最常被忽略的一个原因。SQL Server 安装默认是“Windows 身份验证模式”。在这种模式下你用 sa 或其他 SQL 账号登录不管密码敲得多正确服务端都直接拒绝错误日志里的状态码通常是 5但真实原因并不是密码错了而是服务端根本不认 SQL 登录这种认证方式。查看当前认证模式可以用 SSMS 登录后右键服务器属性在“安全性”页签里看“服务器身份验证”。如果是“Windows 身份验证模式”那就说明问题出在这里。改成混合模式的操作路径SSMS → 右键服务器 → 属性 → 安全性 → 选“SQL Server 和 Windows 身份验证模式” → 确定。改完之后必须重启 SQL Server 服务才能生效。这一步千万别忘我见过有人改完不重启然后继续怀疑人生。如果你不方便用图形界面注册表也可以改。SQL Server 的认证模式存在这里HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQLServer\LoginModeLoginMode 的值是 1 表示仅 Windows 认证2 表示混合认证。改成 2 后同样要重启服务。2.3 连接的账号本身状态完整吗认证模式没问题之后就该看登录名本身了。SQL Server 里一个 SQL 登录名有几项属性会直接导致 18456禁用状态is_disabled密码是否过期is_expiration_checked是否被锁定LOGINPROPERTY 查询是否被强制修改密码IsMustChange用 Windows 身份先连上数据库执行下面这条 SQL就能把用户的状态一次性看明白SELECT name, is_disabled, is_policy_checked, is_expiration_checked, LOGINPROPERTY(name, NIsLocked) AS is_locked, LOGINPROPERTY(name, NIsMustChange) AS must_change_password FROM sys.sql_logins WHERE name Nsa;网上很多教程直接告诉你“用 ALTER LOGIN sa WITH PASSWORD ‘xxx’ 重设密码”但忽略了用户是否禁用、是否被锁。如果 is_disabled 是 1光改密码是没用的还得显式执行一次启用操作。后面我会把每条状态码对应的处理步骤单独列出来你照着做就行。3. 按状态码对症下药把每种“死法”都救活3.1 状态5或状态2账号或密码不对可背后还有5种情况状态 5 是出现频率最高的一种错误日志原文通常写着“密码不匹配”或者“为所提供的登录名提供的密码不匹配”。但我在实际排查中发现状态 5 背后往往藏着好几种不同的根因密码确实输错了。登录名写错了比如把sa写成了admin或者连接串里账号带了多余的空格。服务器认证模式是仅 WindowsSQL 登录被直接拒绝。客户端和服务端之间加密 TLS 设置不匹配导致认证握手失败。密码里的特殊字符没有正确转义。前两种好办重新确认账号密码就行。第三种按上一节改成混合认证并重启。第四种在较新的 SQL Server 版本里容易遇到特别是客户端用了新版驱动时默认启用了强制加密而服务端没有配置证书。这时候错误可能表现为状态 5但错误日志里往往还有一条关于证书或 SSL 的记录。可以先在连接字符串里加TrustServerCertificateTrue或者把驱动的 Encrypt 改成 Optional 再试。第五种常见于在应用配置文件里写连接串时密码包含;、、之类字符。比如Server192.168.1.10;User Idsa;Passwordabc;123分号会把连接字符串截断导致密码解析成abc自然就报密码不匹配。解决办法是把密码单独放到配置项或者用 .NET 的 SqlConnectionStringBuilder 来拼接。真正的“忘记 sa 密码”情况只要你有 Windows 管理员权限还是能救回来的。以管理员身份打开命令提示符把 SQL Server 服务以单用户模式拉起来然后重置 sa 密码。操作步骤我会在第 4 节里完整展开。3.2 状态6、状态7、状态8、状态9禁用、锁定、密码过期一套命令全搞定这几个状态码放在一起说因为它们的处理逻辑是相通的都是“账号本身活着但状态不让用”。状态 6 表示登录名被禁用。常见于安装后从未启用过 sa或者 DBA 出于安全考虑禁用了某个应用账号。修复命令ALTER LOGIN [sa] WITH PASSWORD N新密码, CHECK_POLICY OFF; ALTER LOGIN [sa] ENABLE;如果不想改密码只想启用ALTER LOGIN [sa] ENABLE;状态 7 是账户被锁定。SQL Server 的密码策略里如果开启了“账户锁定阈值”连续多次失败登录后账户会被锁。查询锁定状态用上面提到过的 LOGINPROPERTY解锁命令ALTER LOGIN [sa] WITH UNLOCK;解锁后建议顺手确认一下密码策略配置是否合理。如果业务上确实存在暴力破解风险阈值可以保留但别设得太小否则一个手滑的脚本就能把生产账号锁干净。状态 8 是密码过期状态 9 是必须更改密码。这俩通常出现在开启了密码过期策略的数据库上或者管理员在创建登录名时勾选了“强制密码过期”。修复方式就是改密码ALTER LOGIN [sa] WITH PASSWORD N新密码;如果密码策略限制太死你可以像上面那样在修改时加CHECK_POLICY OFF和CHECK_EXPIRATION OFF但生产环境我不建议这么做密码策略的初衷是安全不是给我们添堵的。3.3 状态11或状态12登录名没问题但没进门的资格状态 11 很多人不熟。这个状态的意思是服务端已经验证了你的账号密码也认可你是合法登录名但因为某些原因不让你进门。最常见的情况是登录名缺少CONNECT SQL权限。SQL Server 里每个登录名必须拥有连接数据库引擎的权限默认情况下 sysadmin 角色和 public 角色可以连接。如果某个登录名被显式拒绝或者服务器角色被改得比较迷就会看到状态 11。修复方式是在“登录名属性→安全对象”里授予“连接 SQL”权限或者用脚本GRANT CONNECT SQL TO [你的登录名];还有一种特殊情况SQL Server 启动时加了-m单用户参数。单用户模式下系统只允许一个连接其他连接请求会以状态 11 被拒绝。如果确认服务器处于单用户模式可以通过 SQL Server 配置管理器查看启动参数等维护结束把-m参数去掉并重启服务即可。状态 12 相对少见它和证书、对称密钥映射有关。如果你不是在做“凭据映射”相关的高级配置基本不用担心这个状态码。真遇到了先回顾最近有没有做过证书切换或恢复然后检查对应证书的有效期。3.4 其他少见状态码遇到也别慌状态 1、状态 2、状态 40、状态 46 这些属于低频状态码。状态 1 常常伴随着错误日志本身不完整优先去 Windows 事件查看器里捞更多细节。状态 40 和 46 疑似和 TLS 加密协商相关建议检查 SQL Server 的 TLS 配置、客户端驱动版本以及是否安装了最新的累积更新。总原则是先看完整日志原文再看服务端和客户端两端的通信协议不要盲目改密码。4. 从报错到修复一次典型故障排查实录4.1 故障现象SQL客户端爆出18456Windows认证却正常之前有朋友的公司内部系统突然连不上测试库SQL Server 的 sa 登录报 18456但用 Windows 身份认证却能顺利连上。一开始他以为是 sa 密码被人改了找我帮忙。我先在本地用 Windows 身份连上数据库执行了认证模式查询发现服务器身份验证确实是混合模式密码对不上这一条就被排除了大部分。接着我打开错误日志看到里面的记录是错误: 18456严重性: 14状态: 5。 登录失败。原因: 为所提供的登录名提供的密码不匹配。但蹊跷的是这个报错记录对应的客户端 IP 是测试机本身的 IP也就是说有人在测试机上用 sa 登录但密码不匹配。我让他自己在测试机上用 sqlcmd 再试一次并确认输入的密码和运维手里记录的密码是否完全一致。4.2 排查步骤的递进思路从日志一行开始定位后来发现问题就出在运维那边保存密码时多了一个空格。这个事听起来很蠢但确实发生过很多次——密码在 Excel、备忘录、邮件转发过程中被自动加了个空格复制到配置文件里完全看不出来。用 sqlcmd 手动输入密码后连接成功。这里我想强调的是排查思路的递进看到 18456先不急着改密码第一件事永远是看日志里的状态码和原因描述第二件事是确认认证模式第三件事才是验证账号密码。顺序反了很容易做出“无效修改”甚至把原本正常的配置搞坏。在这个案例里如果一开始就按网上说的“重置 sa 密码”操作虽然也能解决问题但会造成一次不必要的密码变更所有依赖 sa 的应用都得跟着改。而从日志和认证模式入手只花了五分钟就定位到是“密码复制多了空格”。4.3 如果手里只剩sa密码又没有Windows管理员怎么办这是最麻烦的场景但也不是完全没有办法。如果操作系统管理员权限也没了那就比较棘手因为 SQL Server 的恢复逻辑依赖 Windows 权限。这里我假设你至少还有 Windows 管理员权限只是 sa 密码彻底失传。以管理员身份打开命令提示符先把 SQL Server 服务停掉net stop MSSQLSERVER然后以单用户模式启动net start MSSQLSERVER -m注意-m参数会限制为单用户连接且默认只允许本地连接。启动完成后另开一个命令提示符用 Windows 身份连接sqlcmd -S . -E连接成功后在 sqlcmd 里重置 sa 密码ALTER LOGIN [sa] WITH PASSWORD N你的新密码, CHECK_POLICY OFF; ALTER LOGIN [sa] ENABLE; GO执行完GO后退出 sqlcmd然后重启服务这次不要带-m参数net stop MSSQLSERVER net start MSSQLSERVER最后用新密码连接验证。需要提醒的是单用户模式下如果连接不释放其他连接是进不来的。如果你在 sqlcmd 窗口挂太久记得及时退出。我在实际操作中习惯执行完脚本立刻exit避免占用连接导致自己把自己锁在门外。4.4 如果Windows身份也登不上旧账重提的恢复方案如果你连 Windows 身份都连不上一种可能是当前 Windows 用户不在任何 sysadmin 角色的成员列表里。这种情况只能通过单用户模式 管理员操作系统权限恢复思路和上面一样但是登录时要用-E选项。SQL Server 在单用户模式下会允许本地 Windows 管理员作为 sysadmin 登录这也是微软留下的后门通道。恢复后第一时间把当前 Windows 用户加到 sysadmin 服务器角色然后重新启动正常模式。这一步的操作意图很明确在没有任何可用 SQL 登录名的情况下借助操作系统的管理员身份强制进入实例重置 sa 密码或修复合法的管理员登录名。整个过程要小心别在生产库上执行错了命令最好先在测试环境演练一遍。5. SQL Server登录失败排查速查表与避坑指南5.1 五分钟快速判断问题域的思路遇到 18456 不用慌按照下面这个三步法走看状态码从 SQL Server 错误日志或 Windows 事件日志里找到 18456 对应的状态码。看日志原文找到“原因”后面的描述比如“密码不匹配”“禁用”“锁定”。对表定位结合状态码和描述确定是认证模式类、账号状态类还是权限类问题。只要状态码读对了至少能节约半小时的盲目排错时间。我在处理其他同事提交的问题时通常让同事先截图错误日志原文配合状态码基本能直接给出处理方向。5.2 常见问题速查表现象状态码可能原因处理建议sa 登录报 18456原因“密码不匹配”5密码错误 / 认证模式不匹配 / 密码含特殊字符确认密码检查认证模式检查连接串转义sa 登录报“禁用的登录名”6sa 或登录名被禁用ALTER LOGIN [sa] ENABLE连续输错密码后被锁7触发账户锁定策略ALTER LOGIN [sa] WITH UNLOCK登录报“密码已过期”8密码策略过期修改密码登录报“密码必须更改”9强制密码修改修改密码或调整密码策略本地 Windows 能连远程 184565/11TCP/IP 未启用 / 防火墙未放行 / 端口没监听启用 TCP/IP固定端口放行防火墙应用连不上报 18456日志有 SSL 相关5TLS 配置不匹配连接串加 TrustServerCertificateTrueSQL 登录被拒绝11缺少 CONNECT SQL 权限GRANT CONNECT SQL TO 登录名这张表只覆盖了高频场景。如果你想把它变成自己的排查武器建议把表里的状态码和原因描述抄到自己的笔记里下次报错时对照着看效率翻倍。5.3 新手最容易踩的5个坑第一改完认证模式不重启服务。很多人在 SSMS 里切换成混合模式后直接测试发现还是 18456然后怀疑自己操作错了。实际上认证模式的改动必须重启 SQL Server 服务才生效。第二启用 TCP/IP 后不重启服务或不停在配置里固定端口。TCP/IP 协议启用后同样需要重启服务动态端口如果不固定客户端下次连接可能找不到入口。第三密码重置后不检查“禁用”状态。sa 或某个 SQL 登录名在重置密码后仍然是禁用状态你以为是密码问题实际是禁用问题。第四防火墙只开了 1433 端口却忽略了命名实例需要 UDP 1434。如果你连的是命名实例只开 1433 不够SQL Server Browser 服务的 UDP 1434 也要放行。第五把生产库的密码策略直接关掉。有些同学图省事修改 sa 密码时把所有策略都关掉结果生产环境的安全审计被打穿。我的建议是即使要临时关闭事后也要恢复合理的密码策略。5.4 我的两个独家小技巧技巧一在测试环境里故意制造一次 18456 错误然后去错误日志里找对应记录。这个方法对新手特别管用你可以亲手感受一下“状态码 5”和“状态码 6”在日志原文中的区别。一旦你见过真实的日志格式以后再遇到就不会慌。技巧二使用 sqlcmd 命令验证连接时加上-l参数控制登录超时避免因为网络问题一直卡在那里。一个标准的测试命令是sqlcmd -S 192.168.1.10 -U sa -P 你的密码 -l 5如果本地 sqlcmd 测试通过但程序连接失败问题基本出在连接串或驱动的配置上。如果本地测试也失败那就老老实实按状态码去排查服务端。我之前处理过一个最复杂的案例本地 sqlcmd 能连、本机程序也能连偏偏远程程序连不上。后来查出来是服务器上配置了多个 IPSQL Server 监听的是其中一个内网 IP而客户端访问的是另一个 IP。这种问题排查到最后已经不是 18456 本身能解决的了需要结合网络拓扑和 SQL Server 监听地址一起看。遇到这种概率很低的配置问题时别钻牛角尖先检查服务监听地址是否与客户端访问地址一致。最后再分享一点个人体会SQL Server 的 18456 错误是数据库维护工作中最常见的登录类错误之一但它从来不是“玄学”。它的背后永远是具体的配置状态、账号状态、网络状态和权限状态。读日志、看状态码、按步骤排查这套流程走完绝大多数问题都能迎刃而解。希望这篇内容能帮你少走几步弯路尤其是在那些让人容易忽视的细节上。
阅读完成 · 觉得有帮助?
咨询建站