前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >实现并发新高度:23ai的无锁列值保留

实现并发新高度:23ai的无锁列值保留

作者头像
Alfred Zhao
发布于 2024-06-14 00:08:49
发布于 2024-06-14 00:08:49
19600
代码可运行
举报
运行总次数:0
代码可运行

Oracle Database 23ai支持Lock-Free Reservation,中文通常译为“无锁列值保留”。

本文将通过3个部分来阐述Lock-Free Reservation的这个特性:

  • 1.应用场景
  • 2.实现原理
  • 3.使用限制

1.应用场景

Lock-Free Reservation这项特性可用于实现更细粒度的并发控制。 它的本质是相对于传统的行锁,能以更细的粒度(即列值级别)进行锁定,从而减少锁争用,提高并发性能。

例如,当库存充足时,数据仅在提交时锁定,并有可能改善最终用户体验以及事务的吞吐量。

为了避免重复造轮子,本文演示的测试用例部分,直接参考了官方博客中给出的测试用例,原文链接为:

下面我们就依据此测试用例来测试并理解下Lock-Free Reservation的具体功效吧。

1.1 创建测试表

首先,创建测试表inventory:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create table inventory
( item_id            NUMBER          CONSTRAINT inv_pk PRIMARY KEY,
  item_display_name  VARCHAR2(100)   NOT NULL,
  item_desc          VARCHAR2(2000),
  qty_on_hand        NUMBER          RESERVABLE CONSTRAINT qty_ck CHECK (qty_on_hand >= 0) NOT NULL,
  shelf_capacity     NUMBER          NOT NULL,
    CONSTRAINT shelf_ck CHECK (qty_on_hand <= shelf_capacity)
);

在开始下一步前,我们先解读下这张测试表的创建语句,以便后面测试能更好的理解:

  • CHECK (qty_on_hand >= 0) 这个约束确保了库存数量不能为负数。
  • shelf_capacity,这是货架容量,表示每种物品在货架上的最大存放量。
  • CONSTRAINT shelf_ck CHECK (qty_on_hand <= shelf_capacity),这个约束确保 qty_on_hand(当前库存数量)不能超过 shelf_capacity(货架容量)。

1.2 查看测试表信息

这里测试表的RESERVABLE属性列,还可以通过如下SQL来查看,确认表中是否存在RESERVABLE属性的列,以及确定具体是哪一列:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
col table_name format a30
col has_reservable_column format a30
col reservable_column format a30

select table_name, has_reservable_column
from user_tables
where table_name = 'INVENTORY';

select column_name, reservable_column
from user_tab_cols
where table_name = 'INVENTORY' and reservable_column = 'YES';

查看表中约束信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
col search_condition format a40
col constraint_name format a20
select constraint_name, search_condition
from user_constraints 
where table_name='INVENTORY';

上面查询结果就是我们创建的表的基础信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
07:35:47 PRIMARY @ORCL -> JINGYU @PDB1>
TABLE_NAME		       HAS_RESERVABLE_COLUMN
------------------------------ ------------------------------
INVENTORY		       YES

COLUMN_NAME		       RESERVABLE_COLUMN
------------------------------ ------------------------------
QTY_ON_HAND		       YES

CONSTRAINT_NAME      SEARCH_CONDITION
-------------------- ----------------------------------------
SYS_C008423	     "ITEM_DISPLAY_NAME" IS NOT NULL
SYS_C008424	     "QTY_ON_HAND" IS NOT NULL
SYS_C008425	     "SHELF_CAPACITY" IS NOT NULL
QTY_CK		     qty_on_hand >= 0
SHELF_CK	     qty_on_hand <= shelf_capacity
INV_PK

1.3 插入测试数据

在测试表中插入3条测试数据,并提交更改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
insert into inventory values (123, 'Milk', 'Lowfat 2%', 100, 120);
insert into inventory values (456, 'Bread', 'Multigrain', 50, 100);
insert into inventory values (789, 'Eggs', 'Organic', 50, 75);
commit;

2.实现原理

首先设计测试场景,然后从测试表现理解实现原理。

2.1 测试无锁列值保留

目前测试表中数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
07:37:39 PRIMARY @ORCL -> JINGYU @PDB1> select ITEM_ID, QTY_ON_HAND, SHELF_CAPACITY from inventory;

   ITEM_ID QTY_ON_HAND SHELF_CAPACITY
---------- ----------- --------------
       123	   100		  120
       456	    50		  100
       789	    50		   75

Elapsed: 00:00:00.00
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--更新item_id=123的qty_on_hand列,原值减10 @session1:
update inventory
     set qty_on_hand = qty_on_hand - 10
     where item_id = 123;
     
--更新item_id=123的qty_on_hand列,原值减2 @session2:
update inventory
     set qty_on_hand = qty_on_hand - 2
     where item_id = 123;

--更新item_id=123的qty_on_hand列,原值减9 @session3:     
update inventory
     set qty_on_hand = qty_on_hand - 9
     where item_id = 123;
   
--更新item_id=123的qty_on_hand列,原值加20 @session4:  
update inventory
     set qty_on_hand = qty_on_hand + 20
     where item_id = 123;

传统情况下,不同会话同时更新表的同一行数据,会阻塞,但这里上面4个会话都可以正常执行成功。 结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--@session1:
07:38:03 PRIMARY @ORCL -> JINGYU @PDB1> update inventory
     set qty_on_hand = qty_on_hand - 10
     where item_id = 123;
07:39:13   2  07:39:13   3
1 row updated.

Elapsed: 00:00:00.01
07:39:13 PRIMARY @ORCL -> JINGYU @PDB1>

--@session2:
07:39:01 PRIMARY @ORCL -> JINGYU @PDB1> update inventory
     set qty_on_hand = qty_on_hand - 2
     where item_id = 123;
07:39:29   2  07:39:29   3
1 row updated.

Elapsed: 00:00:00.01
07:39:29 PRIMARY @ORCL -> JINGYU @PDB1>

--@session3:
07:39:03 PRIMARY @ORCL -> JINGYU @PDB1> update inventory
     set qty_on_hand = qty_on_hand - 9
     where item_id = 123;07:39:38   2  07:39:38   3

1 row updated.

Elapsed: 00:00:00.01

--@session4:
07:39:07 PRIMARY @ORCL -> JINGYU @PDB1> update inventory
     set qty_on_hand = qty_on_hand + 20
     where item_id = 123;07:39:45   2  07:39:45   3

1 row updated.

Elapsed: 00:00:00.01

4个会话更新同一行数据,完全不受影响,实现了并发的新高度,即比行锁更细的颗粒度。

2.2 查看journal table

查看journal table,这个是核心,也是Lock-Free Reservation的底层实现机制:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select object_name, object_type, created
     from user_objects order by 3 desc;

结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OBJECT_NAME		       OBJECT_TYPE	       CREATED
------------------------------ ----------------------- ---------
INV_PK			       INDEX		       12-JUN-24
SYS_RESERVJRNL_76171	       TABLE		       12-JUN-24
INVENTORY		       TABLE		       12-JUN-24

查看这个journal table的表结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
07:42:53 PRIMARY @ORCL -> JINGYU @PDB1> desc SYS_RESERVJRNL_76171
 Name												       Null?	Type
 ----------------------------------------------------------------------------------------------------- -------- --------------------------------------------------------------------
 ORA_SAGA_ID$													RAW(16)
 ORA_TXN_ID$													RAW(8)
 ORA_STATUS$													VARCHAR2(11)
 ORA_STMT_TYPE$ 												VARCHAR2(6)
 ITEM_ID											       NOT NULL NUMBER
 QTY_ON_HAND_OP 												VARCHAR2(1)
 QTY_ON_HAND_RESERVED												NUMBER

07:42:58 PRIMARY @ORCL -> JINGYU @PDB1>

select * from SYS_RESERVJRNL_76171;

分别在上面4个会话查询,结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--@session1:
07:42:58 PRIMARY @ORCL -> JINGYU @PDB1> select * from SYS_RESERVJRNL_76171;

ORA_SAGA_ID$			 ORA_TXN_ID$	  ORA_STATUS$ ORA_ST	ITEM_ID Q QTY_ON_HAND_RESERVED
-------------------------------- ---------------- ----------- ------ ---------- - --------------------
				 05001B0068040000 ACTIVE      UPDATE	    123 -		    10

Elapsed: 00:00:00.00

--@session2:
07:39:30 PRIMARY @ORCL -> JINGYU @PDB1> select * from SYS_RESERVJRNL_76171;

ORA_SAGA_ID$			 ORA_TXN_ID$	  ORA_STATUS$ ORA_ST	ITEM_ID Q QTY_ON_HAND_RESERVED
-------------------------------- ---------------- ----------- ------ ---------- - --------------------
				 02000B0050040000 ACTIVE      UPDATE	    123 -		     2

Elapsed: 00:00:00.00

--@session3:
07:39:39 PRIMARY @ORCL -> JINGYU @PDB1> select * from SYS_RESERVJRNL_76171;

ORA_SAGA_ID$			 ORA_TXN_ID$	  ORA_STATUS$ ORA_ST	ITEM_ID Q QTY_ON_HAND_RESERVED
-------------------------------- ---------------- ----------- ------ ---------- - --------------------
				 0A000A00B3030000 ACTIVE      UPDATE	    123 -		     9

Elapsed: 00:00:00.00

--@session4:
07:39:46 PRIMARY @ORCL -> JINGYU @PDB1> select * from SYS_RESERVJRNL_76171;

ORA_SAGA_ID$			 ORA_TXN_ID$	  ORA_STATUS$ ORA_ST	ITEM_ID Q QTY_ON_HAND_RESERVED
-------------------------------- ---------------- ----------- ------ ---------- - --------------------
				 04000E00B2030000 ACTIVE      UPDATE	    123 +		    20

Elapsed: 00:00:00.00

可以看到这个journal table的表SYS_RESERVJRNL_76171详细记录了每个会话对这列的操作。 一旦提交,这个记录就会被清空。有点儿像Oracle的临时表?顺手获取下这个表的创建语句:

select dbms_metadata.get_ddl('TABLE','SYS_RESERVJRNL_76171','JINGYU') from dual;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
07:48:49 PRIMARY @ORCL -> JINGYU @PDB1> select dbms_metadata.get_ddl('TABLE','SYS_RESERVJRNL_76171','JINGYU') from dual;

DBMS_METADATA.GET_DDL('TABLE','SYS_RESERVJRNL_76171','JINGYU')
--------------------------------------------------------------------------------

  CREATE TABLE "JINGYU"."SYS_RESERVJRNL_76171"
   (	"ORA_SAGA_ID$" RAW(16),
	"ORA_TXN_ID$" RAW(8),
	"ORA_STATUS$" VARCHAR2(11),
	"ORA_STMT_TYPE$" VARCHAR2(6),
	"ITEM_ID" NUMBER NOT NULL ENABLE,
	"QTY_ON_HAND_OP" VARCHAR2(1),
	"QTY_ON_HAND_RESERVED" NUMBER
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 16384 NEXT 16384 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"

从创建语句来看倒没有指定临时表创建语句,但感觉上实现机制上有些类似,以后空了再研究,不是很重要。 总之这个日志表是建立无锁列值保留时,Oracle自动创建的,当然也由Oracle自己维护,用户肯定不能对其直接进行操作,否则会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ORA-55727: DML, ALTER, RENAME, and CREATE INDEX operations are not allowed on the reservation journal table "JINGYU"."SYS_RESERVJRNL_76171".
Help: https://docs.oracle.com/error-help/db/ora-55727/

3.使用限制

最后聊下关于Lock-Free Reservation的目前使用限制:

  • 该特性仅限于特定场景,主要是经常需要更新特定列而非整行的场景。
  • 更新特定列也不能随便,只能使用原值增加或减少的方式。
  • 支持的数据类型有限:仅支持数值型数据列,不适用于所有数据类型。
  • 只在23ai数据库版本中提供支持。

3.1 修改非特定列肯定不行

这好像是废话。。。但还是提一句,可不要傻傻的认为表中的所有列都可以。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--@session1:
update inventory
     set item_display_name = 'XXBK'
     where item_id = 123;
     
--@session2:
update inventory
     set item_display_name = 'ABCD'
     where item_id = 123;

比如上面更新这个表的其他列时,session2肯定会等待session1提交或回滚之后才能操作成功。

3.2 修改特定列也有特定限制

特定列就可以随便更新了吗?目前也不是的,只能支持特定的场景,比如使用原值增加或减少的方式。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--@session1:
update inventory
     set qty_on_hand = 30
     where item_id = 123;
          
--@session2:
update inventory
     set qty_on_hand = 40
     where item_id = 123;

上面这种直接更新这个特定列的值,也是会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ORA-55746: Reservable column update statement only supports + or - operations on a reservable column.
Help: https://docs.oracle.com/error-help/db/ora-55746/

3.3 不支持非数值型

如果你定义了非数值型的保留列,建表就会直接报错,明确提醒你只支持NUMBER, INTEGER, FLOAT这些数据类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ORA-55748: Reservable column property specified on column "QTY_ON_HAND" is supported only on columns of data types Oracle NUMBER, INTEGER, and FLOAT.
Help: https://docs.oracle.com/error-help/db/ora-55748/

3.4 修改表中列的RESERVABLE属性

如果你最终发现,你的业务根本不需要列的RESERVABLE属性,那么就可以修改列属性,去掉RESERVABLE属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
alter table inventory modify (qty_on_hand NOT RESERVABLE);

这样,这个列就会支持常规更新操作,但同时,就会和普通列一样持有锁:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--@session1:
update inventory
     set qty_on_hand = 30
     where item_id = 123;
          
--@session2:
update inventory
     set qty_on_hand = 40
     where item_id = 123;

3.5 测试环境清理

最后测试回退相关操作,删除测试表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
drop table inventory;

好了,有关Oracle Database 23ai支持Lock-Free Reservation特性实现并发新高度的测试就到这里了。大家可以想想自己公司的业务中是否有合适的场景可以通过这个特性大幅增加并发能力,欢迎一起讨论。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle 12c系列(五)|PDB Refresh
作者 杨禹航 出品 沃趣技术 PDB Refresh是12C推出的特性,具有对源端PDB进行增量同步的功能,每次刷新会将源端PDB中的任何更改同步到目标PDB(在此环境中目标PDB被称作Refreshable PDB)中,目前增量同步方式有两种:手动方式与自动方式。 一、Refresh MODE语句 在使用Create Pluggable Database创建PDB时指定Refresh MODE子句用来控制是否开启刷新机制。 该子句目前只在"Create Pluggable Database...
沃趣科技
2018/03/26
1.5K0
Operational Property Graphs到底是个啥?
Operational Property Graphs,中文通常译为“操作属性图”。
Alfred Zhao
2024/06/22
1170
Operational Property Graphs到底是个啥?
[译] Oracle Database 21c 中的数据泵(expdp、impdp)增强功能
以下示例,通过 expdp 实用程序导出 T1 表,需要注意的是,T1 表需要包含使用新 JSON 数据类型定义的列。
Lucifer三思而后行
2022/04/13
7300
实验:Oracle数据泵导出导入之序列问题
今天同事提出了一个问题: 使用数据泵expdp导出1个schema,有个表主键是触发器自增的id,导入测试库测试时,发现表里的数据比自增序列的值要大。导致插入数据报错。 最终结论是: 由于数据库先进行序列导出,然后再进行表数据导出。然后在导出的过程中,该表一直有插入操作,最终导致了这种差异。 解决方法: 重建触发器中的序列,让序列的开始值为表主键最大值+1。
Alfred Zhao
2019/05/24
2K0
混合列压缩(HCC)在OLAP及OLTP场景中的测试
2019年度 ACOUG活动启动啦!为了感恩和回馈一直支持社区工作的技术爱好者、会员、嘉宾和合作伙伴,2019年度,我们汇集了行业大咖最新的精彩主题跟大家分享,更有惊喜好礼等你拿,点击“我要报名”,立即参与!2019年,我们将探索更多可能。
数据和云
2019/05/12
4.3K0
Oracle DG环境中的gap处理办法总结
当主库的某些日志没有成功传送到备库,那么这时候就发生了归档裂缝(Archive Gap)。目前Oracle提供了两种日志GAP的检测和处理机制,分别是自动GAP处理(Automatic Gap Resolution)和FAL进程GAP处理(FAL Gap Resolution)。自动GAP处理即主库上的ARCn进程会每分钟检查备库上的日志GAP情况并做相应处理。FAL(Fetch Archive Log)是通过配置FAL_SERVER和FAL_CLIENT实现GAP检测的一种机制,它是备库主动发起的“取”日志的过程。备库就是FAL_CLIENT,它从FAL_SERVER中取这些GAP。Oracle会首先尝试使用FAL进程处理GAP,当发现FAL机制并没有配置生效的时候,进而尝试使用自动GAP处理。FAL进程只在物理备库存在。FAL进程提供了一个CLIENT/SERVER的机制,用来解决检测在主库产生的连续的归档日志,而在备库接受的归档日志不连续的问题。该进程只有在需要的时候才会启动,而当工作完成后就关闭了,因此在正常情况下,该进程是无法看见的。
AiDBA宝典
2023/04/27
2.3K0
Oracle DG环境中的gap处理办法总结
【DB笔试面试793】在Oracle中,如何修复由于主库NOLOGGING引起的备库ORA-01578和ORA-26040错误?
在Oracle中,如何修复由于主库NOLOGGING引起的备库ORA-01578和ORA-26040错误?
AiDBA宝典
2020/05/09
2.1K0
【DB笔试面试793】在Oracle中,如何修复由于主库NOLOGGING引起的备库ORA-01578和ORA-26040错误?
你知道 DBA 工作中都要做的巡检有哪些吗?
-------------------------------------------------------------------
JiekeXu之路
2020/04/14
7760
你知道 DBA 工作中都要做的巡检有哪些吗?
【DB笔试面试666】在Oracle中,高并发高负载情况下,如何给表添加字段、设置DEFAULT值
在Oracle中,在高并发、高负载的情况下,如何给表添加字段并设置DEFAULT值?
AiDBA宝典
2019/10/25
3.7K0
19c 新特性 |ADG 备库支持 DML 重定向
在 Oracle 19c 中有众多的新特性,Oracle 官方上有一个专门收集新特性的网站,从 11g 到 21c 均有涉及,并且每一个新特性都对应了官方文档,仅 19c 新特性就有 118 个。
JiekeXu之路
2022/12/07
5860
19c 新特性 |ADG 备库支持 DML 重定向
【云和恩墨大讲堂】谈Oracle表新增字段的影响
作者简介 刘晨,网名bisal,Oracle 10g/11g OCM,并国内首批Oracle YEP成员,博客:blog.itpub.net/bisal 很多人在做一些表设计时会留出几个reverse
数据和云
2018/03/07
2.5K0
【云和恩墨大讲堂】谈Oracle表新增字段的影响
DDL操作提示了一个DML操作才会抛的ORA错误?
某张表,有个字段,存在默认值,并且设置了NOT NULL约束,例如,NEED_PO VARCHAR2(1) default 'N' not null,
bisal
2019/12/20
6980
DDL操作提示了一个DML操作才会抛的ORA错误?
大厂最爱问的MVCC,到底是个啥?
多版本并发控制(MVCC)是一种用于提高数据库并发性能的技术,尤其在处理高并发读写操作时极为有效。MVCC通过维护数据的多个版本来避免读写冲突,使得读操作无需阻塞写操作,写操作也不会影响读操作。下面,我们具体讲解MySQL中InnoDB存储引擎对MVCC的实现原理。
不惑
2024/09/04
2.1K0
大厂最爱问的MVCC,到底是个啥?
「事件驱动架构」使用GoldenGate创建从Oracle到Kafka的CDC事件流
我们通过GoldenGate技术在Oracle DB和Kafka代理之间创建集成,该技术实时发布Kafka中的CDC事件流。
架构师研究会
2019/12/10
1.2K0
「事件驱动架构」使用GoldenGate创建从Oracle到Kafka的CDC事件流
ClickHouse物化视图在微信的实战经验
ClickHouse广泛用于用户和系统日志查询场景中,借助腾讯云提供基础设施,微信也在分阶段逐步推进clickhouse的建设和应用,目前作为基础建设的一部分,主要针对于OLAP场景,为业务方提供稳定高效的查询服务。
Vitamin_C
2021/06/08
4.9K1
ClickHouse物化视图在微信的实战经验
流数据湖平台Apache Paimon(二)集成 Flink 引擎
Paimon目前支持Flink 1.17, 1.16, 1.15 和 1.14。本课程使用Flink 1.17.0。
Maynor
2023/07/31
3K0
流数据湖平台Apache Paimon(二)集成 Flink 引擎
MySQL8.0新特性集锦
在8.0版本之前,默认字符集为latin1,utf8指向的是utf8mb3,8.0版本默认字符集为utf8mb4,utf8默认指向的也是utf8mb4。
MySQL技术
2019/09/08
9200
Oracle RU23 发布了,花个把小时来玩玩
2024 年 4 月 16 日,Oracle 2024 年第二季度 RU 补丁发布。每个季度 Oracle 发布补丁程序后都会更新 Doc ID 888.1 文档,Primary Note for Database Proactive Patch Program (Doc ID 888.1),从 2022 年 10 月的补丁周期开始,将不再为 19.17.0 及以上版本提供 19c RUR。在 2023 年 1 月交付 Oracle Database 19c RUR 19.16.2 之后,将不再在任何平台上交付其他 RUR。有关详细信息,请参阅 19c RUR 的日落和常见问题解答(Note 2898381.1)。为了让客户更频繁地访问推荐的、经过充分测试的补丁集,Oracle 很高兴从 2022 年 11 月起推出每月推荐补丁(MRP)。MRP 仅支持 Linux x86-64 平台。MRP 可能包括与安全相关的修复。此类安全相关修复将按季度记录在下表中。有关详细信息,请参阅介绍每月推荐补丁 (MRP) 和常见问题解答(Note 2898740.1)。
JiekeXu之路
2024/04/25
8600
Oracle RU23 发布了,花个把小时来玩玩
MyBatis学习总结(四)——MyBatis缓存与代码生成
缓存可以提高系统性能,可以加快访问速度,减轻服务器压力,带来更好的用户体验。缓存用空间换时间,好的缓存是缓存命中率高的且数据量小的。缓存是一种非常重要的技术。
张果
2018/11/08
1.4K0
【DB宝31】Oracle DG环境中主库使用rman做不完全恢复后,备库如何修复继续同步
本文介绍一下,在DG环境中,主库使用rman做不完全恢复后,备库如何通过flashback操作,继续和主库保持同步,而不用重新搭建DG。
AiDBA宝典
2020/12/08
9330
推荐阅读
相关推荐
Oracle 12c系列(五)|PDB Refresh
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验