上一篇
作者:某DBA的深夜咖啡
最后更新:2025年8月
"老张,咱们那个Oracle9i的订单库得和10g的报表库做实时同步,下周一上线!" 项目经理拍着我肩膀时,我嘴里的咖啡差点喷出来——这俩版本中间差了整整一代,官方文档里都写着"建议升级到统一版本",可现在偏偏要玩混搭。
作为团队里最熟悉Oracle复制的"老油条",我决定把这次搭建过程记下来,毕竟这种跨版本复制就像让Windows XP和Windows 10共享剪贴板,坑肯定不少。
-- 9i端查询 SELECT * FROM v$version WHERE banner LIKE '%Oracle%'; -- 结果:Oracle9i Enterprise Edition Release 9.2.0.8.0 -- 10g端查询 SELECT * FROM v$version WHERE banner LIKE '%Oracle%'; -- 结果:Oracle Database 10g Enterprise Edition Release 10.2.0.5.0
全局数据库名必须不同:
-- 分别在主从库执行 SELECT * FROM GLOBAL_NAME;
(主库:ORCL9I_PRD,从库:ORCL10G_RPT)
归档模式必须开启:
ARCHIVE LOG LIST; -- 两库都要显示"Archive Mode Enabled"
补充日志强制开启:
-- 主库执行 ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
-- 创建复制管理员账号(名字随便取,但两边要一致) CREATE USER rep_admin IDENTIFIED BY "Repl_123!@#" DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp; GRANT CONNECT, RESOURCE, DBA TO rep_admin; GRANT EXECUTE ON DBMS_DEFER TO rep_admin; -- 创建物化视图日志(以订单表ORDERS为例) CREATE MATERIALIZED VIEW LOG ON scott.orders WITH PRIMARY KEY, ROWID;
⚠️ 坑点1:9i的DBMS_REPCAT
包和10g的DBMS_REPCAT
有细微差异,遇到"参数不匹配"错误时,需要显式指定参数名:
-- 错误写法(10g可以,9i报错) BEGIN DBMS_REPCAT.CREATE_MASTER_REPGROUP('ORDERS_REP'); END; -- 正确写法 BEGIN DBMS_REPCAT.CREATE_MASTER_REPGROUP( gname => 'ORDERS_REP', master_comment => '订单表复制组' ); END;
-- 创建数据库链接(指向主库) CREATE PUBLIC DATABASE LINK ORCL9I_LINK CONNECT TO rep_admin IDENTIFIED BY "Repl_123!@#" USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.100)(PORT=1521))(CONNECT_DATA=(SID=ORCL9I)))'; -- 测试链接 SELECT * FROM dual@ORCL9I_LINK; -- 能返回数据才算成功 -- 创建物化视图 CREATE MATERIALIZED VIEW scott.orders_mv REFRESH FAST WITH PRIMARY KEY START WITH SYSDATE NEXT SYSDATE + 5/1440 -- 每5分钟刷新 AS SELECT * FROM scott.orders@ORCL9I_LINK;
⚠️ 坑点2:10g默认启用自动内存管理(AMM),但和9i复制时容易引发ORA-04031错误,需要切回手动模式:
ALTER SYSTEM SET sga_target=0 SCOPE=SPFILE; ALTER SYSTEM SET pga_aggregate_target=0 SCOPE=SPFILE; ALTER SYSTEM SET shared_pool_size=800M SCOPE=SPFILE; ALTER SYSTEM SET db_cache_size=1G SCOPE=SPFILE; -- 重启实例生效
-- 主库插入测试数据 INSERT INTO scott.orders VALUES (999999, SYSDATE, 'TEST'); COMMIT; -- 从库查询(等待5分钟后) SELECT * FROM scott.orders_mv WHERE order_id = 999999;
检查物化视图日志队列:
-- 主库执行 SELECT * FROM DBA_REPCATLOG; -- 确保没有长时间滞留的事务
强制立即刷新测试:
-- 从库执行 BEGIN DBMS_MVIEW.REFRESH('scott.orders_mv', method => 'F'); END;
网络延迟模拟(用Linux的tc工具):
# 在10g服务器上执行 tc qdisc add dev eth0 root netem delay 500ms
然后观察复制是否超时(9i默认超时时间是30秒)
调整9i端的LGWR进程:
ALTER SYSTEM SET log_archive_max_processes=4 SCOPE=BOTH;
10g端调整物化视图并行度:
ALTER MATERIALIZED VIEW scott.orders_mv PARALLEL 4;
关键视图监控SQL(保存成daily_check.sql):
-- 复制延迟监控 SELECT mview_name, last_refresh_date, (SYSDATE - last_refresh_date)*1440 AS minutes_late FROM user_mviews; -- 网络传输统计 SELECT * FROM V$REPDESTSTAT WHERE status != 'NORMAL';
折腾三天后,系统终于稳定同步,总结几个血泪教训:
现在这套系统已经跑了半年,每天同步200多万条订单记录,每次看到监控面板上的绿色状态灯,都会想起那个边翻20年前PDF文档边骂娘的深夜——或许这就是DBA的浪漫吧。
本文由 朱傲旋 于2025-08-02发表在【云服务器提供商】,文中图片由(朱傲旋)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/514851.html
发表评论