Oracle GoldenGate Oracle—Oracle 双向复制

本文深入探讨了Oracle GoldenGate的两种双向复制配置模式:Active-Passive与Active-Active,详细解释了它们的部署、主备切换流程、负载均衡与高可用性实现,以及在Active-Active模式下可能出现的冲突问题与解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle GoldenGate支持两种双向复制配置,一种是active-passive模式,这种模式一般被用来实现live standby,做主备库,还有一种是active-active模式,这种模式被用来实现HA高可用、分摊负载压力。
Active-passive for a live standby
首先先介绍一下active-passive模式的部署以及主备库的切换。配置active-passive模式的目的是为了主库因计划和非计划的中断后可以失败转移到一个完整复制主库数据的备份数据库上,业务架构如下:

 

在这种配置中,备库拥有一个不活动的Extract group和一个data pump。这些进程组在用户应用因switchover或failover切换到这个live standby系统前都应保持stopped状态。当用户活动切换到standby时,这些进程组开始捕获事务并将其写入到本地的trail中,这些数据存储在磁盘上直到主库恢复使用。
在主库失败的案例中,Oracle GoldenGate的Manager和Replicat进程与一个数据库协同工作,在主系统恢复后从备库将数据恢复到主库,使两个系统相等。在适当的时候,将用户移回主系统,Oracle GoldenGate再一次被配置为准备模式,以准备将来的failover。
配置一个live standby需要考虑以下问题:
Duplicate standby
在大多数的live standby的实现中,备库与主库的内容和结构应该是相同的,data mapping、conversion和filtering在这种配置中是不合适的,但是如果你的业务模型要求的话,Oracle GoldenGate也是支持这些功能的,使用MAP和TABLE参数选项可以实现这些功能。
备用系统上的DML操作
如果你的应用允许,你可以将live standby用作保镖和查询,但是不要有DML操作。如果在live standby系统上会有活动的事务应用影响对象的话,你应该把它配置为active-active模式。
Oracle GoldenGate processes
在普通的操作模式下,你应该让live standby上的primary extract进程和data pump保持stopped状态,让active source上的replicat进程保持stopped状态。这防止了任何偶尔发生在备用系统上的DML操作被传播到active source。只有将数据从active source传送到standby的Extract进程、data pump进程和replicat进程是被激活的。
备份文件
定期备份主系统和备用系统的Oracle GoldenGate工作目录。这个备份必须包含Oracle GodenGate安装目录下的所有文件以及所有的子目录。有了这个Oracle GoldenGate环境的备份意味着你不需要再去重建进程组和参数文件。
为Failover做好准备
请确保在一个计划的switchover或者非计划的source failure事件中主备系统能够立即访问。以下的一些高可用计划的组件应便于每台系统可供使用:

赋予insert、update和delete权限的脚本
启用live standby上trigger和cascaded delete的脚本
切换应用服务、启动应用和复制不在复制环境中复制的必要的文件的脚本
一个当source系统发生故障后移动用户到备用系统的故障转移过程

由数据库生成的序列值
如果由数据库生成的值作为键值的一部分,那么这个值在每台系统上的范围必须为不同以使其没有机会重叠。如果应用允许,你也可以为这个值添加一个本地标识以强制其唯一。
对于Oracle数据库,你可以通过配置Oracle GoldenGate使其复制sequence来确保其在每个系统上唯一。使用SEQUENCE和MAP参数来复制SEQUENCE。
 
Oracle GoldenGate配置live standby的原理架构图:

配置active-passive模式其实就是在原先单向复制的基础上在target端创建一个extract和data pump指向source,而在source上创建一个replicat执行target传过来的trail的应用,只是这些进程组不启动而已。配置单向复制的方法请参照我的另一篇文章Goldengate Oracle–Oracle 单向复制Change Synchronization安装部署,要注意的是source端由于要复制,所以也同样需要创建checkpointtable,而target端由于要作为今后的source端进行挖掘,所以它也需要启用DDL支持,但是ddl_enable.sql和ddl_pin.sql不需要执行,而在切换为source时再执行,因为作为target端目前还不需要捕获ddl操作,source创建checkpointtable和target启用ddl支持需要在配置初期完成,不能待完成单向复制配置后再回过头来在source端创建checkpointtable,因为有DDL复制,所以在source创建checkpointtable后会传播到target,而target已存在相同的表,这会导致复制报错,replicat会abend,如果使用不同的表名则不会报错,当然也可以在replicat用ddlerror 955 ignore参数来处理忽略这个错误,955是error号,ignore表示忽略它。

Switchover–
在配置完active-passive模式后我们尝试进行switchover,目前source端与target端的OGG下的进程状态如下:
source端

ogg@gc ogg]$ ggsci

Oracle GoldenGate Command Interpreter for Oracle
Version 11.2.1.0.14 17547423 OGGCORE_11.2.1.0.0OGGBP_PLATFORMS_131022.0605_FBO
Linux, x64, 64bit (optimized), Oracle 11g on Oct 22 2013 11:03:39

Copyright (C) 1995, 2013, Oracle and/or its affiliates. All rights reserved.

GGSCI (gc.yxd.com) 1> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:05 00:00:00
EXTRACT RUNNING PUMP1 00:00:00 00:00:05
REPLICAT STOPPED REP1 00:00:00 00:04:38

target端

[ogg@gc2 ogg]$ ggsci

Oracle GoldenGate Command Interpreter for Oracle
Version 11.2.1.0.14 17547423 OGGCORE_11.2.1.0.0OGGBP_PLATFORMS_131022.0605_FBO
Linux, x64, 64bit (optimized), Oracle 11g on Oct 22 2013 11:03:39

Copyright (C) 1995, 2013, Oracle and/or its affiliates. All rights reserved.

GGSCI (gc2.yxd.com) 1> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT STOPPED EXT1 00:00:00 00:19:31
EXTRACT STOPPED PUMP1 00:00:00 00:07:13
REPLICAT RUNNING REP1 00:00:00 00:00:05

1. source端停止用户应用,但是保持extract与data pump运行以捕获积压的数据。
2. source端发布lag extract ext1确保捕获完成。

GGSCI (gc.yxd.com) 2> lag extract ext1

Sending GETLAG request to EXTRACT EXT1 …
Last record lag: 8 seconds.

3. source停止extract

GGSCI (gc.yxd.com) 7> stop extract ext1

Sending STOP request to EXTRACT EXT1 …
Request processed.

GGSCI (gc.yxd.com) 8> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT STOPPED EXT1 00:00:05 00:00:08
EXTRACT RUNNING PUMP1 00:00:00 00:00:09
REPLICAT STOPPED REP1 00:00:00 00:10:51

4. source禁用trigger和cascaded delete(如果有的话),收回用户的insert、update和delete权限

[oracle@gc ~]$ cd /ogg/
[oracle@gc ogg]$ sqlplus ogg/000000 as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Fri Nov 29 15:44:01 2013

Copyright (c) 1982, 2013, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @ddl_disable.sql

Trigger altered.

SQL> revoke resource from yxd;

Revoke succeeded.

5. source端发布lag extract pump1,直到出现“At EOF, no more records to process.”表明捕获的数据都已经发送到target了。

GGSCI (gc.yxd.com) 9> lag extract pump1

Sending GETLAG request to EXTRACT PUMP1 …
Last record lag: 8 seconds.
At EOF, no more records to process.

6. source端停止pump1

GGSCI (gc.yxd.com) 10> stop pump1

Sending STOP request to EXTRACT PUMP1 …
Request processed.

GGSCI (gc.yxd.com) 11> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT STOPPED EXT1 00:00:05 00:04:11
EXTRACT STOPPED PUMP1 00:00:00 00:00:03
REPLICAT STOPPED REP1 00:00:00 00:14:54

7. target发布lage replicat rep1,直到出现“At EOF, no more records to process.”表明数据都已被应用

GGSCI (gc2.yxd.com) 3> lag replicat rep1

Sending GETLAG request to REPLICAT REP1 …
Last record lag: 10 seconds.
At EOF, no more records to process.

8. target停止replicat

GGSCI (gc2.yxd.com) 4> stop rep1

Sending STOP request to REPLICAT REP1 …
Request processed.

GGSCI (gc2.yxd.com) 5> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT STOPPED EXT1 00:00:00 00:34:16
EXTRACT STOPPED PUMP1 00:00:00 00:21:58
REPLICAT STOPPED REP1 00:00:00 00:00:03

9. target端运行赋予用户insert、update、delete权限的脚本,启用trigger和cascaded delete的脚本。

[oracle@gc2 ogg]$ sqlplus ogg/000000 as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Fri Nov 29 15:46:48 2013

Copyright (c) 1982, 2013, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @ddl_enable.sql

Trigger altered.

SQL> @ddl_pin.sql ogg

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

SSQL> grant resource to yxd;

Grant succeeded.

10. 拷贝不在复制环境中复制的文件到target live standby
11. 修改target的extract ext1为begin now,让他从现在这个时间点开始挖据

GGSCI (gc2.yxd.com) 6> alter extract ext1,begin now
EXTRACT altered.

12. 启动target的extract ext1

GGSCI (gc2.yxd.com) 7> start ext1

Sending START request to MANAGER …
EXTRACT EXT1 starting

GGSCI (gc2.yxd.com) 8> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:10 00:00:08
EXTRACT STOPPED PUMP1 00:00:00 00:37:07
REPLICAT STOPPED REP1 00:00:00 00:15:12

13. 启动target的extract pump1

GGSCI (gc2.yxd.com) 12> start pump1

Sending START request to MANAGER …
EXTRACT PUMP1 starting

GGSCI (gc2.yxd.com) 13> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:03 00:00:02
EXTRACT RUNNING PUMP1 00:00:00 00:39:01
REPLICAT STOPPED REP1 00:00:00 00:17:06

GGSCI (gc2.yxd.com) 14> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:03 00:00:05
EXTRACT RUNNING PUMP1 00:00:00 00:39:04
REPLICAT STOPPED REP1 00:00:00 00:17:09

GGSCI (gc2.yxd.com) 15> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:03 00:00:07
EXTRACT RUNNING PUMP1 00:00:00 00:39:06
REPLICAT STOPPED REP1 00:00:00 00:17:11

GGSCI (gc2.yxd.com) 16> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT RUNNING EXT1 00:00:03 00:00:09
EXTRACT RUNNING PUMP1 00:00:00 00:00:00
REPLICAT STOPPED REP1 00:00:00 00:17:13

14. source端启动replicat rep1开始复制

GGSCI (gc.yxd.com) 14> start rep1

Sending START request to MANAGER …
REPLICAT REP1 starting

GGSCI (gc.yxd.com) 15> info all

Program Status Group Lag at Chkpt Time Since Chkpt

MANAGER RUNNING
EXTRACT STOPPED EXT1 00:00:05 00:28:55
EXTRACT STOPPED PUMP1 00:00:00 00:24:47
REPLICAT RUNNING REP1 00:00:00 00:00:02

15. 切换应用服务,启动应用,移动用户到target端,切换完成。
16. 测试target端同步数据到source
target端建立表、插入数据、使用sequence

[oracle@gc2 ogg]$ cd
[oracle@gc2 ~]$ sqlplus yxd/000000

SQL*Plus: Release 11.2.0.4.0 Production on Fri Nov 29 16:02:12 2013

Copyright (c) 1982, 2013, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create table oo (id number,name varchar2(20));

Table created.

SQL> insert into oo values(33,'sdfsdf');

1 row created.

SQL> /

1 row created.

SQL> /

1 row created.

SQL> /

1 row created.

SQL> /

1 row created.

SQL> commit;

Commit complete.

SQL> select * from oo;

        ID NAME
———- —————————————-
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf

SQL> select * from tab;

TNAME TABTYPE
———————————————————— ————–
 CLUSTERID
———-
II TABLE

KK TABLE

OO TABLE

TNAME TABTYPE
———————————————————— ————–
 CLUSTERID
———-
TT TABLE

XX TABLE

SQL> select seq.nextval from dual;

   NEXTVAL
———-
        15

SQL> /

   NEXTVAL
———-
        16

SQL> /

   NEXTVAL
———-
        17

SQL> /

   NEXTVAL
———-
        18

SQL> select last_number from user_sequences;

LAST_NUMBER
———–
         19

查看source端是否数据同步

[oracle@gc ogg]$ sqlplus yxd/000000

SQL*Plus: Release 11.2.0.4.0 Production on Fri Nov 29 16:05:30 2013

Copyright (c) 1982, 2013, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select * from oo;

        ID NAME
———- —————————————-
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf
        33 sdfsdf

SQL> select * from tab;

TNAME TABTYPE
———————————————————— ————–
 CLUSTERID
———-
II TABLE

KK TABLE

OO TABLE

TNAME TABTYPE
———————————————————— ————–
 CLUSTERID
———-
TT TABLE

XX TABLE

SQL> select last_number from user_sequences;

LAST_NUMBER
———–
         19

数据完全一致,同步成功,要切换回去使用相同的步骤即可。
 
Failover–
Failover由于source失败已经不可用,所以对与source的步骤也就没有了,使用switchover中的步骤7-13以及步骤15即可完成failover。
 
Active-Active for high availability
Active-Active模式通常用来解决一些分摊负载提高高可用性的需求,这种配置在两个系统上拥有相同的数据集,并且应用用户可以在任意一台机器上进行数据更改。Oracle GoldenGate复制每一台的事务数据变化到其他的节点来保持所有的数据集一致。
在这种双向配置中,在每一台系统上都有一个完整的激活的Oracle GoldenGate进程组集合。在一台系统上由Extract进程捕获的数据会传播到其他系统上用作Replicat的复制应用。
这种配置可以支持负载共享,它可以用作容灾如果每个节点的业务应用是一致的话。双向同步支持所有Oracle GoldenGate所支持的数据库类型。
Active-Active同步的实现原理与架构图:

从架构上可以看出Active-Active模式与Active-Passive模式的区别只在于在两个系统上的所有的extract、data pump和replicat进程都是激活的,所以它在架设上与Active-Passive相似,无非是将所有的进程都开启而已,具体的配置不再过多讨论。由于两边都可以修改数据库,所以必定会有一些冲突的问题产生,下面着重了解一下可能产生的冲突与解决方法。
TRUNCATES–
在这个配置中TRUNCATE的复制是不支持的,但是你可以配置这些操作总是向一个方向复制,而数据是双向复制的。在Active-Active配置中,TRUNCATE必须只能从一个源数据库发起,并且每次都只能是同一个数据库。
你需要按照以下来配置环境:

配置所有的数据库角色无法执行TRUNCATE操作,除了那台用作TRUNCATE源的数据库。
在允许TRUNCATE的系统上,配置Extract和Replicat参数文件去包含GETTRUNCATES参数。
在其他系统上,配置Extract和Replicat参数文件去包含IGNORETRUNCATES参数。作为Oracle GoldenGate配置的一部分,在这些系统上的应用不应该执行TRUNCATE操作。

DDL–
在Active-Active配置中,DDL的复制是支持的。
 
应用的设计–
Active-Active配置不建议使用商业化可用的已打包了的业务应用,除非这些应用是为Active-Active配置设计的。这些应用可能会出现以下障碍:

已打包的应用可能会包含Oracle GoldenGate不支持的对象和数据类型。
这些应用可能会自动执行一些你不能控制的DML操作,当这些操作被复制给Replicat应用时可能会导致冲突。
你可能无法控制数据结构修改它以达到Active-Active复制的要求。

键–
为了准确的侦测冲突,所有的记录应该有一个唯一的、非空的标识。如果可能,创建一个主键,如果不可能就创建一个唯一键或者使用MAP和TABLE参数中的KELCOL选项来创建一个替代键。如果缺失了这个唯一键,那么Oracle GoldenGate将使用WHERE子句中所有有效的字段,但是这会降低性能如果这个表包含很多字段的话。
为了维护数据的完整性和防止error发生,你使用的所有给出的表的键必须要满足以下条件:

在所有驻留的数据库中这张表必须包含相同的字段。
在所有数据库中每个相应行的集合的值必须相同。

Triggers and cascaded deletes–
由Trigger和ON DELETE CASCADE约束产生的DML操作是能够被复制的。为了防止本地的DML与由这些操作复制的DML冲突,你需要做以下事:

修改Trigger,忽略由复制应用的DML操作。对于某些Oracle数据库版本,你可以使用DBOPTIONS参数的SUPPRESSTRIGGERS选项来禁止复制会话的trigger。
禁用ON DELETE CASCADE约束而使用父表上的trigger去执行删除子表数据的要求。创建一个BEFORE trigger用来在父表执行删除前删除子表。这反转了级联删除的逻辑规则,但是对于避免在target端由复制操作而产生“table not found”错误是很有必要的。

Database-generated values–
在active-active的双向复制中不要复制数据库生成的序列值,在active-passive模式中我们是通过复制sequence来实现序列一致的,这样在切换后序列值能够延续下去,但是双向复制是需要同时操作数据的,所以sequence是不能复制的,否则会引起冲突。我们需要让序列在每个系统上的取值范围必须是不同的以使他们不会重叠。例如:在两个数据库的环境中,你可以在一台系统上生成奇数值而另一个系统生成偶数值。对于一个多数据库的环境,每一个key的起始值是不同的,增长的步长是系统个数,比如4个数据库的环境,那么每个数据库上的起始值分别是1、2、3、4,步长为数据库的总数4,那么他们就没有重叠的机会。由于没有了重叠的机会,也不需要保持一致,所以此时的sequence是可以被cache的。但是这种方法可能并不是对所有类型的应用或数据库有效。如果应用允许,你可以添加一个本地标识使其强制唯一。

冲突处理–
所有的系统上必须统一冲突处理规则用来处理当在分离的系统上的相同的数据集同时(或者几乎同时)发生修改时的冲突。在active-active环境中,冲突应该立即被标识并且尽可能自动的被处理,然而,不同的业务应用在这个领域会有他们自己的独特的要求。Oracle GoldenGate对于insert、update和delete冲突提供内建的冲突处理支持。
防止数据环回–
在active-active双向复制中,从一台系统复制到另一台系统的SQL改变必须防止被复制回第一台系统。否则,它会向前向后移动无限循环,例如:
1. 一个用户应用在A系统上update了一行数据。
2. Extract从系统A提取这行数据然后发送到系统B。
3. Replicat在系统B上更新了这行数据。
4. 在系统B上的Extract提取了这行数据发送回系统A。
5. 这行数据第二次在系统A上被应用。
6. 这个会无限循环下去。
为了防止数据环回,你也许需要提供以下指令:

防止捕获由Replicat进程产生的SQL操作,但是捕获包含了在Extract参数文件中指定的对象的由业务应用生成的SQL操作。
标识本地Replicat事务,使Extract进程可以忽略它们。

防止捕获Replicat操作–
依赖你使用的数据库,你也许需要也许不需要提供明确的指令来防止Replicat操作的捕获。
Teradata数据库–
对于Teradata数据库防止捕获Replicat应用的SQL需要设置Replicat会话重写复制。在根的Replicat的参数文件中使用以下SQLEXEC:

SQLEXEC "SET SESSION OVERRIDE REPLICATION ON;"
SQLEXEC "COMMIT;"

这些SQLEXEC语句会在启动时执行以自动设置Replicat会话。
其他数据库–
其他数据库使用以下参数防止不会Replicat产生的SQL操作:

GETAPPLOPS|IGNOREAPPLOPS:控制除去Extract进程写到一个指定Trail或文件中Replicat包含的内容外是否还包含了业务应用的数据操作。
GETREPLICATES|IGNOREREPLICATES:控制是否包含了Replicat产生的DML操作内容到Extract进程所写的那个Trail或文件中。

在启动Extract进程前,要确保这些参数要么不写,要么就设置GETAPPLOPS和IGNOREREPLICATES。
 
标识Replicat事务–
配置Extract去识别Replicat事务,究竟哪些数据会被捕获可以用以下指令:
DB2 on z/OS and LUW,在Extract参数文件中使用以下参数来标识复制用户名:

TRANLOGOPTIONS EXCLUDEUSER <user name>

这个参数语句标记了所有由这个用户座位复制事务产生的数据事务。这个用户包含在事务记录中由Extract读取。
 
MySQL和NonStop SQL/MX,在Extract参数文件中用以下参数语句来标识Replicat checkpoint table的名字:

TRANLOGOPTIONS FILTERTABLE <table_name>

在每个事务的终点,Replicat写一个checkpoint到checkpoint表座位它的checkpoint过程的一部分(这个表就是用ADD CHECKPOINTTABLE命令创建的那个)。因为每一个复制事务要写这张表,它能够在active-active双向复制中用来识别复制事务。FILTERTABLE标识了checkpoint table的名字,以至于Extract能够忽略这张表上的任何操作。
 
Oracle数据库使用以下的一种语句来标识Replicat用户。所有的由这个用户生成的事务将被捕获忽略。在事务记录中的这些信息对Extract是有效地。

在Extract参数文件中使用以下参数通过名称来标识Replicat数据库用户:

TRANLOGOPTIONS EXCLUDEUSER <user name>

在Extract参数文件中使用Oracle user-id(uid)在以下参数语句中来标识Replicat数据库用户:

TRANLOGOPTIONS EXCLUDEUSERID <user-id>

 
Sqlserver中通过使用以下Extract参数文件中的参数语句来标识Replicat事务名:

TRANLOGOPTIONS EXCLUDETRANS <transaction name>

这个参数语句只在Replicat事务名被定义为其他的名称而不是默认的ggs_repl才被要求。
 
Sybase使用以下任意一种方式:

在Extract参数文件中使用以下参数语句来标识一个Replicat事务名:

TRANLOGOPTIONS EXCLUDETRANS <transaction name>

在Extract参数文件中使用以下参数语句来标识一个Replicat用户名:

TRANLOGOPTIONS EXCLUDEUSER <user name>

EXCLUDEUSER标记了所有由这个复制事务用户生成的事务。这个用户名包含在事务记录中由Extract来读取。

什么都不做,并允许Replicat使用默认的事务名ggs_repl。

Teradata,你不需要去标识应用到一个teradata数据库的复制事务。

原文链接:http://www.knowwinter.com/2013/12/03/oracle-goldengate-oracle-mdash-oracle-shuang-xiang-fu-zhi/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值