注册服务器是 SSMS 里的书签表:存组名、服务器名、认证方式,写在本机的 RegSrvr.xml 里。
服务器名有五种写法:.、(local)、localhost、机器名、机器名\实例名;
tcp:主机,端口 是显式指定协议。
注册了不等于连得上;端口通了也不代表对面是 SQL Server。
这一节是第 3 章的收尾,也是 SSMS 里第一个要点的按钮。 教材讲得很轻:建组、注册、删除,三步。 但「注册」这个词容易误会成「连接」。 其实它只是往本地存一条记录,跟浏览器书签一个性质——存下来不代表打得开。 演示里把六台服务器注册进三个组,再拿 1433 端口挨个探一遍。 结果一台都连不上,而原因各不相同。这正好把「注册」和「可用」的差别摆清楚。
一、服务器组:只是一个文件夹
SSMS 的「已注册的服务器」窗口里,第一层是组,第二层才是服务器。
组不参与连接,它只影响这个窗口怎么排。 可以按环境分(生产/测试/本机),也可以按项目分。
组是纯本地的,不跟着服务器走。 你在自己机器上建一个「生产」组,同事的 SSMS 里看不到;
反过来,你把服务器删了,服务器本身一点事没有。
教材建议按环境分组,这个建议值得听。 生产库和测试库长得一模一样,选错了对象执行 DELETE,
代价不是重跑一遍能补回来的。
分组的价值就在这一步之前——让你在点「执行」之前,眼睛能扫到「生产」两个字。
二、注册与删除服务器
注册的动作是:右键组 → 新建服务器注册 → 填服务器名、选认证方式 → 保存。
只有三步,但它顺手记下了两样东西:服务器名和认证方式。
认证方式这一栏会跟服务器名一起存下来,下次双击就直接用这套方式连。选了「Windows 身份验证」,
双击时用的是你当前登录的 Windows 账户;
选了「SQL Server 身份验证」,得在注册时就填好用户名密码,或者双击时再输。
密码存不存是个选择。 存了省事,但它是加密后写在 RegSrvr.xml 里的,换台机器拷过去就用不了。
生产环境建议不存,每次输。
删除注册只删这条记录。 服务器上的库、登录名、作业,一样都不会动。
这一点跟「分离数据库」完全不同——那个是真从实例上摘下来。
三、五种服务器名写法
服务器名这一栏能填的东西比想象的多。演示里解析了六种,归结起来是五类:
| 写法 | 指向 | 什么时候用 |
|---|---|---|
| . | 本机默认实例 | 最短,只在本机有效 |
| (local) | 本机默认实例 | 老写法,跟点号等价 |
| localhost | 本机默认实例 | 通用写法,别的数据库也认 |
| 机器名 | 本机默认实例 | 能写进文档、发给别人 |
| 机器名\实例名 | 本机命名实例 | 连 Express 必用 |
| tcp:主机,端口 | 指定协议和端口 | 跨网段、跨防火墙 |
前三种只在本机有效,写进文档发给同事,人家连不上。所以配置文档里的服务器名,
一律写机器名或 IP,别写点号。
第五行那个反斜杠是命名实例的写法,不是路径。 一个反斜杠,两边都不能有空格。
写成 机器名 \ SQLEXPRESS 就连不上——空格会被当成名字的一部分。
最后一行 tcp:主机,端口 是显式指定。 只有 TCP 协议能这么写;
用了它就不再问 Browser 服务,直接连指定端口。
跨网段、跨防火墙的时候这是唯一可靠的办法,因为 Browser 用的是 UDP 1434,很多防火墙不放行 UDP。
四、注册 ≠ 连得上
演示里注册了六台:两台生产的、两台测试的、两台本机的。拿 1433 端口挨个探,一台都连不上。 六台全是超时,一个「连接被拒绝」都没有。 这两个反馈的含义完全不同:拒绝说明对方主机在、 端口明确回了 RST; 超时说明连 RST 都收不到——包在路上被丢了,可能是防火墙,也可能主机根本不在这网段。 这台机器上连本机端口也是超时。 说明这里的防火墙对没人监听的端口是丢包,不是回拒绝。 所以「超时」这个词本身不指向任何具体原因,只能往下查。 还有一个对照值得看:本机 135 端口是通的。 那是 RPC,系统自己在用。 这正好说明「端口能连上」不等于「对面是 SQL Server」——要知道对面是谁,得等握手时的那几个字节, 那是驱动干的活。 最后落到这一节的结论:注册是在本地记一笔,连接是一次完整的网络加认证过程。记一笔不花代价, 也不带来任何保证。双击之前,谁也不知道通不通。
五、本章小结
3.1 讲服务是什么:一个实例是一组服务,引擎是核心;服务账户决定能碰哪些文件; 启动类型只有 2、3、4 三个数要认。 3.2 讲怎么起:三种方式各有场合;「自动」不等于「正在运行」;返回码 2 有两种含义; 依赖断一环报 1068。 3.3 讲怎么记:注册只是本地书签;服务器名五种写法;注册了不等于连得上。 三节连起来是一条排查路径:服务起没起 → 端口通不通 → 名字对不对。 连不上数据库的时候按这个顺序走,比乱试连接串省时间得多。
六、动手 Demo:解析服务器名并探一遍端口
这一段做三件事:把六种服务器名拆成「主机/实例/端口」,把六台服务器按三个组登记一遍, 再拿 1433 端口挨个探,看注册和可用到底差多远。
import socket
def parse(s):
"""把服务器名拆成 主机 / 实例 / 端口,跟 sqlcmd 的 -S 吃的是同一套写法。"""
port, host, inst = u"", s, u""
if s.startswith(u"tcp:"):
s = s[4:]
if u"," in s:
host, port = s.split(u",", 1)
return host, u"", port
if u"\\" in s:
host, inst = s.split(u"\\", 1)
if host in (u".", u"(local)", u"localhost", u"127.0.0.1"):
host = u"本机(%s)" % host
return host, inst, port
for name in (u".", u"localhost", u"PC01\\SQLEXPRESS", u"tcp:10.0.1.5,1433"):
print(name, u"->", parse(name))
# 注册过的服务器,挨个探 1433
for host in (u"10.0.1.11", u"127.0.0.1"):
try:
s = socket.create_connection((host, 1433), 0.4)
s.close()
print(host, u"连得上")
except socket.timeout:
print(host, u"超时:包被丢了")
except OSError as e:
print(host, u"错误码 %s:端口明确拒绝" % e.errno)
实跑输出:
--------------------------------------------------------------------
注册服务器:本机的一张书签表
--------------------------------------------------------------------
① 服务器名有五种写法,解析出来不一样
--------------------------------------------------------------------
| 写法 | 主机 | 实例 | 端口 |
|---|---|---|---|
| . | 本机(.) | 默认实例 | 未指定(1433 或问 Browser) |
| (local) | 本机((local)) | 默认实例 | 未指定(1433 或问 Browser) |
| localhost | 本机(localhost) | 默认实例 | 未指定(1433 或问 Browser) |
| DESKTOP-9NS2P4R | DESKTOP-9NS2P4R | 默认实例 | 未指定(1433 或问 Browser) |
| DESKTOP-9NS2P4R\SQLEXPRESS | DESKTOP-9NS2P4R | SQLEXPRESS | 未指定(1433 或问 Browser) |
| tcp:192.168.1.20,1433 | 192.168.1.20 | 默认实例 | 1433 |
点号、括号 local、localhost 是三种「本机」的老写法,都指向同一个地方。
最后一行是显式指定协议和端口——只有 TCP 才能这么写,跨网段、跨防火墙时常用。
② 注册服务器就是本地存一张分组表
--------------------------------------------------------------------
| 组 | 服务器 | 实例 | 认证方式 |
|---|---|---|---|
| 生产 | 10.0.1.11 | 默认实例 | SQL 身份验证 |
| 生产 | 10.0.1.12\SHOP | SHOP | Windows 身份验证 |
| 测试 | 10.0.2.31 | 默认实例 | SQL 身份验证 |
| 测试 | 10.0.2.32\QA | QA | Windows 身份验证 |
| 本机 | DESKTOP-9NS2P4R | 默认实例 | Windows 身份验证 |
| 本机 | DESKTOP-9NS2P4R\SQLEXPRESS | SQLEXPRESS | Windows 身份验证 |
合计 6 台,分 3 组
③ 注册了不等于连得上
--------------------------------------------------------------------
拿 1433 端口挨个探一遍:连得上 0 台,连不上 6 台
| 注册过的服务器 | 错误码 | 耗时 ms | 含义 |
|---|---|---|---|
| 10.0.1.11 | 超时 | 419 | 包被丢了 |
| 10.0.1.12\SHOP | 超时 | 412 | 包被丢了 |
| 10.0.2.31 | 超时 | 411 | 包被丢了 |
| 10.0.2.32\QA | 超时 | 414 | 包被丢了 |
| DESKTOP-9NS2P4R | 超时 | 415 | 包被丢了 |
| DESKTOP-9NS2P4R\SQLEXPRESS | 超时 | 413 | 包被丢了 |
六台全是超时,一个「连接被拒绝」都没有。
对照:本机 135 端口 连得上(1 ms)
135 是 RPC 端口,它开着是因为系统自己在用。
所以「端口能连上」只说明有人在那儿听,不说明它是 SQL Server——
真要靠握手时的协议头才能认出对方是谁,这也是驱动做的事。
注册服务器只是在 SSMS 里存了一条记录(写在用户配置目录的 RegSrvr.xml 里),
它不验证、不缓存、不保持连接。点了才知道通不通。
超时和错误码 10061 是两种不同的反馈:10061 说明对方主机在、端口明确拒绝;
超时说明连拒绝都收不到——这台机器就是防火墙在丢包,不是回 RST。
上面那些 10.0 开头的服务器名是我编的,连不上是正常的;
本机那两台连不上,是因为这台机器根本没装 SQL Server。
注册和可用是两件事,本节讲的就是这个差别。
第一段那六行,前三行都指向本机。
点号、(local)、localhost 是三种写法一个意思,都是「本机默认实例」。
第四行开始才是能写进文档的形式。
第五行那个反斜杠是命名实例的标志。 一个反斜杠,两边不留空格。
写成 PC01 \ SQLEXPRESS 就连不上,因为空格会变成名字的一部分。
最后一行 tcp:主机,端口 是显式指定协议和端口,跨防火墙时唯一可靠——它不再去问 Browser 服务,
也就绕开了 UDP 1434 被挡的问题。
第二段探出来全是超时。
注意我区分了「超时」和「错误码」两种反馈:超时是包被丢了,拒绝是对方明确回了 RST。
这两种含义完全不同,但很多人只看「连不上」三个字。
最后那个对照是本节的点睛:本机 135 端口是通的,但它不是 SQL Server。端口通只说明有人在那儿听,
认对面是谁要靠协议握手——那是驱动的事,不是 telnet 能看出来的。
30 秒实验
- 打开 SSMS 的「已注册的服务器」,建一个叫「测试」的组,随便注册一台服务器(连不上没关系)。 然后右键删掉它,再去「对象资源管理器」里看——那边不会有任何变化。
- 把
tcp:主机,端口这种写法记住,下次在防火墙后面连不上时先试它。 它能绕开 Browser 服务,而 Browser 用的是 UDP,很多防火墙不放行 UDP。 - 想一想:为什么配置文档里的服务器名不能写「.」? 因为点号只在本机有效。 同事照文档敲「.」,连的是他自己的机器,不是你的。
常见误区
- 「注册了服务器就等于能连上」。两者没关系。
注册只是往本地
RegSrvr.xml写一条记录,不验证、不缓存、不保活。 双击之后才发现连不上,是常态。 - 「telnet 通 1433 就说明 SQL Server 正常」。只能说明那个端口有人监听。 认对面是不是 SQL Server,要看握手时返回的协议头,telnet 看不出来; 而且很多驱动启用加密之后,握手内容根本没法肉眼判断。
- 「点号最省事,文档里就写点号」。点号只在本机有效。 配置文档里一律写机器名或 IP,否则同事照着做,连的是他自己那台。
自测三问(点开对答案)
1. 注册服务器时存了哪两样东西? —— **服务器名和认证方式。** 认证方式决定了双击时用 Windows 账户还是 SQL 账户。 如果选了 SQL 认证还勾了「记住密码」,密码会加密写进 `RegSrvr.xml`,换机器就用不了。 2. `机器名\SQLEXPRESS` 和 `SQL Server (SQLEXPRESS)` 有什么区别? —— **前者是连接用的服务器名,后者是服务面板里的显示名。**连接串里要写前者(一个反斜杠, 无空格);往 `net start` 里敲要用 `MSSQL$SQLEXPRESS`。三个地方三种写法,这是最容易混的一处。 3. 为什么「超时」和「连接被拒绝」要分开看? —— **因为指向的原因不同。** 拒绝说明主机在、端口明确回了 RST——服务没起或端口不对; 超时说明连 RST 都收不到——防火墙丢包、路由不通,或者主机根本不在。 这两种情况的排查方向完全相反。第 3 章到此结束。 下一篇进第 4 章 4.1,讲「数据库」这个对象本身: 数据文件和日志文件各自的角色、五个系统库分别管什么、文件组为什么要分。
- ☐ (本篇完,下一篇 4.1 认识数据库)