1. 概述
1.1 版本
FineDataLink 版本 | 功能变动 |
---|---|
- | - |
4.1.2 | 支持多租户架构作为管道任务数据来源端 |
CDC(Change Data Capture),即数据变更抓取,通过为源端数据源开启 CDC,FineDataLink 数据管道可实现数据源的实时数据同步以及数据表的物理删除同步。
FineDataLink 数据管道支持 Oracle 的 XStream 和 LogMiner 两种 CDC 模式,本章节主要介绍如何为 Oracle 数据库开启 LogMiner 模式的CDC功能。另外,根据Oracle数据库类型为CDB数据库还是非 CDB 数据库,CDC 的配置有所不同。
执行同步任务前,需要参考本文在数据源中进行一些配置,为后续的数据同步做好准备。
注:归档日志会占用较多的磁盘空间,若磁盘空间满了会影响业务,请定期清理过期归档日志,详情参见:清理Oracle归档日志
2. 确认当前使用的数据库版本
确认是否为数据管道同步任务所支持的版本。
数据管道支持读取的 Oracle 数据库版本如下表所示:
数据库类型 | 支持数据库版本 |
---|---|
Oracle | Oracle 10g、11g、12c、18c、19c、Oracle RAC集群 |
以具有 DBA 权限的用户身份登录数据库
例如 Windows 系统中安装的 Oracle,命令提示符中输入:sqlplus / as sysdba 进入数据库操作界面。
同时可以查看到当前数据库的版本,如下图所示:
3. 数据来源为 CDB
3.1 开启 Archive Log
1)以具有 DBA 权限的用户身份登录数据库2)使用命令查看数据库的 logging mode :
select log_mode from v$database;
如果返回的结果是 ARCHIVELOG , 可以直接操作 3.3 节进行操作。
如果返回的结果是 NOARCHIVELOG , 继续按照以下步骤操作:
登录服务端:sqlplus / as sysdba
关闭数据库: 使用命令:shutdown immediate;
启动并挂载数据库: startup mount;
开启存档并打开数据库:
alter database archivelog;
alter database open;
3.2 开启 Supplemental Log
3.2.1 Oracle 10g、11g版本开启方式
使用如下命令开全库补全日志:
alter database add supplemental log data;
alter system switch logfile;
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
3.2.2 Oracle 12c、18c、19c、RAC集群版本的特殊配置方法
使用以下命令,确认 supplemental logging 是否开启:
SELECT supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_all FROM v$database;
如果返回的三列都是 Yes 或者 Implicit ,则表示 identification key logging(标识键日志)和 full supplemental logging(全补充日志)已同时开启,可以直接查看 3.4 节数据库账号相关内容。
如果返回的前两列是 Yes 或者 Implicit ,则表示只开启了 identification key logging(标识键日志),需要参考 3.3 节开启全补充日志。
3.2.3 Oracle 12c、18c、19c、RAC集群的 CDB 开启方式
为单个表开启 identification key logging(标识键日志):
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER TABLE <schema name>.<table name> ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
对所有表开启 identification key logging(标识键日志):
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
3.3 开启 full supplemental logging(全补充日志)
单表开启 full supplemental logging(全补充日志),使用如下命令:
ALTER TABLE <schema name>.<table name> ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
所有表开启 full supplemental logging(全补充日志),使用如下命令:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
提交更改的配置:
ALTER SYSTEM SWITCH LOGFILE;
然后可以使用命令查看单表的补全日志权限是否开启:
SELECT OWNER, TABLE_NAME, LOG_GROUP_NAME, ALWAYS, LOGGING_COLUMNS
FROM DBA_LOG_GROUPS
WHERE TABLE_NAME = '你的表名';
3.4 分配数据库账号权限
需要规划一个可访问数据源的账号,用于后续数据管道过程中访问数据源并进行数据提取、写入的同步操作。
创建账号操作详情请参见: 创建 Oracle 账号
3.4.1 Oracle 10g、11g版本
使用如下命令创建用户帐户并分配权限:
CREATE USER <user name> IDENTIFIED BY <password>;
GRANT create session, alter session, execute_catalog_role, select any dictionary, select any transaction, select any table, unlimited tablespace to <user name>;
此时即可在进行数据连接时使用该用户账号,例如上述使用的是Roxy,则数据连接如下图所示:
3.4.2 Oracle 12c、18c、19c standard databases 版本
在Oracle 12c、19c标准模式下,创建一个用户所必须的权限。
1)以具有 DBA 权限的用户身份登录数据库
2)创建普通用户:
CREATE USER <user name> IDENTIFIED BY <password>;
GRANT create session, alter session, select any dictionary, select any transaction,select any table,logmining, execute_catalog_role TO <username>;
根据对表的权限需求,重复执行最后一个命令来赋予 select 权限。
3.5 检查用户权限
注:Oracle 11g 及以下版本不需要 LOGMINING 权限
输入以下命令检查判断当前用户是否有 LOGMINER 权限。
WITH required_sys_privileges AS (
SELECT column_value AS PRIVILEGE
FROM TABLE (
sys.odcivarchar2list(
'SELECT ANY TRANSACTION',
'CREATE SESSION',
'SELECT ANY DICTIONARY',
'SELECT ANY TABLE',
'FLASHBACK ANY TABLE',
'LOGMINING'
)
)
),
required_role_privileges AS (
SELECT column_value AS ROLE_NAME
FROM TABLE (
sys.odcivarchar2list(
'EXECUTE_CATALOG_ROLE',
'RESOURCE'
)
)
),
required_table_privileges AS (
SELECT column_value AS PRIVILEGE
FROM TABLE (
sys.odcivarchar2list(
'DBMS_FLASHBACK',
'DBMS_LOGMNR',
'DBMS_LOGMNR_D'
)
)
)
SELECT r.PRIVILEGE,
NVL2(p.USERNAME, 'OK', 'REQUIRED') AS PRIVILEGE_STATUS
FROM required_sys_privileges r
LEFT JOIN user_sys_privs p
ON r.PRIVILEGE = p.PRIVILEGE
UNION
SELECT r.ROLE_NAME,
NVL2(p.USERNAME, 'OK', 'REQUIRED') AS PRIVILEGE_STATUS
FROM required_role_privileges r
LEFT JOIN user_role_privs p
ON r.ROLE_NAME = p.GRANTED_ROLE
UNION
SELECT r.PRIVILEGE,
NVL2(p.GRANTEE, 'OK', 'REQUIRED') AS PRIVILEGE_STATUS
FROM required_table_privileges r
LEFT JOIN user_tab_privs p
ON r.PRIVILEGE = p.TABLE_NAME;
对于返回结果,若显示为 Required 则是未开启 logminer 权限,显示为 OK 则是有权限。
对于缺乏的权限,需要进行开启。
4. 数据来源为 PDB
如果数据来源为 PDB ,则无法直接读取数据库的 redolog ,需要借助 CDB 来读取。
4.1 查询该数据库是否开启多租户
1)以具有 DBA 权限的用户身份登录数据库,使用如下命令查看数据库是否开启多租户:
SELECT CDB FROM V$DATABASE;
4.2 判断当前是否为根容器下
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;
4.3 开启数据库权限
参考本文 3.1、3.2、3.3 节开启数据库日志权限。
4.4 判断连接用户是否为 Common User 以及是否拥有 Set Container 权限
4.4.1 启动所有的 PDB
在 sqlplus 下使用命令查看当前 PDB 状态,如下图所示:
show pdbs;
或者也可以在数据库查询界面使用命令
SELECT name, open_mode
FROM v$pdbs
ORDER BY name;
2)此时可以看出 PDBORCL 和 ORCLPDB 均未启动,此时需要将其开启。
使用如下命令:
注: PDB 名称需要根据数据库实际情况修改。
ALTER PLUGGABLE DATABASE ORCLPDB1 OPEN;
ALTER PLUGGABLE DATABASE PDBORCL OPEN;
然后再次查看PDB 状态,PDB 均开启:
4.4.2 创建账号
注:在 CDB 中创建公共用户, PDBS 中也会创建相同用户。若 CDB 下 GRANT 命令赋权时未指定container=all,则赋权只在 CDB 中生效,并不会在 PDB 中生效,这个用户要能够访问PDB,需要切换到 PDB 再赋权。若赋权时指定 container=all,则赋权在 CDB 中生效,也在 PDB 中生效。
1)创建用户账号
CREATE USER "C##ROXY122" IDENTIFIED BY 123 CONTAINER=all;
注1:用户名和密码此处分别为 C##ROXY122 和 123,用户可根据实际情况修改。
注2:当 Oracle 处于多租户模式下时,用户名需增加 C## 前缀。
2)授予权限
GRANT create session, alter session, select any dictionary, select any transaction,select any table,logmining, execute_catalog_role,set container TO "C##ROXY122" container=all;
此处仅为新增账号的授权操作,数据库权限需要参考本文 4.3 节开启:
ALTER USER "C##ROXY122" QUOTA UNLIMITED ON "USERS";
SELECT supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_all FROM v$database;
GRANT create session, alter session, select any dictionary, select any transaction,select any table,logmining, execute_catalog_role TO "C##ROXY122";
最后授予用户 V_$PDBS 的权限,如下图所示:
alter user "C##ROXY122" set container_data=all for sys.v_$pdbs container = current;
此时再查询这个新增账号的权限:
SELECT USERNAME, OBJECT_NAME FROM CDB_CONTAINER_DATA WHERE USERNAME = 'C##KAMA' AND OBJECT_NAME = 'V_$PDBS';
可以查到对应的 v$pdbs 权限,如下图所示:
远程 Oracle 所在服务器并切换到 sqlplus 模式下,执行赋予权限命令:
grant restricted session TO "C##ROXY122" container=all;
然后执行命令,赋予建表权限:
GRANT CREATE TABLE TO <username> CONTAINER=ALL;
执行后查询是否还有建表权限:
SELECT PRIVILEGE FROM USER_SYS_PRIVS WHERE PRIVILEGE = 'CREATE TABLE';
此时可以正常建表。