在之前的一篇博客中,我谈到了可更新的PDB技术,它可以用来更新目标PDB。目标 PDB 可以处于已装入状态(必须更新),也可以以只读模式打开。
一个应用程序是使用目标可刷新的 PDB 作为主服务器来提供 PDB 快照。
PDB 快照是 PDB 在给定时间的副本。源 PDB 可以在创建快照时以只读方式打开,也可以是读/写。拍摄的快照可用于克隆完整的独立 PDB,也可以具体化。
我使用的配置与之前的博客中相同(VM with XFS FS)
Oracle 21c 源 CDB:具有源 PDB -PDB1 的 DB21
Oracle 21c 目标 CDB :TEST21 将包含 PDB1 的可刷新克隆
从可刷新的PDB PDB1FRES,我们可以创建例如2个PDB快照
- 开发人员的 DEVSNAP
- 用于测试的测试快照

让我们在 PDB1 中做一些更改:
SQL> show con_name
CON_NAME
------------------------------
PDB1
SQL>
SQL> select * from test;
ID
----------
1
10
20
30
40
在 TEST21 CDB 上,让我们刷新一下 PDB1FRES:
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
4 PDB1FRES MOUNTED
SQL> alter pluggable database PDB1FRES refresh;
Pluggable database altered.
我们可以验证 PDB1 上新更改是否已生效:
SQL> alter pluggable database PDB1FRES open ;
Pluggable database altered.
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
4 PDB1FRES READ ONLY NO
SQL> alter session set container=PDB1FRES;
Session altered.
SQL> show con_name;
CON_NAME
------------------------------
PDB1FRES
SQL> select * from test;
ID
----------
1
10
20
30
40
50
6 rows selected.
好了,现在让我们从 PDB1FRES 创建 DEVSNAP 快照:
SQL> create pluggable database DEVSNAP from pdb1fres snapshot copy;
create pluggable database DEVSNAP from pdb1fres snapshot copy
*
ERROR at line 1:
ORA-65169: error encountered while attempting to copy file
/u01/app/oracle/oradata/TEST21/D8843948FA4E1659E0531502A8C00AD6/datafile/o1_mf_u
ndotbs1_k16n5zj0_.dbf
ORA-17525: Database clone using storage snapshot not supported on file
/u01/app/oracle/oradata/TEST21/D8843948FA4E1659E0531502A8C00AD6/datafile/o1_mf_u
ndotbs1_k16n5zj0_.dbf
如文档(https://docs.oracle.com/en/database/oracle/oracle-database/21/multi/introduction-to-the-multitenant-architecture.html#GUID-179F941D-B0AE-4BBC-AA59-430652B809B5)中所述,克隆的参数必须设置为 TRUE(因为我没有使用 Exadata 和不支持快照的文件系统)。
如果文件系统支持存储快照,则创建可插拔数据库,快照复制从源 PDB 复制 PDB,该 PDB 可在操作期间读/写。快照副本 PDB 文件使用写入时复制技术。只有修改后的块才需要在磁盘上额外存储。如果文件系统不支持存储快照或使用 Oracle Exadata 稀疏文件,则 CLONEDB 初始化参数必须为 true,并且只要快照副本 PDB 存在,源 PDB 就必须是只读的。
让我们将克隆的参数设置为 TRUE。
SQL> alter system set clonedb=TRUE scope=spfile;
System altered.
SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 1191180480 bytes
Fixed Size 9685184 bytes
Variable Size 335544320 bytes
Database Buffers 838860800 bytes
Redo Buffers 7090176 bytes
Database mounted.
Database opened.
SQL> show parameter clonedb;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
clonedb boolean TRUE
clonedb_dir string
SQL>
让我们尝试重新创建 DEVSNAP(开发快照):
SQL> create pluggable database DEVSNAP from pdb1fres snapshot copy;
Pluggable database created.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DEVSNAP MOUNTED
4 PDB1FRES MOUNTED
SQL>
当它生效后,现在让我们对快照DEVSNAP做一些基本的操作:
在 RW 上打开 DEVSNAP
SQL> alter pluggable database DEVSNAP open;
Pluggable database altered.
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DEVSNAP READ WRITE NO
4 PDB1FRES MOUNTED
SQL>
查询表测试
SQL> alter session set container=DEVSNAP;
Session altered.
SQL> show con_name
CON_NAME
------------------------------
DEVSNAP
SQL> select * from test;
ID
----------
1
10
20
30
40
50
6 rows selected.
SQL>
在 DEVSNAP 上创建一个表
SQL> create table testsnap(id number);
Table created.
SQL> insert into testsnap values (1);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from testsnap;
ID
----------
1
SQL>
当 DEVSNAP 在 RW 中打开时,让我们以 RO 模式打开源 PDB1FRES
SQL> alter pluggable database PDB1FRES open;
Pluggable database altered.
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DEVSNAP READ WRITE NO
4 PDB1FRES READ ONLY NO
SQL> alter session set container=PDB1FRES;
Session altered.
SQL> select * from test;
ID
----------
1
10
20
30
40
50
6 rows selected.
SQL>
让我们再次关闭 PDB1FRES ,并使用 PDB1 中的更改来刷新它(记住 PDB1FRES 是可刷新的 PDB)
SQL> alter pluggable database PDB1FRES close;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
4 PDB1FRES MOUNTED
SQL> alter pluggable database PDB1FRES refresh;
alter pluggable database PDB1FRES refresh
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-01114: IO error writing block to file 18 (block # 1)
ORA-01110: data file 18:
'/u01/app/oracle/oradata/TEST21/D8843948FA4E1659E0531502A8C00AD6/datafile/o1_mf_
users_k16n5zj1_.dbf'
ORA-27091: unable to queue I/O
ORA-27041: unable to open file
Linux-x86_64 Error: 13: Permission denied
Additional information: 3
SQL>
会发生什么?让我们看看 PDB1FRES 的权限文件
SQL> show con_name
CON_NAME
------------------------------
PDB1FRES
SQL> select GUID from v$pdbs;
GUID
--------------------------------
D8843948FA4E1659E0531502A8C00AD6
SQL>
[oracle@oraadserver ~]$ ls -l /u01/app/oracle/oradata/TEST21/D8843948FA4E1659E0531502A8C00AD6/datafile/ total 812324
-r--r-----. 1 oracle oinstall 440410112 Feb 21 09:45 o1_mf_sysaux_k16n5zhx_.dbf
-r--r-----. 1 oracle oinstall 314580992 Feb 21 09:45 o1_mf_system_k16n5zhs_.dbf
-rw-r-----. 1 oracle oinstall 135274496 Feb 21 09:43 o1_mf_temp_k16n5zhy_.dbf
-r--r-----. 1 oracle oinstall 68165632 Feb 21 09:45 o1_mf_undotbs1_k16n5zhx_.dbf
-r--r-----. 1 oracle oinstall 3350528 Feb 21 09:45 o1_mf_undotbs1_k16n5zj0_.dbf
-r--r-----. 1 oracle oinstall 5251072 Feb 21 09:45 o1_mf_users_k16n5zj1_.dbf
[oracle@oraadserver ~]$
如果我们将这些权限与其他 PDBS进行比较
oracle@oraadserver:/home/oracle/ [DB21 (CDB$ROOT)] ls -l /u01/app/oracle/oradata/DB21/B61CD0352E9C6862E0531502A8C08AB7/datafile/
total 803016
-rw-r-----. 1 oracle oinstall 429924352 Feb 21 11:05 o1_mf_sysaux_hx477lhx_.dbf
-rw-r-----. 1 oracle oinstall 314580992 Feb 21 11:10 o1_mf_system_hx477lhw_.dbf
-rw-r-----. 1 oracle oinstall 135274496 Dec 21 14:25 o1_mf_temp_hx477lj0_.dbf
-rw-r-----. 1 oracle oinstall 62922752 Feb 21 11:10 o1_mf_undotbs1_hx477lhy_.dbf
-rw-r-----. 1 oracle oinstall 3350528 Feb 21 10:03 o1_mf_undotbs1_hx477lj0_.dbf
oracle@oraadserver:/home/oracle/ [DB21 (CDB$ROOT)]
我们可以看到,自从我们创建快照后,PDB1FRES 数据文件的权限发生了变化。
是的,这是正常行为。查看以下文档
如何在删除所有快照克隆后安全地恢复源 PDB 的数据文件权限(文档 ID 2627975.1)
我们可以阅读以下几行
当使用 create snapshot copy pdb 从源 PDB 创建快照副本 PDB 时,源 PDB 的数据文件的权限将更改为只读模式。设置这些数据文件权限是为了防止意外修改源 PDB 数据文件。对这些数据文件的任何修改都将阻止依赖于这些数据文件的快照副本 PDB 正常和一致地工作。
因此,如果我们想在创建快照后刷新 PDB1FRES,我们可以按照以下步骤操作:
删除此 PDB1FRES 的所有快照
SQL> alter pluggable database devsnap close;
Pluggable database altered.
SQL> select GUID from v$PDBs where NAME like 'PDB1FRES';
GUID
--------------------------------
D8843948FA4E1659E0531502A8C00AD6
SQL> select PDB_NAME from dba_pdb_history where CLONED_FROM_PDB_GUID like 'D8843948FA4E1659E0531502A8C00AD6';
PDB_NAME
--------------------------------------------------------------------------------
DEVSNAP
DEVSNAP
DEVSNAP
DEVSNAP
SQL>
SQL> drop pluggable database devsnap including datafiles;
Pluggable database dropped.
SQL>
恢复 PDB1FRES 的数据文件权限
SQL> exec dbms_dnfs.restore_datafile_permissions('PDB1FRES');
PL/SQL procedure successfully completed.
SQL>
我们可以验证权限是否已恢复
/u01/app/oracle/oradata/TEST21/D8843948FA4E1659E0531502A8C00AD6/datafile/
total 812324
-rw-rw----. 1 oracle oinstall 440410112 Feb 21 09:45 o1_mf_sysaux_k16n5zhx_.dbf
-rw-rw----. 1 oracle oinstall 314580992 Feb 21 09:45 o1_mf_system_k16n5zhs_.dbf
-rw-r-----. 1 oracle oinstall 135274496 Feb 21 09:43 o1_mf_temp_k16n5zhy_.dbf
-rw-rw----. 1 oracle oinstall 68165632 Feb 21 09:45 o1_mf_undotbs1_k16n5zhx_.dbf
-rw-rw----. 1 oracle oinstall 3350528 Feb 21 09:45 o1_mf_undotbs1_k16n5zj0_.dbf
-rw-rw----. 1 oracle oinstall 5251072 Feb 21 09:45 o1_mf_users_k16n5zj1_.dbf
[oracle@oraadserver ~]$
然后更新
SQL> alter pluggable database PDB1FRES refresh;
Pluggable database altered.
SQL> alter pluggable database PDB1FRES open;
Pluggable database altered.
SQL>
然后我们可以在刷新之后,从 PDB1FRES 重新创建快照。
好的,我们看到在 RW 中打开快照并像普通 PDB 一样处理它。我们还能用快照做什么?
我们可以使用快照作为源来克隆完整的 PDB
SQL> create pluggable database CLONESNAP from DEVSNAP;
Pluggable database created.
SQL> alter pluggable database CLONESNAP open;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DEVSNAP MOUNTED
4 PDB1FRES MOUNTED
5 CLONESNAP READ WRITE NO
SQL>
然后删除 DEVSNAP
SQL> drop pluggable database DEVSNAP including datafiles;
Pluggable database dropped.
SQL>
实现快照副本
物化快照副本 PDB 复制所有数据块。我们可以通过运行带有 MATERIALIZE 子句的 ALTER PLUGGABLE DATABASE 语句来实现快照副本 PDB。物化后,快照副本将转换为完全可插拔的数据库,不再依赖于源 PDB。
SQL> alter session set container=DEVSNAP;
Session altered.
SQL> startup
Pluggable Database opened.
SQL> alter pluggable database materialize;
Pluggable database altered.
SQL>
结论
我们可以学习到可刷新 PDB 技术如何与多租户环境中的快照一起使用,为开发人员提供 PDBS,用于测试。希望这篇文章对你有帮助。




