必须通过srvctl modify scan_listener -p修改scan监听器端口,同步更新remote_listener参数及客户端连接串;直接编辑配置文件或使用lsnrctl无效,且需stop/start而非reload。

不能直接改 SCAN listener 的端口,Oracle 不允许这么做;必须通过 srvctl 修改并重启,且需同步更新 remote_listener 参数和客户端连接串。
srvctl config scan_listener 显示端口不可写
执行 srvctl config scan_listener 会看到类似 Endpoints: TCP:1521 的输出,但这只是当前生效的监听端点,不是配置文件中可编辑的字段。SCAN listener 的端口由 Oracle 集群自动管理,不存于 listener.ora 或任何文本配置中 —— 它绑定在 SCAN VIP 上,由 grid 用户下的 CRS 资源控制。
常见错误现象:
• 直接修改 $GRID_HOME/network/admin/listener.ora 对 SCAN listener 无效
• 手动启动 lsnrctl start LISTENER_SCAN1 会失败或被 CRS 自动拉回原端口
• 使用 lsnrctl set 命令尝试改端口,提示“not supported for SCAN listeners”
- 真正有效的入口只有
srvctl命令 - 修改后必须 stop/start(不能 reload),否则新端口不会生效
- 所有节点上的 SCAN listener 端口必须一致,否则客户端轮询会失败
srvctl modify scan_listener -p 是唯一合法方式
要将 SCAN listener 端口从默认的 1521 改为 3306(仅作示例,生产环境慎用非标准端口),必须用:
srvctl modify scan_listener -p 3306
然后逐个重启:
srvctl stop scan_listener<br>srvctl start scan_listener
注意:
• 此操作影响整个集群,所有 SCAN VIP(如 scan1、scan2、scan3)都会切换到新端口
• 不需要重启数据库实例,但已建立的连接可能因 TNS 连接超时短暂中断
• 若使用 DNS 轮询解析 SCAN 名,客户端无需改连接串(只要 DNS 指向的是 SCAN name,不是 IP)
- 验证是否生效:
srvctl config scan_listener和lsnrctl status LISTENER_SCAN1中的Listening Endpoints Summary...行 - 如果只改了一个 SCAN listener(比如 LISTENER_SCAN1),其它 SCAN listener(LISTENER_SCAN2/3)端口不会变 ——
srvctl modify scan_listener默认作用于全部 - 该命令必须由
grid用户执行,且 GI 已启动
remote_listener 参数必须同步更新
SCAN listener 修改端口后,每个数据库实例的 remote_listener 参数若仍指向旧端口(如 scan:1521),实例就无法向 SCAN listener 注册服务,srvctl status service 会显示服务 offline,客户端连接报 ORA-12514: TNS:listener does not currently know of service requested in connect descriptor。
检查当前值:
sqlplus / as sysdba<br>SHOW PARAMETER remote_listener
更新方式(以改为 3306 为例):
ALTER SYSTEM SET remote_listener='scan:3306' SCOPE=BOTH;
- 必须对每个实例单独执行(RAC 多实例场景)
- 执行后立刻触发服务注册,无需重启实例
- 如果使用 SCAN name(而非 IP),确保 DNS 解析仍有效;若临时改用 IP,要确认 SCAN VIP 未漂移
- 别漏掉 PDB:CDB 级参数变更对所有 PDB 生效,无需额外操作
客户端连接串和 tnsnames.ora 需要适配
即使 SCAN listener 端口变了,只要客户端用的是 SCAN name(如 myrac-scan)且 DNS 正常,tnsnames.ora 中的端口可以省略(默认走 1521)—— 但这是危险的默认行为。
强烈建议显式指定端口,例如:
MYRAC =<br> (DESCRIPTION =<br> (ADDRESS = (PROTOCOL = TCP)(HOST = myrac-scan)(PORT = 3306))<br> (CONNECT_DATA =<br> (SERVER = DEDICATED)<br> (SERVICE_NAME = orcl)<br> )<br> )
否则一旦某天 SCAN listener 回滚到 1521,而客户端没配 PORT,就会连错端口(实际监听在 3306,客户端却连 1521)。
- Java 应用若用 JDBC URL,格式应为:
jdbc:oracle:thin:@myrac-scan:3306/orcl - tnsping 测试时带端口:
tnsping myrac-scan 3306,避免误判 - 别依赖 sqlnet.ora 的
DEFAULT_SDU_SIZE或SQLNET.EXPIRE_TIME来“绕过”端口问题 —— 它们不解决连接目标错误
最易被忽略的一点:SCAN listener 端口修改后,local_listener 参数不用动,它只管本机 VIP;但所有依赖 remote_listener 注册的服务(包括 PDB service_name)都会重新广播,这个过程是异步的,可能有数秒延迟 —— 别在刚改完就立刻跑压力测试。











