改库名不是一条命令的事。nid 只改控制文件和数据文件头里的 DB_NAME,实例名、spfile 文件名、密码文件、监听注册、目录结构、PDB 名称都要跟着改,漏掉任何一处都会在下次重启时暴露。本文按实际操作顺序走一遍,环境是 Red Hat 7.9 + Oracle 19.10,CDB 名 CFCDB、PDB 名 CFPDB,目标改为 YZCDB / YZPDB。
先做全库备份,并且确认备份可恢复。nid 会同时修改 DBID,改完之后原有的备份和归档日志全部失效,这是不可逆的。生产库还要额外确认:有停库窗口、应用已停止、Data Guard 关系已解除或同步处理、有回退到原库的完整副本。
一、环境与改前确认
| 项目 | 版本 |
|---|---|
| 操作系统 | Red Hat 7.9 |
| 数据库 | Oracle 19.10.0.0 |
先记录当前标识,改完之后要拿它对比:
SQL> select dbid, name from v$database;
DBID NAME
---------- ---------
1601623831 CFCDB
SQL> show parameter name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cdb_cluster_name string
cell_offloadgroup_name string
db_file_name_convert string
db_name string CFCDB
db_unique_name string CFCDB
global_names boolean FALSE
instance_name string CFCDB
lock_name_space string
log_file_name_convert string
pdb_file_name_convert string
processor_group_name string
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string CFCDB
RMAN 全备:
rman target /
RMAN> backup database plus archivelog;
RMAN> validate database;
二、用 nid 修改 DB_NAME
1. 停库并启动到 mount
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 2080374576 bytes
Fixed Size 9142064 bytes
Variable Size 637534208 bytes
Database Buffers 1426063360 bytes
Redo Buffers 7634944 bytes
Database mounted.
2. 执行 nid
SQL> !nid target=sys/your_password dbname=YZCDB
DBNEWID: Release 19.0.0.0.0 - Production on Mon Jun 5 14:36:11 2023
Connected to database CFCDB (DBID=1601623831)
Connected to server version 19.10.0
Control Files in database:
/oracle/app/db/oradata/CFCDB/control01.ctl
/oracle/app/db/fast_recovery_area/CFCDB/control02.ctl
Change database ID and database name CFCDB to YZCDB? (Y/[N]) => y
Proceeding with operation
Changing database ID from 1601623831 to 1594212955
Changing database name from CFCDB to YZCDB
Control File /oracle/app/db/oradata/CFCDB/control01.ctl - modified
Control File /oracle/app/db/fast_recovery_area/CFCDB/control02.ctl - modified
Datafile /oracle/app/db/oradata/CFCDB/system01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/sysaux01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/undotbs01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/pdbseed/system01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/pdbseed/sysaux01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/users01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/pdbseed/undotbs01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/system01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/sysaux01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/undotbs01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/users01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/cfuser01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/temp01.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/pdbseed/temp012023-05-30_10-32-18-659-AM.db - dbid changed, wrote new name
Datafile /oracle/app/db/oradata/CFCDB/CFPDB/temp01.db - dbid changed, wrote new name
Control File /oracle/app/db/oradata/CFCDB/control01.ctl - dbid changed, wrote new name
Control File /oracle/app/db/fast_recovery_area/CFCDB/control02.ctl - dbid changed, wrote new name
Instance shut down
Database name changed to YZCDB.
Modify parameter file and generate a new password file before restarting.
Database ID for database YZCDB changed to 1594212955.
All previous backups and archived redo logs for this database are unusable.
Database is not aware of previous backups and archived logs in Recovery Area.
Database has been shutdown, open database with RESETLOGS option.
Succesfully changed database name and ID.
DBNEWID - Completed succesfully.
三个关键提示:要改参数文件、要重建密码文件、必须以 RESETLOGS 打开。三件事都要做。
3. 处理 ORA-01103
nid 结束后实例是关闭的,用原来的 SID 连上去启动会报错:
SQL> startup mount;
ORACLE instance started.
Total System Global Area 2080374576 bytes
Fixed Size 9142064 bytes
Variable Size 637534208 bytes
Database Buffers 1426063360 bytes
Redo Buffers 7634944 bytes
ORA-01103: database name 'YZCDB' in control file is not 'CFCDB'
控制文件里已经是新名字,spfile 里还是旧的。改掉再启动:
SQL> alter system set db_name=YZCDB scope=spfile;
System altered.
SQL> shutdown immediate;
ORA-01507: database not mounted
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
...
Database mounted.
SQL> select dbid, name from v$database;
DBID NAME
---------- ---------
1594212955 YZCDB
SQL> alter database open resetlogs;
Database altered.
此时 db_name 和 db_unique_name 都变成 YZCDB,但 instance_name 仍是 CFCDB:
SQL> show parameter name
...
db_name string YZCDB
db_unique_name string YZCDB
instance_name string CFCDB
...
service_names string YZCDB
三、修改 INSTANCE_NAME
1. 停库
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
2. 改 ORACLE_SID 并重命名 spfile
[oracle@ora-recover01 ~]$ sed -i s/"ORACLE_SID=CFCDB"/"ORACLE_SID=YZCDB"/g ~/.bash_profile
[oracle@ora-recover01 ~]$ source ~/.bash_profile
[oracle@ora-recover01 ~]$ env | grep ORACLE_SID
ORACLE_SID=YZCDB
[oracle@ora-recover01 dbs]$ mv spfileCFCDB.ora spfileYZCDB.ora
[oracle@ora-recover01 dbs]$ ll
total 18312
-rw-rw----. 1 oracle oinstall 1544 Jun 5 14:56 hc_CFCDB.dat
-rw-r--r--. 1 oracle oinstall 692 Jun 2 11:21 initCFCDB.ora
-rw-r--r--. 1 oracle oinstall 3079 May 14 2015 init.ora
-rw-r-----. 1 oracle oinstall 24 Jun 2 14:18 lkCFCDB
-rw-r-----. 1 oracle oinstall 24 Jun 5 14:50 lkYZCDB
-rw-r-----. 1 oracle oinstall 18726912 Jun 5 14:52 snapcf_CFCDB.f
-rw-r-----. 1 oracle oinstall 3584 Jun 5 14:52 spfileYZCDB.ora
注意 spfile 必须改名,否则新 SID 下找不到参数文件,会退化成用默认参数启动。
3. 启动并确认
SQL> startup
ORACLE instance started.
...
Database mounted.
Database opened.
SQL> show parameter name
...
db_name string YZCDB
db_unique_name string YZCDB
instance_name string YZCDB
...
service_names string YZCDB
4. 重新注册监听
SQL> alter system register;
System altered.
SQL> host lsnrctl reload
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 05-JUN-2023 15:33:22
...
The command completed successfully.
SQL> host lsnrctl status
...
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ora-recover01)(PORT=1526)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1526)))
The listener supports no services
The command completed successfully
The listener supports no services 说明服务还没注册上,等几十秒或再执行一次 alter system register。如果一直为空,检查 local_listener 和 service_names。
5. 重建密码文件
[oracle@ora-recover01 dbs]$ orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password='your_password' entries=3
nid 已经提示过必须重建,旧密码文件对应旧 SID,不能直接改名了事。改完确认 remote_login_passwordfile=EXCLUSIVE 时 sys 能远程登录。
6. 其他要同步改的地方
listener.ora、tnsnames.ora里如果写死了SERVICE_NAME = CFCDB,改成新名。/etc/oratab和/etc/rc.local里的 SID。- 监控脚本、备份脚本、crontab 里的
ORACLE_SID。 - 如果配了 Data Guard,
db_unique_name、log_archive_dest_n、fal_server都要改,且要先拆掉 DG 再改。
四、修改数据文件目录(可选)
改库名不要求改目录。但目录名还是旧库名时,后续维护容易看错,可以顺手迁。这一步风险高于前面几步,必须在库名和实例名都改完、库能正常打开之后再做。
1. 生成 pfile 并停库
SQL> create pfile='/home/oracle/pfileYZCDB.ora' from spfile;
File created.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
2. 修改 pfile 中的路径
改前:
*.audit_file_dest='/oracle/app/db/admin/CFCDB/adump'
*.control_files='/oracle/app/db/oradata/CFCDB/control01.ctl','/oracle/app/db/fast_recovery_area/CFCDB/control02.ctl'
*.db_name='YZCDB'
*.db_recovery_file_dest='/oracle/app/db/fast_recovery_area'
*.diagnostic_dest='/oracle/app/db'
改后:
*.audit_file_dest='/oracle/app/db/admin/YZCDB/adump'
*.control_files='/oracle/app/db/oradata/YZCDB/control01.ctl','/oracle/app/db/fast_recovery_area/YZCDB/control02.ctl'
*.db_name='YZCDB'
*.db_recovery_file_dest='/oracle/app/db/fast_recovery_area'
*.diagnostic_dest='/oracle/app/db'
3. 备份旧目录、复制新目录
[oracle@ora-recover01 admin]$ pwd
/oracle/app/db/admin
[oracle@ora-recover01 admin]$ mv CFCDB/ CFCDB.bak
[oracle@ora-recover01 oradata]$ cd /oracle/app/db/oradata/
[oracle@ora-recover01 oradata]$ cp -r CFCDB/ YZCDB
fast_recovery_area 同样处理。用 cp 而不是 mv,旧目录保留到验证通过再删。
4. 用 pfile 启动到 mount
SQL> startup mount pfile='/home/oracle/pfileYZCDB.ora';
启动后查三类文件的实际路径:
SQL> select name from v$datafile;
SQL> select name from v$tempfile;
SQL> select member from v$logfile;
5. 用 RMAN 切换数据文件
[oracle@ora-recover01 ~]$ rman target /
RMAN> catalog start with '/oracle/app/db/oradata/YZCDB/';
Do you really want to catalog the above files (enter YES or NO)? Y
cataloging files...
cataloging done
RMAN> list copy of database;
RMAN> switch database to copy;
catalog 会把新目录下的文件登记进来,switch database to copy 等价于批量 rename file。注意 redo log 不能被 catalog,会报 RMAN-07529: Reason: catalog is not supported for this file type,这是正常的,日志文件要手工 rename。
6. 生成并执行 rename 语句
数据文件:
SQL> set pagesize 0 heading off echo off termout off feedback off linesize 1200 colsep "," trimspool on trimout on
select 'alter database rename file '''||a.NAME||''''||' to '|| '''/oracle/app/db/oradata'||'/'||b.name||'/'||(substr(a.NAME,instr(a.NAME,'/',-1)+1,99999))||''';'
from v$datafile a, v$database b;
临时文件把 v$datafile 换成 v$tempfile,日志文件把 a.NAME 换成 a.MEMBER、表换成 v$logfile。逐条检查生成结果再执行,例如:
alter database rename file '/oracle/app/db/oradata/CFCDB/pdbseed/sysaux01.dbf' to '/oracle/app/db/oradata/YZCDB/pdbseed/sysaux01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/pdbseed/system01.dbf' to '/oracle/app/db/oradata/YZCDB/pdbseed/system01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/pdbseed/undotbs01.dbf' to '/oracle/app/db/oradata/YZCDB/pdbseed/undotbs01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/system01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/system01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/sysaux01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/sysaux01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/undotbs01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/undotbs01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/users01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/users01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/cfuser01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/cfuser01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/CFPDB/temp01.dbf' to '/oracle/app/db/oradata/YZCDB/CFPDB/temp01.dbf';
alter database rename file '/oracle/app/db/oradata/CFCDB/redo03.log' to '/oracle/app/db/oradata/YZCDB/redo03.log';
alter database rename file '/oracle/app/db/oradata/CFCDB/redo02.log' to '/oracle/app/db/oradata/YZCDB/redo02.log';
alter database rename file '/oracle/app/db/oradata/CFCDB/redo01.log' to '/oracle/app/db/oradata/YZCDB/redo01.log';
7. 打开数据库
SQL> alter database open;
Database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 CFPDB MOUNTED
SQL> alter pluggable database CFPDB open;
Pluggable database altered.
用 pfile 启动成功后,记得 create spfile from pfile 回到 spfile 模式,否则下次启动还是走 pfile。
五、修改 PDB 名称
改 PDB 名期间会有短暂中断。先把 PDB 置于 restricted 模式,阻止新连接进来,再处理已有会话。
SQL> select username, machine, terminal, program, client_info, logon_time
from v$session order by logon_time desc;
这条查询用来确认还有谁连着,必要时 alter system kill session 清掉。
SQL> alter pluggable database CFPDB close;
Pluggable database altered.
SQL> alter pluggable database CFPDB open restricted;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 CFPDB READ WRITE YES
进入 PDB 改名:
SQL> alter session set container=CFPDB;
Session altered.
SQL> alter pluggable database rename global_name to YZPDB;
Pluggable database altered.
关闭再正常打开:
SQL> alter pluggable database close immediate;
Pluggable database altered.
SQL> alter pluggable database open;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
3 YZPDB READ WRITE NO
rename global_name 只改 PDB 的全局名,服务名会跟着变,但数据文件路径不会动。应用连接串里的 SERVICE_NAME 要同步更新。
六、修改 PDB 数据文件目录
1. 备份并建新目录
[oracle@ora-recover01 YZCDB]$ cp -r CFPDB/ CFPDBBAK/
[oracle@ora-recover01 YZCDB]$ mkdir /oracle/app/db/oradata/YZPDB
2. 在线 move 数据文件
SQL> alter session set container=YZPDB;
SQL> select name from v$datafile;
/oracle/app/db/oradata/YZCDB/CFPDB/system01.dbf
/oracle/app/db/oradata/YZCDB/CFPDB/sysaux01.dbf
/oracle/app/db/oradata/YZCDB/CFPDB/undotbs01.dbf
/oracle/app/db/oradata/YZCDB/CFPDB/users01.dbf
/oracle/app/db/oradata/YZCDB/CFPDB/cfuser01.dbf
SQL> alter database move datafile '/oracle/app/db/oradata/YZCDB/CFPDB/system01.dbf'
2 to '/oracle/app/db/oradata/YZCDB/YZPDB/system01.dbf';
Database altered.
依次 move sysaux01.dbf、undotbs01.dbf、users01.dbf、cfuser01.dbf。alter database move datafile 在 12c 以后支持在线执行,PDB 处于 open 状态也可以。
3. temp 文件不能 move
对临时文件执行同样的语句会失败:
SQL> alter database move datafile '/oracle/app/db/oradata/YZCDB/CFPDB/temp01.dbf'
2 to '/oracle/app/db/oradata/YZCDB/YZPDB/temp01.dbf';
alter database move datafile '/oracle/app/db/oradata/YZCDB/CFPDB/temp01.dbf' to '/oracle/app/db/oradata/YZCDB/YZPDB/temp01.dbf'
*
ERROR at line 1:
ORA-01516: nonexistent log file, data file, or temporary file
"/oracle/app/db/oradata/YZCDB/CFPDB/temp01.dbf" in the current container
临时表空间只能删了重建:
SQL> alter session set container=YZPDB;
SQL> alter database tempfile '/oracle/app/db/oradata/YZCDB/CFPDB/temp01.dbf' drop including datafiles;
Database altered.
SQL> alter tablespace TEMP add tempfile '/oracle/app/db/oradata/YZCDB/YZPDB/temp01.dbf' size 50M autoextend on;
Tablespace altered.
如果 PDB 里有多个临时表空间,逐个确认默认临时表空间指向,别把 TEMP 删成没有默认值。
4. OMF 环境下的两种做法
开了 OMF 时文件路径由 Oracle 管理,move 有两条路:
停机方式:关库 → 操作系统 mv 文件 → 启动到 mount → alter database rename file '旧' to '新' → open。
表空间方式:alter tablespace ... offline → 操作系统 mv → alter tablespace ... rename datafile '旧' to '新' → online。
两种方式都要求路径和文件名完全对应,改错一个字符就会在 open 时报 ORA-01157。
七、验收清单
select dbid, name from v$database返回新 DBID 和新库名。show parameter name中db_name、db_unique_name、instance_name、service_names全部一致。lsnrctl status能看到新服务名,且状态为READY。sqlplus sys/...@host:port/新服务名 as sysdba能远程登录,说明密码文件正确。show pdbs中 PDB 名称、open mode 正确。select name from v$datafile/v$tempfile/v$logfile无旧路径残留。- 重启一次主机,确认
/etc/oratab、自启动脚本、监听都能拉起。 - 旧目录至少保留到业务验证通过,再清理。
原文首发于微信公众号「止水研习社」。
文章评论