写在前面
目前我们的项目较多项目使用了Oracle数据库。当前虽然国产数据库正成为一个发展趋势,但在未来一两年里,Oracle、MySQL和PostgreSQL仍是主流的选择。尽管网络上有不少关于Oracle数据库主从配置的资料,但这些资料要么信息不完整,要么包含部分错误命令。鉴于山东项目也采用了Oracle数据库,我决定将Oracle配置主从的教程记录下来,希望这能为大家提供一个实用的参考。
这份讲解内容分为多个部分:
- 基础设置:介绍Oracle主从配置的基本环境和前提条件。
- 详细步骤:逐步讲解配置过程,包括每个命令的详细说明。
- 常见问题及解决方案:分享在配置过程中可能遇到的问题及其解决方法。
- 后续维护和管理:提供主从数据库维护和管理的建议和技巧。
希望这份教程能成为使用Oracle数据库的用户的实用参考,特别是对于那些需要配置主从数据库的项目团队。
Data Guard介绍
甲骨文公司推出的DataGuard是一种高可用性数据库解决方案,最初在Oracle 8i及其之前的版本中被称为Standby Database。自Oracle 9i版本起,这一解决方案正式更名为DataGuard。其核心功能是通过在主数据库节点和备份数据库节点之间同步日志来保持数据的一致性,这不仅可以实现数据库的快速切换,还能在发生灾难时快速恢复数据库。DataGuard的一个重要特点是它仅在软件层面上进行数据库的设置调整,不需要用户额外购买任何硬件或软件组件。这使得用户能够在对主数据库造成最小影响的情况下实现主备数据库的同步。此外,主备数据库之间的数据差异通常只存在于在线日志中。因此,DataGuard被广泛应用于众多企业,作为一种有效的数据容灾解决方案。
部署架构
配置准备
开库顺序 先启备库,再启主库(启动监听,打开告警日志)
关库顺序 先关主库再关备库
- 查看数据库版本
csharp
# 主库ip:10.41.170.30;备库ip:ip:10.41.170.130
# 查看数据库版本,必须是企业版否则不支持oracle data guard
SQL> select * from v$version;
- 备库只安装软件(重点,如果不是会出现很多奇奇怪怪的错误)
- 确保备库安装路径、实例名与主库完全一致,避免同步出错(如果不是会出现很多莫名其妙的错误)
一、主库配置
1、在/oracl11下创建interlib文件夹(自定义文件夹名),在创建文件夹log
shell
# 日志文件路径:'logUrl=E:\oracl11\interlib\log'
# 控制文件路径:'standbyUrl=E:\oracl11\interlib'
2、开启归档模式
ini
# 在主库上启动数据库到mount模式,开启归档模式与force logging
sqlplus / as sysdba
SQL>shutdown immediate;
SQL>startup mount;
#修改为归档模式
SQL>alter database archivelog;
SQL>alter database open;
#设置强制归档模式
SQL> alter database force logging;
#查看命令:
select log_mode,force_logging from v$database;
#查看是否归档命令:
Archive log list ;
3、为备库创建日志文件cleart
sql
# logUrl=E:\oracl11\interlib\log 根据实际的"日志文件路径"改变
SQL> alter database add standby logfile group 4 ('E:/oracl11/interlib/log/STAN04.LOG') size 50m;
SQL> alter database add standby logfile group 5 ('E:/oracl11/interlib/log/STAN05.LOG') size 50m;
SQL> alter database add standby logfile group 6 ('E:/oracl11/interlib/log/STAN06.LOG') size 50m;
4、创建standby控制文件
sql
SQL> alter database create standby controlfile as 'E:\oracl11\interlib\standby.ctl';
5、导出当前数据库参数并修改
ini
SQL> create pfile='E:/oracl11/interlib/initora.ora' from spfile;
# 修改相关路径,以及增加没有的参数
orcl11.__db_cache_size=24293408768
orcl11.__java_pool_size=134217728
orcl11.__large_pool_size=134217728
orcl11.__oracle_base='E:\oracl11'#ORACLE_BASE set from environment
orcl11.__pga_aggregate_target=22011707392
orcl11.__sga_target=32883343360
orcl11.__shared_io_pool_size=0
orcl11.__shared_pool_size=7918845952
orcl11.__streams_pool_size=0
*.archive_lag_target=1800
*.audit_file_dest='E:\oracl11\admin\orcl11\adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='E:\oracl11\oradata\orcl11\control01.ctl','E:\oracl11\flash_recovery_area\orcl11\control02.ctl'
*.db_block_size=8192
*.db_cache_size=536870912
*.db_domain=''
*.DB_FILE_NAME_CONVERT='E:\oracl11\oradata\orcl11','E:\oracl11\oradata\orcl11'
*.db_name='orcl11'
*.db_recovery_file_dest='E:\oracl11\flash_recovery_area'
*.db_recovery_file_dest_size=4102029312
*.db_unique_name='primary'
*.diagnostic_dest='E:\oracl11'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orcl11XDB)'
*.fal_client='standby'
*.fal_server='primary'
*.log_archive_config='DG_CONFIG=(primary,standby)'
*.log_archive_dest_1='LOCATION=E:\oracl11\interlib\log\ VALID_FOR=(all_logfiles,all_roles) db_unique_name=primary'
# 设置为异步复制模式async
*.log_archive_dest_2='service=standby arch async valid_for=(online_logfiles,primary_role) db_unique_name=standby'
*.log_archive_dest_state_1='enable'
*.log_archive_dest_state_2='enable'
*.log_archive_format='%t_%s_%r.dbf'
*.LOG_FILE_NAME_CONVERT='E:\oracl11\interlib\log','E:\oracl11\interlib\log'
*.memory_target=54828990464
*.open_cursors=300
*.processes=30000
*.remote_login_passwordfile='EXCLUSIVE'
*.sessions=3350
*.standby_file_management='auto'
*.undo_tablespace='UNDOTBS1'
6、重新加载配置启动服务
ini
#停止服务
SQL> shutdown immediate;
#使用新参数文件启动数据库
SQL> startup pfile='E:\oracl11\interlib\initora.ora' nomount;
#创建新的 spfile 文件
SQL> create spfile from pfile='E:\oracl11\interlib\initora.ora';
#停止服务
SQL> shutdown immediate;
#启动服务
SQL> startup;
7、创建密码文件
ini
# 如果有此步,存在,密码设置为:mstchina*2022
密码文件可不操作
# 在DOS窗口执行,不需要登录sqlplus,路径不能加引号,否则会报opw-00001错误
orapwd file=E:\oracl11\product\11.2.0\dbhome_1\database\PWDorcl11.ora password=mstchina*2022 entries=10
# 密码文件存放路径:
密码文件存放路径:
passwordUrl=E:\oracl11\product\11.2.0\dbhome_1\database\PWDorcl11.ora
# 注意密码文件命名规则.ora命名规则为PWD+sid,我这里的sid为orcl11,所以为PWDorcl11,不然会出现远程登录权限不足
8、配置监听和访问服务
ini
# 修改 listener.ora
# listener.ora Network Configuration
# File: E:\oracl11\product\11.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = E:\oracl11\product\11.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:E:\oracl11\product\11.2.0\dbhome_1\bin\oraclr11.dll")
)
# 添加SID_DESC
(SID_DESC =
(GLOBAL_DBNAME = orcl11)
(ORACLE_HOME = E:\oracl11\product\11.2.0\dbhome_1)
(SID_NAME = orcl11)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.41.170.30)(PORT = 1521))
)
)
ADR_BASE_LISTENER = E:\oracl11
ini
# 修改tnsname.ora文件
# tnsnames.ora Network Configuration File: E:\oracl11\product\11.2.0\dbhome_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools.
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
orcl11=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = WIN-QEDP6N8PVGK)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl11)
)
)
# 增加主库配置
PRIMARY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP) (HOST = 10.41.170.30) (PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl11)
)
)
# 增加备库配置
STANDBY=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP) (HOST = 10.41.170.130) (PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl11)
)
)
9、测试监听
sql
#停止服务
SQL> shutdown immediate;
SQL> startup mount;
#alter database open是数据库处于mount状态,从mount状态打开数据库的命令。
SQL> alter database open;
# 在DOS窗口执行,不需要登录sqlplus,
lsnrctl stop
lsnrctl start
#测试配置是否正确
SQL> sqlplus sys/mstchina*2022@primary as sysdba
PS:若连接失败,检查防火墙设置或者ping下IP地址是否正常。
10、关闭主数据库
arduino
SQL> shutdown immediate;
PS:在配置备库前,需要关闭主数据库,以免产生其他的log
二、备库配置
1、拷贝数据到备库
- 主库和备库创建 E:\oracl11\interlib\tmp 文件夹,并把interlib其余目录也拷贝过去
- 将主库oracle目录下的oradata文件夹下内容复制到备库相同目录
- 将E:\oracl11 目录下的admin,cfgtollogs,diag,flash_recover_area 目录以及密码文件('E:\oracl11\product\11.2.0\dbhome_1\database\PWDorcl11.ora')拷贝到备用库的相同路径。可直接覆盖
- 将standby.ctl文件拷贝到备库的数据文件夹内(E:\oracl11\oradata\orcl11\)和E:\oracl11\flash_recovery_area\orcl11\下。在两个路径下将文件复制为control01.ctl,control02.ctl。
- 将主库的listener.ora和tnsname.ora拷贝到备库相同路径,并修改linstener.ora的ip为备库ip ('E:\oracl11\product\11.2.0\dbhome_1\NETWORK\ADMIN')
ini
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.41.170.130)(PORT = 1521))
)
)
2、备库新建实例
csharp
# 备库新建实例,如果备库也安装了数据库,实例也是orcl11这步可跳过
# 在备库上注册oracle实例到服务中,DOS下执行
oradim -new -sid orcl11
lsnrctl start
3、修改备库参数并创建实例
ini
# 将从主库拷贝的 E:\oracl11\interlib\initora.ora修改
#下面是要修改的地方
orcl11.__db_cache_size=24293408768
orcl11.__java_pool_size=134217728
orcl11.__large_pool_size=134217728
orcl11.__oracle_base='E:\oracl11'#ORACLE_BASE set from environment
orcl11.__pga_aggregate_target=22011707392
orcl11.__sga_target=32883343360
orcl11.__shared_io_pool_size=0
orcl11.__shared_pool_size=7918845952
orcl11.__streams_pool_size=0
*.archive_lag_target=1800
*.audit_file_dest='E:\oracl11\admin\orcl11\adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='E:\oracl11\oradata\orcl11\control01.ctl','E:\oracl11\flash_recovery_area\orcl11\control02.ctl'
*.db_block_size=8192
*.db_cache_size=536870912
*.db_domain=''
*.DB_FILE_NAME_CONVERT='E:\oracl11\oradata\orcl11','E:\oracl11\oradata\orcl11'
*.db_name='orcl11'
*.db_recovery_file_dest='E:\oracl11\flash_recovery_area'
*.db_recovery_file_dest_size=4102029312
*.db_unique_name='standby'
*.diagnostic_dest='E:\oracl11'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orcl11XDB)'
*.fal_client='primary'
*.fal_server='standby'
*.log_archive_config='DG_CONFIG=(primary,standby)'
*.log_archive_dest_1='LOCATION=E:\oracl11\interlib\log\ VALID_FOR=(all_logfiles,all_roles) db_unique_name=standby'
*.log_archive_dest_2='service=primary arch async valid_for=(online_logfiles,primary_role) db_unique_name=primary'
*.log_archive_dest_state_1='enable'
*.log_archive_dest_state_2='enable'
*.log_archive_format='%t_%s_%r.dbf'
*.LOG_FILE_NAME_CONVERT='E:\oracl11\interlib\log','E:\oracl11\interlib\log'
*.memory_target=54828990464
*.open_cursors=300
*.processes=30000
*.remote_login_passwordfile='EXCLUSIVE'
*.sessions=3350
*.standby_file_management='auto'
*.undo_tablespace='UNDOTBS1'
使用新参数文件建立备库实例
ini
SQL> startup nomount pfile='E:\oracl11\interlib\initora.ora';
SQL> create spfile from pfile='E:\oracl11\interlib\initora.ora';
SQL> shutdown immediate; #(此步骤可能会报错 01507,暂时忽略)
SQL> startup nomount;
此时登录 sqlplus会报错:ORA-12560: TNS: 协议适配器错误
解决方案如下:
- 检查
OracleOraDb11g_home1TNSlistener
服务是否存在,如果存在看看有没有启动该服务,如果不存在,在E:\oracl11\product\11.2.0\dbhome_1\BIN
路径下的emca.bat双击启动 - 打开环境变量:属性--高级--环境变量---系统变量--新建,变量名=oracle_sid,变量值=XXX,XXX就是你的 database SID,我这里sid是orcl11,如下图所示:
三、主库执行相关语句
1、建立主库备份
ini
# 在备库执行,DOS下执行
sqlplus / as sysdba
SQL> startup;
# 复制主库,使用RMAN建立备份,DOS下执行
rman target /
RMAN> backup full database format='E:\oracl11\interlib\tmp\FOR_STANDBY_%u%p%s,RMN' include current controlfile for standby;
# 将当前archivelog归档,执行sql语句
RMAN> sql 'alter system archive log current'; #主库处于mount或nomount状态时会出现错误,主语sql后的空格
2、复制数据库
复制数据库;将主库E:\oracl11\interlib\tmp
下产生的的备份集拷贝到备库的相同路径下
shell
# 拷贝完成后在主库刚才的RMAN中执行,注意这时备库需要处于nomount状态
RMAN> connect auxiliary sys/mstchina*2022@standby # mstchina*2022为备库sys的密码,
RMAN> duplicate target database for standby nofilenamecheck;
# 执行完后会在备库130的 E:\ORACL11\ORADATA目录出现一些DBF文件
3、配置 备库为备用库模式
sql
#启动备用数据库为挂载备库模式
SQL>startup nomount;
SQL>alter database mount standby database;# 可能会报错 01100不管
#在备用服务器上启动日志传送服务
SQL>alter database recover managed standby database disconnect from session;
SQL>shutdown immediate;
SQL>startup;
四、检查测试
1、状态查看测试
vbnet
# 主库备库分别执行如果 APPLIED 列的值为 yes,表示重做应用成功
SELECT SEQUENCE#,APPLIED FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#;
csharp
# 或者查看切换归档,归档日志记录会+1
select max(sequence#) from v$archived_log;
alter system switch logfile;
select max(sequence#) from v$archived_log;
2、日志查看测试
shell
# 主库上执行(手动归档日志,手动同步)
alter system switch logfile;
#,通过select name from v$archived_log; 可以看到主库和备库都增加了一个log文件(.DBF)
3、查看主备库状态
csharp
# 执行sql语句
select open_mode,protection_mode,database_role,switchover_status from v$database;
五、DG切换
ini
# 主库执行
# 先将主库切换成备库,然后将原主库启动到物理库的状态
alter database commit to switchover to physical standby with session shutdown;
# 关闭主库
shutdown immediate;
# 开数据库nomount
startup nomount;
# 更改主库为备库
alter database mount standby database;
alter database recover managed standby database disconnect from session;
# 如果配置了 standby redo log 并需要启用实时同步则执行以下代码
alter database recover managed standby database using current logfile disconnect from session;
备库执行,switchover到primary
sql
# 更改备库为主库
alter database commit to switchover to primary with session shutdown;
# 如果备库还有未应用的日志则执行
alter database recover managed standby database disconnect from session;
shutdown immediate;
startup
六、DG切换后再恢复最初
即原主库切换为备库,再从备库切换为主库
bash
# 开库顺序
先启备库,再启主库(启动监听,打开告警日志)
# 关库顺序
先关主库再关备库
lsnrctl stop
lsnrctl start
1、主库操作
perl
# 登录原主库
rman target /
RMAN> connect auxiliary sys/123.com@standby
RMAN> duplicate target database for standby nofilenamecheck;
2、备库stnadby
sql
# 在备库执行
sqlplus / as sysdba
SQL>alter database mount standby database; # 可能会报错 01100不管
SQL>alter database recover managed standby database disconnect from session;
3、状态监测
sql
# 或者查看切换归档,归档日志记录会+1
SQL>select max(sequence#) from v$archived_log;
SQL>alter system switch logfile;
SQL>select max(sequence#) from v$archived_log;
4、复制模式切换
ini
### 异步复制,主库上操作
**## 设置归档目的地参数(LOG_ARCHIVE_DEST_n)**
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_db_name ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby_db_unique_name';
## 设置日志传输服务(Log Transport Services)
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_db_name LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby_db_unique_name';
## 确认配置
SQL> SHOW PARAMETER LOG_ARCHIVE_DEST;
# 检查输出中的LOG_ARCHIVE_DEST_n参数值,确保它们包含ASYNC关键字。
ini
### 同步复制,主库上操作
## 设置归档目的地参数(LOG_ARCHIVE_DEST_n)
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_db_name SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby_db_unique_name';
## 设置同步复制使用LGWR SYNC模式,它指示日志写入器进程(Log Writer Process)以同步方式传输重做日志
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_db_name LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby_db_unique_name';
## 确认配置
SQL> SHOW PARAMETER LOG_ARCHIVE_DEST;
# 检查输出中的LOG_ARCHIVE_DEST_n参数值,确保它们包含SYNC关键字。
七、常见错误处理办法
1、ORA-10456
错误号 | 错误描述 |
---|---|
ORA-01507 | database not mounted |
可忽略不处理
2、ORA-10456
错误号 | 错误描述 |
---|---|
ORA-10456 | cannot open standby database; media recovery session may be in progress |
sql
#解决办法
alter database recover managed standby database cancel;
alter database open;
alter database recover managed standby database using current logfile disconnect ;
3、ORA-01031
错误号 | 错误描述 |
---|---|
ORA-01031 | insufficient privileges |
解决方法:检查登录的sid密码文件是否存在,或者命名规则是否正确,注意密码文件命名规则.ora命名规则为PWD+sid,我这里的sid为orcl11,所以为PWDorcl11,不然会出现远程登录权限不足
4、ORA-01031
错误号 | 错误描述 |
---|---|
ORA-01031 | insufficient privileges |
解决方法:检查登录的sid密码文件是否存在,或者命名规则是否正确,注意密码文件命名规则.ora命名规则为PWD+sid,我这里的sid为orcl11,所以为PWDorcl11,不然会出现远程登录权限不足
5、ORA-01110
错误号 | 错误描述 |
---|---|
ORA-01110 | 数据文件 1: 'E:\ORACL11\ORADATA\ORCL11SYSTEM01.DBF' |
解决方法:一般情况是因为数据文件不存在,可通过重新主库备份,可参考以下命令
shell
# 在备库执行,DOS下执行
sqlplus / as sysdba
SQL> startup;
# 复制主库,使用RMAN建立备份,DOS下执行
rman target /
RMAN> backup full database format='E:\oracl11\interlib\tmp\FOR_STANDBY_%u%p%s,RMN' include current controlfile for standby;
# 将当前archivelog归档,执行sql语句
RMAN> sql 'alter system archive log current'; #主库处于mount或nomount状态时会出现错误,主语sql后的空格
RMAN> connect auxiliary sys/mstchina*2022@standby # mstchina*2022为备库sys的密码,
RMAN> duplicate target database for standby nofilenamecheck;
# 执行完后会在备库130的 E:\ORACL11\ORADATA目录出现一些DBF文件
6、ORA-02232
错误号 | 错误描述 |
---|---|
ORA-02232 | ??? MOUNT ?? |
makefile
#解决办法
主库生成的standby.ctl控制文件拷贝到initora.ora中控制文件指定的地方,
再重新使用initora.ora nomount启动数据库即可,对于备库原有的control01.ctl文件进行覆盖,必须保证主库和备库的control01文件一致。
可参考前面的standby.ctl流程,备库需要复制standby.ctl到具体位置,并修改名字
将standby.ctl文件拷贝到备库的数据文件夹内(E:\oracl11\oradata\orcl11\)和E:\oracl11\flash_recovery_area\orcl11\下。在两个路径下将文件复制为control01.ctl,control02.ctl。
7、ORA-01090
错误号 | 错误描述 |
---|---|
ORA-01090 | shutdown in process-connection is not permitted |
perl
#解决办法
再开一个会话执行
shutdown abort
startup
shutdown immediate
8、ORA-01100
错误号 | 错误描述 |
---|---|
ORA-01100 | 数据库已装载 |
可忽略不处理
9、ORA-01153
错误号 | 错误描述 |
---|---|
ORA-01153 | 激活了不兼容的介质恢复 |
perl
#解决办法
再开一个会话执行
shutdown abort
startup
shutdown immediate