外观
基于GoldenGate的读写分离
概述
基于GoldenGate的读写分离是指利用Oracle GoldenGate技术,将写操作路由到主数据库,将读操作路由到一个或多个备数据库,从而实现数据库的负载均衡和高可用性。GoldenGate支持异构数据库环境,提供低延迟、高吞吐量的数据复制功能,适用于复杂的读写分离场景。
架构设计
读写分离架构
基于GoldenGate的读写分离架构主要包括以下组件:
- 主数据库:处理所有写操作和部分读操作
- 备数据库:处理只读操作,可以是Oracle或其他异构数据库
- GoldenGate Extract进程:从主数据库捕获数据变更
- GoldenGate Data Pump进程:将捕获的数据变更传输到备数据库
- GoldenGate Replicat进程:将数据变更应用到备数据库
- 负载均衡器:负责将客户端请求路由到主库或备库
- 应用层:实现读写分离逻辑,将写操作发送到主库,将读操作发送到备库
读写分离模式
基于GoldenGate的读写分离支持以下模式:
- 单向复制读写分离:从一个主库复制到多个备库,实现读写分离
- 双向复制读写分离:两个数据库之间相互复制,实现双向读写分离
- 级联复制读写分离:通过中间库实现多级读写分离
- 异构数据库读写分离:从Oracle主库复制到其他异构数据库(如MySQL、SQL Server等),实现读写分离
环境准备
系统要求
| 配置项 | 要求 |
|---|---|
| Oracle版本 | 19c或21c |
| GoldenGate版本 | 19c或21c(与Oracle版本兼容) |
| 操作系统 | Linux 64位或Windows 64位 |
| 内存 | 至少8GB(推荐16GB) |
| 磁盘空间 | 至少100GB |
| 网络带宽 | 至少1Gbps(推荐10Gbps) |
初始化配置
- 安装GoldenGate软件
- 配置主数据库和备数据库的Oracle参数
- 配置主数据库和备数据库的网络连接
- 在主数据库和备数据库中创建GoldenGate用户
- 启用主数据库的补充日志和强制日志记录
配置步骤
1. 配置主库GoldenGate
创建GoldenGate用户
sql
CREATE USER ggadmin IDENTIFIED BY ggadmin DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE, DBA TO ggadmin;
GRANT SELECT ANY DICTIONARY, SELECT ANY TABLE TO ggadmin;
GRANT CREATE ANY TABLE, ALTER ANY TABLE, DROP ANY TABLE TO ggadmin;
GRANT CREATE ANY INDEX, ALTER ANY INDEX, DROP ANY INDEX TO ggadmin;启用补充日志和强制日志记录
sql
ALTER DATABASE FORCE LOGGING;
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;配置Manager进程
bash
ggsci
CREATE SUBDIRS
EDIT PARAMS MGR在Manager参数文件中添加以下内容:
PORT 7809
DYNAMICPORTLIST 7810-7909
AUTORESTART EXTRACT *, RETRIES 5, WAITMINUTES 3
AUTORESTART REPLICAT *, RETRIES 5, WAITMINUTES 3
PURGEOLDEXTRACTS /u01/app/ogg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 7创建Extract进程
bash
ggsci
ADD EXTRACT ext1, TRANLOG, BEGIN NOW
ADD EXTTRAIL /u01/app/ogg/dirdat/et, EXTRACT ext1, MEGABYTES 100
EDIT PARAMS ext1在Extract参数文件中添加以下内容:
EXTRACT ext1
USERID ggadmin@primary_db, PASSWORD ggadmin
EXTTRAIL /u01/app/ogg/dirdat/et
TABLE hr.employees;
TABLE hr.departments;创建Data Pump进程
bash
ggsci
ADD EXTRACT dp1, EXTTRAILSOURCE /u01/app/ogg/dirdat/et
ADD RMTTRAIL /u01/app/ogg/dirdat/rt, EXTRACT dp1, MEGABYTES 100
EDIT PARAMS dp1在Data Pump参数文件中添加以下内容:
EXTRACT dp1
USERID ggadmin@primary_db, PASSWORD ggadmin
RMTHOST standby_host, MGRPORT 7809
RMTTRAIL /u01/app/ogg/dirdat/rt
PASSTHRU
TABLE hr.employees;
TABLE hr.departments;2. 配置备库GoldenGate
创建GoldenGate用户
sql
CREATE USER ggadmin IDENTIFIED BY ggadmin DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE, DBA TO ggadmin;
GRANT SELECT ANY DICTIONARY, SELECT ANY TABLE TO ggadmin;
GRANT CREATE ANY TABLE, ALTER ANY TABLE, DROP ANY TABLE TO ggadmin;
GRANT CREATE ANY INDEX, ALTER ANY INDEX, DROP ANY INDEX TO ggadmin;
GRANT INSERT ANY TABLE, UPDATE ANY TABLE, DELETE ANY TABLE TO ggadmin;配置Manager进程
bash
ggsci
CREATE SUBDIRS
EDIT PARAMS MGR在Manager参数文件中添加以下内容:
PORT 7809
DYNAMICPORTLIST 7810-7909
AUTORESTART EXTRACT *, RETRIES 5, WAITMINUTES 3
AUTORESTART REPLICAT *, RETRIES 5, WAITMINUTES 3
PURGEOLDEXTRACTS /u01/app/ogg/dirdat/*, USECHECKPOINTS, MINKEEPDAYS 7创建Checkpoint表
bash
ggsci
DBLOGIN USERID ggadmin@standby_db, PASSWORD ggadmin
ADD CHECKPOINTTABLE ggadmin.checkpoint创建Replicat进程
bash
ggsci
ADD REPLICAT rep1, EXTTRAIL /u01/app/ogg/dirdat/rt, CHECKPOINTTABLE ggadmin.checkpoint
EDIT PARAMS rep1在Replicat参数文件中添加以下内容:
REPLICAT rep1
USERID ggadmin@standby_db, PASSWORD ggadmin
ASSUMETARGETDEFS
DISCARDFILE /u01/app/ogg/dirrpt/rep1.dsc, APPEND, MEGABYTES 100
MAP hr.employees, TARGET hr.employees;
MAP hr.departments, TARGET hr.departments;3. 启动GoldenGate进程
bash
# 启动主库进程
ggsci@primary
START MGR
START EXTRACT ext1
START EXTRACT dp1
# 启动备库进程
ggsci@standby
START MGR
START REPLICAT rep14. 应用层读写分离实现
Java应用实现
在Java应用中,可以使用Spring框架的AbstractRoutingDataSource实现读写分离:
java
// 配置主库数据源
@Bean(name = "primaryDataSource")
public DataSource primaryDataSource() {
// 配置主库数据源
}
// 配置备库数据源
@Bean(name = "standbyDataSource")
public DataSource standbyDataSource() {
// 配置备库数据源
}
// 配置动态数据源
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource,
@Qualifier("standbyDataSource") DataSource standbyDataSource) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceType.PRIMARY, primaryDataSource);
targetDataSources.put(DataSourceType.STANDBY, standbyDataSource);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(primaryDataSource);
return dynamicDataSource;
}
// 配置事务切面,实现读写分离
@Aspect
@Component
public class DataSourceAspect {
@Before("execution(* com.example.service.*.select*(..)) || execution(* com.example.service.*.get*(..))")
public void setReadDataSourceType() {
DataSourceContextHolder.setDataSourceType(DataSourceType.STANDBY);
}
@Before("execution(* com.example.service.*.insert*(..)) || execution(* com.example.service.*.update*(..)) || execution(* com.example.service.*.delete*(..))")
public void setWriteDataSourceType() {
DataSourceContextHolder.setDataSourceType(DataSourceType.PRIMARY);
}
}.NET应用实现
在.NET应用中,可以使用Oracle Data Provider for .NET (ODP.NET)实现读写分离:
csharp
// 配置主库连接字符串
string primaryConnectionString = "Data Source=primary_db;User Id=scott;Password=tiger;";
// 配置备库连接字符串
string standbyConnectionString = "Data Source=standby_db;User Id=scott;Password=tiger;";
// 写操作使用主库
using (OracleConnection conn = new OracleConnection(primaryConnectionString))
{
conn.Open();
OracleCommand cmd = new OracleCommand("INSERT INTO employees (employee_id, first_name, last_name) VALUES (:id, :first_name, :last_name)", conn);
cmd.Parameters.Add(":id", OracleDbType.Int32).Value = 1001;
cmd.Parameters.Add(":first_name", OracleDbType.Varchar2).Value = "John";
cmd.Parameters.Add(":last_name", OracleDbType.Varchar2).Value = "Doe";
cmd.ExecuteNonQuery();
}
// 读操作使用备库
using (OracleConnection conn = new OracleConnection(standbyConnectionString))
{
conn.Open();
OracleCommand cmd = new OracleCommand("SELECT * FROM employees", conn);
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader["employee_id"] + ", " + reader["first_name"] + ", " + reader["last_name"]);
}
}版本差异
Oracle 19c vs 21c基于GoldenGate的读写分离差异
| 特性 | Oracle 19c | Oracle 21c |
|---|---|---|
| 并行复制 | 支持 | 增强并行复制,提高复制性能 |
| 双向复制 | 支持 | 增强双向复制,减少冲突概率 |
| 异构数据库支持 | 支持 | 增强异构数据库支持,支持更多数据库类型 |
| 自动发现表 | 支持 | 增强自动发现表,支持更多场景 |
| 云集成 | 基础云集成 | 增强云集成,支持与OCI、AWS、Azure等云平台集成 |
| 自动诊断 | 基础自动诊断 | 增强自动诊断和修复能力 |
| 安全功能 | 基础安全功能 | 增强安全功能,支持数据加密和访问控制 |
| 监控能力 | 基础监控能力 | 增强监控能力,提供更详细的性能指标 |
监控与管理
监控GoldenGate读写分离状态
- 查看GoldenGate进程状态
bash
ggsci
INFO ALL
LAG EXTRACT ext1
LAG REPLICAT rep1
STATS EXTRACT ext1
STATS REPLICAT rep1- 监控复制延迟
bash
ggsci
LAG EXTRACT ext1
LAG REPLICAT rep1- 查看复制统计信息
bash
ggsci
STATS EXTRACT ext1, TOTAL
STATS REPLICAT rep1, TOTAL- 监控备库性能
sql
-- 查看备库的等待事件
SELECT EVENT, COUNT(*) FROM V$SESSION_WAIT GROUP BY EVENT ORDER BY COUNT(*) DESC;
-- 查看备库的SQL执行情况
SELECT SQL_ID, PLAN_HASH_VALUE, EXECUTIONS, ELAPSED_TIME/1000000 AS ELAPSED_TIME_SEC FROM V$SQL ORDER BY ELAPSED_TIME DESC;常见管理任务
- 添加新表到复制
bash
ggsci
EDIT PARAMS ext1
# 添加新表到Extract参数文件
TABLE hr.jobs;
EDIT PARAMS dp1
# 添加新表到Data Pump参数文件
TABLE hr.jobs;
EDIT PARAMS rep1
# 添加新表到Replicat参数文件
MAP hr.jobs, TARGET hr.jobs;
# 重新启动进程或刷新参数
ggsci
ALTER EXTRACT ext1, EXTEND TABLE hr.jobs
ALTER EXTRACT dp1, EXTEND TABLE hr.jobs
ALTER REPLICAT rep1, EXTEND MAP hr.jobs, TARGET hr.jobs- 处理复制冲突
查看冲突日志:
bash
cat /u01/app/ogg/dirrpt/rep1.dsc修复冲突数据,然后重新启动Replicat进程:
bash
ggsci
START REPLICAT rep1- 调整复制性能
bash
# 调整Extract进程并行度
ggsci
ALTER EXTRACT ext1, PARALLEL 4
# 调整Replicat进程并行度
ggsci
ALTER REPLICAT rep1, PARALLEL 4最佳实践
性能优化
优化GoldenGate进程参数
- 调整Extract和Replicat进程的并行度
- 配置合适的Trail文件大小
- 使用BATCHSQL参数提高批量处理能力
- 启用压缩选项减少网络传输量
优化网络连接
- 使用高速网络连接,至少10Gbps
- 调整TCP缓冲区大小
- 使用多个Data Pump进程分散网络负载
- 配置合适的网络超时参数
优化备库性能
- 配置足够的内存和CPU资源
- 使用高速存储设备,提高I/O性能
- 优化备库的Oracle参数
- 启用并行查询,提高复杂查询的性能
高可用性
配置Manager进程自动重启
AUTORESTART EXTRACT *, RETRIES 5, WAITMINUTES 3 AUTORESTART REPLICAT *, RETRIES 5, WAITMINUTES 3使用备用Manager进程
- 配置多个Manager进程,确保高可用性
- 使用虚拟IP地址实现Manager进程的故障转移
配置多个备库
- 配置多个备库,实现读写分离的高可用性
- 当一个备库不可用时,自动切换到其他备库
安全管理
使用加密传输
RMTHOST target_host, MGRPORT 7809, ENCRYPT AES256, KEYNAME mykey使用加密Trail文件
EXTTRAIL /u01/app/ogg/dirdat/et, ENCRYPT AES256, KEYNAME mykey限制GoldenGate用户权限
- 遵循最小权限原则,只授予必要的权限
- 定期轮换GoldenGate用户密码
- 使用OS认证或Wallet存储密码
故障处理
常见故障及解决方法
- Extract进程无法启动
症状:GGSMGR日志显示"ERROR OGG-00664: Oracle GoldenGate Capture for Oracle, ext1.prm: Failed to attach to logmining server."
解决方法:
- 检查主库是否启用了补充日志和强制日志记录
- 检查GoldenGate用户是否有足够的权限
- 检查主库的LOG_MINING_SERVER参数配置
- Replicat进程应用失败
症状:GGSMGR日志显示"ERROR OGG-01003: Oracle GoldenGate Delivery for Oracle, rep1.prm: There is a problem in mapping record to target table HR.EMPLOYEES."
解决方法:
- 检查源表和目标表的结构是否一致
- 验证GoldenGate版本与Oracle版本是否兼容
- 检查Trail文件的完整性
- 查看DISCARDFILE获取详细的错误信息
- 复制延迟过大
症状:LAG命令显示Extract或Replicat进程延迟超过阈值
解决方法:
- 检查网络带宽和延迟
- 调整Extract和Replicat进程的并行度
- 优化源库和备库的性能
- 调整Trail文件大小和数量
常见问题(FAQ)
Q: 基于GoldenGate的读写分离有什么优势?
A: 基于GoldenGate的读写分离具有以下优势:
- 支持异构数据库环境,可以实现Oracle与其他数据库之间的读写分离
- 复制延迟极低,通常在毫秒级
- 吞吐量极高,适合高并发场景
- 灵活性高,支持复杂的读写分离策略
- 可以实现双向复制和多级复制
Q: 基于GoldenGate的读写分离适用于哪些场景?
A: 基于GoldenGate的读写分离适用于以下场景:
- 读多写少的业务场景,如电商网站、新闻网站等
- 异构数据库环境,需要在不同数据库之间实现读写分离
- 对复制延迟要求极高的场景
- 需要复杂读写分离策略的场景
- 数据迁移和数据集成场景
Q: 如何处理GoldenGate读写分离中的数据冲突?
A: 可以通过以下方式处理数据冲突:
- 使用冲突检测和解决(CDR)功能
- 配置适当的冲突解决规则
- 定期监控和处理冲突日志
- 优化应用设计,减少冲突概率
- 使用时间戳或序列生成器确保数据一致性
Q: 基于GoldenGate的读写分离支持多少个备库?
A: GoldenGate支持从一个主库复制到多个备库,理论上没有数量限制。实际使用中,备库数量取决于系统资源、网络带宽和业务需求。
Q: 如何验证基于GoldenGate的读写分离的数据一致性?
A: 可以使用以下方法验证数据一致性:
- 使用Oracle Data Compare工具比较主库和备库的数据
- 使用DBMS_COMPARISON包验证主备库数据一致性
- 执行业务查询,比较主库和备库的查询结果
- 定期执行数据校验和计算
- 使用GoldenGate的VERIFY功能验证数据一致性
Q: 基于GoldenGate的读写分离与基于Data Guard的读写分离有什么区别?
A: 基于GoldenGate的读写分离与基于Data Guard的读写分离的主要区别:
- 技术原理:GoldenGate基于逻辑复制,Data Guard基于物理复制
- 延迟:GoldenGate的延迟极低,Data Guard的延迟较低
- 异构支持:GoldenGate支持异构数据库,Data Guard只支持Oracle数据库
- 配置复杂度:GoldenGate的配置相对复杂,Data Guard的配置相对简单
- 灵活性:GoldenGate的灵活性更高,支持更复杂的读写分离场景
总结
基于GoldenGate的读写分离是一种高效、灵活的数据复制解决方案,支持异构数据库环境,提供低延迟、高吞吐量的数据复制功能。在配置基于GoldenGate的读写分离时,需要根据业务需求选择合适的复制模式和配置参数,并定期监控和管理GoldenGate进程,确保其正常运行。Oracle 21c相比19c在GoldenGate方面有显著增强,包括增强的并行复制、双向复制和云集成等功能。
