暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

从Oracle PDB到OB多租户体验国产数据库的核心特性

原创 多明戈教你玩狼人杀 2024-10-14
1166

在上一篇文章《从Oracle PDB到OB多租户窥探国产数据库的核心特性之路》中,我以曾经的产品经理视角,来回顾从Oracle PDB到Oceanbase的多租户特性。而数据库终究是一个要实操的软件,仅仅停留在纸面上的理论,终究要落地到实际操作中。针对上一篇文章提出的三个核心需求,我来以自己的实际操作,进一步来体验分析多租户这一数据库的和新特性。

细粒度的资源分配与隔离

存算与权限,PDB与Oceanbase各自能做到什么样的细粒度?

1. Oracle的资源分配与隔离

1.1 存储资源的隔离

Oracle除了表空间文件的限制,也有pdb上限存储空间的管理,其中参数STORAGE(MAXSIZE n)来控制,可以在创建时显式指定,也可以再修改。

以当前主流的Oracle19c为例,首先我们创建一个PDB叫testpdb,存储上限1GB,并且表空间文件只有100MB:

CREATE PLUGGABLE DATABASE testpdb ADMIN USER testpdb IDENTIFIED BY qwerty1234
STORAGE (MAXSIZE 1G) DEFAULT TABLESPACE testpdb DATAFILE '/u01/app/oracle/oradata/testpdb/testpdb01.dbf' SIZE 100M FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/ora19c/pdbseed', '/u01/app/oracle/oradata/ora19c/testpdb');

除了oracle一直有的可以精准控制表空间的上限,在pdb的存储上限中,也有一个参数MAXSIZE可以控制整个PDB的存储资源上限。如果超过限制会报错:

ORA-65000: invalid operation
ORA-65001: operation would exceed maximum size

一旦到达阈值并且没有打开自增,无论是表空间或者pdb都不会再允许操作,在存储这一点上,Oracle做到了细粒度的资源隔离。


1.2 计算资源的隔离

计算资源每个产品的定义可能不一样,本文的计算资源主要是指IO、CPU与内存三种资源。

1.2.1 内存管理

Oracle在非PDB架构下已经很成熟,PDB架构也基本继承了SGA与PGA的参数管理,既可以为所有PDB统一规划内存分配,也可以单独为某一个PDB规划:

ALTER SESSION SET CONTAINER = testpdb;

ALTER SYSTEM SET SGA_TARGET = 512M SCOPE = BOTH;
ALTER SYSTEM SET SGA_MIN_SIZE = 200M SCOPE = BOTH;

ALTER SYSTEM SET PGA_AGGREGATE_LIMIT  = 512M SCOPE = BOTH;
ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 256M SCOPE = BOTH;

在这一步里,因为我先切到了testpdb,因此后面所有对SGA与PGA的操作,全部都是对testpdb做的。如果不执行第一条,在sqplus进入之后直接执行四条ALTER SYSTEM,就可以对所有PDB做操作。完成之后,可以验证我们分配的结果,实例如下:

SELECT r.con_id,
       p.pdb_name,
       r.begin_time,
       r.end_time,
       r.sga_bytes,
       r.pga_bytes,
       r.buffer_cache_bytes,
       r.shared_pool_bytes
FROM   v$rsrcpdbmetric_history r,
       cdb_pdbs p
WHERE  r.con_id = p.con_id
ORDER BY r.begin_time;    

    CON_ID PDB_NAME   BEGIN_TIME		 END_TIME		     SGA_BYTES	PGA_BYTES BUFFER_CACHE_BYTES SHARED_POOL_BYTES
---------- ---------- -------------------------- -------------------------- ---------- ---------- ------------------ -----------------
	 3 TESTPDB    07-OCT-2024 03:42:39	 07-OCT-2024 03:43:39	      55329504	 22748305	    10348936	      44980568
	 3 TESTPDB    07-OCT-2024 03:43:39	 07-OCT-2024 03:44:39	      55347368	 12459111	    10348936	      44998432
	 3 TESTPDB    07-OCT-2024 03:44:39	 07-OCT-2024 03:45:39	      55360196	 12459111	    10348936	      45011260
	 3 TESTPDB    07-OCT-2024 03:45:39	 07-OCT-2024 03:46:39	      55339762	 12459111	    10348936	      44990826
	 3 TESTPDB    07-OCT-2024 03:46:39	 07-OCT-2024 03:47:39	      55307960	 12459111	    10348936	      44959024
	 3 TESTPDB    07-OCT-2024 03:47:39	 07-OCT-2024 03:48:38	      55374250	  8818569	    10420898	      44953352
	 3 TESTPDB    07-OCT-2024 03:48:38	 07-OCT-2024 03:49:39	      55405092	  7258338	    10451740	      44953352
	 3 TESTPDB    07-OCT-2024 03:49:39	 07-OCT-2024 03:50:39	      55489300	 17220610	    10451740	      45037560
	 3 TESTPDB    07-OCT-2024 03:50:39	 07-OCT-2024 03:51:39	      55534644	  7258338	    10451740	      45082904
	 3 TESTPDB    07-OCT-2024 03:51:39	 07-OCT-2024 03:52:39	      55534644	  7258338	    10451740	      45082904
	 3 TESTPDB    07-OCT-2024 03:52:39	 07-OCT-2024 03:53:39	      55549080	  9893597	    10451740	      45097340

    CON_ID PDB_NAME   BEGIN_TIME		 END_TIME		     SGA_BYTES	PGA_BYTES BUFFER_CACHE_BYTES SHARED_POOL_BYTES
---------- ---------- -------------------------- -------------------------- ---------- ---------- ------------------ -----------------
	 3 TESTPDB    07-OCT-2024 03:53:39	 07-OCT-2024 03:54:39	      55556119	  7258338	    10451740	      45104379
	 3 TESTPDB    07-OCT-2024 03:54:39	 07-OCT-2024 03:55:40	      58299339	  7258338	    11582155	      46717184
	 3 TESTPDB    07-OCT-2024 03:55:40	 07-OCT-2024 03:56:39	      59769329	  7258338	    12190841	      47578488


1.2.2 IO管理

和内存的管理有点相似的是,Oracle同样可以对每个的IOPS做上限的控制,也是一条命令:

ALTER SESSION SET CONTAINER = testpdb;
ALTER SYSTEM SET max_iops=100 SCOPE=BOTH;
ALTER SYSTEM SET max_mbps=400 SCOPE=BOTH;


如果不切到指定的pdb,那么后两条命令的生效范围就是所有pdb。同样可以用查询来验证结果,因为我测试过程没有跑什么业务,所以这两个指标都没有触达上限:

SELECT r.con_id,
       p.pdb_name,
       r.begin_time,
       r.end_time,
       r.iops,
       r.iombps,
       r.iops_throttle_exempt,
       r.iombps_throttle_exempt,
       r.avg_io_throttle
FROM   v$rsrcpdbmetric_history r,
       cdb_pdbs p
WHERE  r.con_id = p.con_id
ORDER BY r.begin_time;  

    CON_ID PDB_NAME   BEGIN_TIME		 END_TIME			  IOPS	   IOMBPS IOPS_THROTTLE_EXEMPT IOMBPS_THROTTLE_EXEMPT AVG_IO_THROTTLE
---------- ---------- -------------------------- -------------------------- ---------- ---------- -------------------- ---------------------- ---------------
	 3 TESTPDB    07-OCT-2024 03:42:39	 07-OCT-2024 03:43:39	    .050513554		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:43:39	 07-OCT-2024 03:44:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:44:39	 07-OCT-2024 03:45:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:45:39	 07-OCT-2024 03:46:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:46:39	 07-OCT-2024 03:47:39	    .148957299		0	    .148957299			    0		    0
	 3 TESTPDB    07-OCT-2024 03:47:39	 07-OCT-2024 03:48:38		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:48:38	 07-OCT-2024 03:49:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:49:39	 07-OCT-2024 03:50:39	    .198642609		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:50:39	 07-OCT-2024 03:51:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:51:39	 07-OCT-2024 03:52:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:52:39	 07-OCT-2024 03:53:39	    .016837851		0		     0			    0		    0

    CON_ID PDB_NAME   BEGIN_TIME		 END_TIME			  IOPS	   IOMBPS IOPS_THROTTLE_EXEMPT IOMBPS_THROTTLE_EXEMPT AVG_IO_THROTTLE
---------- ---------- -------------------------- -------------------------- ---------- ---------- -------------------- ---------------------- ---------------
	 3 TESTPDB    07-OCT-2024 03:53:39	 07-OCT-2024 03:54:39		     0		0		     0			    0		    0
	 3 TESTPDB    07-OCT-2024 03:54:39	 07-OCT-2024 03:55:40	    3.29361139 .033101622		     0			    0		    0


1.2.3 CPU管理

CPU的管理,Oracle19c既可以通过cpu_count和内存以及IO一样直接分配pdb的cpu,同样引入了资源计划的概念,通过资源计划绑定pdb来实现cpu的资源隔离。

资源计划是一个比较大的功能,如果有机会我写一篇文章详解,这里我们主要介绍一下用参数直接调整。假设现在我们有一台服务器,一共16个逻辑CPU,我们要通过资源计划限制上限4个给它。

ALTER SESSION SET CONTAINER = testpdb;
ALTER SYSTEM SET CPU_COUNT=4;
ALTER SYSTEM SET CPU_MIN_ACCOUNT=2;



此时testpdb能够使用的cpu上限就是4个逻辑CPU,如果不在PDB中指定这几个参数,那么每个PDB默认可以使用的上限就是根容器的cpu_count上限。可以通过查询可以看到结果:


select a.con_id,nvl(b.name,'CDB$ROOT') as dbname,a.name,a.value from v$system_parameter a,v$pdbs b
where a.con_id=b.con_id(+) and a.name ='cpu_count'
order by a.con_id;

CON_ID DBNAME NAME VALUE
---------- ---------- -------------------------------------------------- --------------------------------------------------
0 CDB$ROOT cpu_count 16
3 TESTPDB cpu_count 4



1.3 用户权限的分配与隔离

在Oracle的pdb架构下,创建用户进一步被细分,一部分是pdb下的用户,这些用户仅仅被特定的pdb可见,不会出现在其他pdb或者根容器cdb$root下。而根容器下禁止创建本地用户,只能创建c##开头的用户,通过授权,这类用户可以在不同pdb之间登陆。

例如我在testpdb下,创建一个新用户test1,并查询:


ALTER SESSION SET CONTAINER = testpdb;
CREATE USER test1 IDENTIFIED BY welcome1;
select username from dba_users;

USERNAME
--------------------------------------------------------------------------------
SYS
SYSTEM
XS$NULL
OUTLN
DBSNMP
APPQOSSYS
DBSFWUSER
GGSYS
ANONYMOUS
GSMADMIN_INTERNAL
XDB

USERNAME
--------------------------------------------------------------------------------
WMSYS
GSMCATUSER
TEST1
REMOTE_SCHEDULER_AGENT
PDBADMIN
SYSBACKUP
GSMUSER
SYSRAC
AUDSYS
DIP
SYSKM

USERNAME
--------------------------------------------------------------------------------
ORACLE_OCM
SYS$UMF
SYSDG

25 rows selected.


--在另一个newpdb下查询,不会出现:

ALTER SESSION SET CONTAINER = newpdb;
select username from dba_users;

USERNAME
--------------------------------------------------------------------------------
SYS
SYSTEM
XS$NULL
OUTLN
DBSNMP
APPQOSSYS
DBSFWUSER
GGSYS
ANONYMOUS
GSMADMIN_INTERNAL
XDB

USERNAME
--------------------------------------------------------------------------------
WMSYS
GSMCATUSER
REMOTE_SCHEDULER_AGENT
PDBADMIN
SYSBACKUP
GSMUSER
SYSRAC
AUDSYS
DIP
SYSKM

USERNAME
--------------------------------------------------------------------------------
ORACLE_OCM
SYS$UMF
SYSDG

24 rows selected.


在根容器下同样不会出现。

在根容器下创建一个多租户通用的用户c##test1,创建和授权,都可以指定在具体某个pdb中生效,或者是所有pdb。

CREATE USER C##TEST1 IDENTIFIED BY test1234 CONTAINER=ALL;  —在所有PDB均生效

GRANT DBA TO C##TEST1 CONTAINER=testpdb; —仅仅在testpdb中有dba权限


这里需要注意的是,执行了这两条语句,虽然c##test1已经可存在于所有pdb,但是除了testpdb没有任何权限,所以除了testpdb,其他pdb是连登录都没有的。


1.4 小结

Oracle在PDB中的细粒度资源隔离,我来做一个小结:

1. 实现了PDB级别的权限隔离,同样名称的用户,可以存在于不同的PDB中,互不干扰。

2. 根容器的高权限用户,例如sys可以对所有pdb做所有操作,权限不受影响。

3. 根容器中可以创建跨pdb的用户,可以指定pdb范围,可以实现在不同pdb下的不同权限。

4. 存算资源,都做到了细粒度的资源分配,可以通过参数配置上限下限,从而做到不同pdb之间的资源分配。

5. 提供了更加复杂且精确的资源计划功能,需要更多的配置,后续如果有机会展开描述。

在PDB层面,确实是实现了权限的隔离,但其实这并不是完全严格的权限隔离,根容器的SYS用户仍然可以干扰pdb下的数据库运维管理。


2. Oceanbase的资源分配与隔离

Oceanbase的多租户之间的资源隔离,是通过两个方式来实现的,一个是在租户创建中定义的资源规格与资源池,另一个就是类似Oracle的资源管理计划。我们着重介绍前者。

2.1 资源规格

资源规格(Unit)是对 CPU、内存、磁盘空间、IOPS 等资源项进行的定义。包含了CPU、内存、日志盘空间、IOPS 等资源项。具体的创建语法如下:

CREATE RESOURCE UNIT unit_name 
    MEMORY_SIZE [=] 'size_value',
    MAX_CPU [=] cpu_num,  
    [LOG_DISK_SIZE [=] 'size_value',]
    [MAX_IOPS [=] iops_num,]
    [MIN_CPU [=] cpu_num,]
    [MIN_IOPS [=] iops_num]    [IOPS_WEIGHT [=] iops_weight_num];

我们能看见的是,这里面实际包含的项目有内存上限、CPU上限下限、日志盘大小、IOPS上限下限与权重。一个数据库集群,允许拥有多种资源规格。实际上这个思想更加接近云原生,能够通过自定义,创建不同规格的资源组,根据实际业务需求分配不同数量的资源组:

CREATE RESOURCE UNIT unit1
                MEMORY_SIZE = '4G',
                MAX_CPU = 1, MIN_CPU = 1,
                LOG_DISK_SIZE = '4G',
                MAX_IOPS = 10000, MIN_IOPS = 2000, IOPS_WEIGHT=1;

CREATE RESOURCE UNIT unit2
                MEMORY_SIZE = '4G',
                MAX_CPU = 2, MIN_CPU = 1,
                LOG_DISK_SIZE = '6G',
                MAX_IOPS = 1500, MIN_IOPS = 1000, IOPS_WEIGHT=2;

查询 DBA_OB_UNIT_CONFIGS 视图,,可以确认资源规格创建成功

SELECT name,max_cpu,min_cpu,max_iops FROM oceanbase.DBA_OB_UNIT_CONFIGS WHERE NAME like 'unit%';
+----------------+---------+---------+----------+----------+
| NAME           | MAX_CPU | MIN_CPU | MAX_IOPS | MIN_IOPS |
+----------------+---------+---------+----------+----------+
| unit1          |       1 |       1 |    10000 |    10000 |
+----------------+---------+---------+----------+----------+
| unit2          |       2 |       1 |     1500 |     1000 |+----------------+---------+---------+----------+----------+
2 row in set


2.2 资源池

顾名思义,资源池是在创建多租户时可以使用的资源集合,而其中资源分配的最小粒度就是资源规格,语法如下:

CREATE RESOURCE POOL poolname 
    UNIT [=] unitname, 
    UNIT_NUM [=] unitnum, 
    ZONE_LIST [=] ('zone' [, 'zone' ...]);

一个resource pool,允许使用一种资源规格,通过数量来定义总量,通过zone_list参数来确定资源池在zone中的分布。例如我们创建一个包含5倍unit1的资源池:

CREATE RESOURCE POOL rp1
                UNIT='unit1', 
                UNIT_NUM=5, 
                ZONE_LIST=('zone1','zone2'); 

查询结果,能够看到已经创建的资源池rp1:

SELECT NAME,UNIT_COUNT,UNIT_CONFIG_ID,ZONE_LIST FROM DBA_OB_RESOURCE_POOLS WHERE NAME = 'rp1';
+------------+------------+----------------+--------------+
| NAME       | UNIT_COUNT | UNIT_CONFIG_ID | ZONE_LIST    |
+------------+------------+----------------+--------------+
| rp1        |          5 | 1021           |  zone1;zone2 |
+------------+------------+----------------+--------------+
1 row in set


2.3 创建租户

创建资源组与资源池是创建租户的先决条件,实际上创建租户是从资源池里获取资源,完成租户的创建,租户的资源取决于资源池里的资源数量,而通过修改资源组的资源,可以直接对租户做扩缩容。

CREATE TENANT [IF NOT EXISTS] tenant_name  
    PRIMARY_ZONE [=] zone,
    RESOURCE_POOL_LIST [=](poolname [, poolname...])
    [ENABLE_ARBITRATION_SERVICE = {true | false}]
    {SET | SET VARIABLES | VARIABLES} system_var_name = expr [,system_var_name = expr] ...


例如我们创建一个租户tenant1,使用资源池rp1:

CREATE TENANT IF NOT EXISTS tenant1 
                PRIMARY_ZONE='zone1', 
                RESOURCE_POOL_LIST=('rp1')
                set OB_TCP_INVITED_NODES='%';


2.4 权限分配与隔离

租户创建完成之后,会自动生成超级用户root或者sys,根据是mysql模式还是oracle模式有所不同,第一次登录没有密码,需要用户自行修改。

与Oracle不同的是,Oceanbase的多租户权限分配与隔离,更加严格。不同租户之间的用户是完全隔离的,而且就连重置租户的管理员密码功能,也无法通过系统租户来实现。这一点上更为严格,集群管理员无从得知租户管理员的密码,相当程度上减少了密码的人为泄露风险。

我们以MySQL模式为例,首先我们在租户tenant1创建一个用户test

create user test identified by "tewq1234";
Query OK, 0 rows affected (0.059 sec)

select user,host from mysql.user;
+------+------------+
| user | host       |
+------+------------+
| root | %          |
| test | %          |
+------+------------+
3 rows in set (0.001 sec)


登录到系统租户,是不会看到这个用户的

select user,host from mysql.user;
+-------------+------+
| user        | host |
+-------------+------+
| root        | %    |
| proxyro     | %    |
| ocp_monitor | %    |
+-------------+------+


在系统租户中,创建一个用户root_test

create user root_test identified by "qwer1234";
Query OK, 0 rows affected (0.086 sec)

obclient [oceanbase]> select user,host from mysql.user;
+-------------+------+
| user        | host |
+-------------+------+
| root        | %    |
| proxyro     | %    |
| ocp_monitor | %    |
| root_test   | %    |
+-------------+------+


登录到tenant1,同样也没有

select user,host from mysql.user;
+------+------------+
| user | host       |
+------+------------+
| root | %          |
| test | %          |
+------+------------+

虽然两个租户都有同一个用户root,但是彼此之间也是完全不同的两个用户,通过加入租户名称来区分,如果用其中一个租户的root登录另一个root租户,一定会报错(当然如果两个密码一样也是可以成功的)

ERROR 1045 (42000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)


2.5 小结

接下来我来对Oceanbase的多租户资源分配与隔离做一个小结:

1. Oceanbase基于云原生的思路,所有租户的创建,都必须经过unit、pool、租户三个级别,缺一不可。

2. unit的引入,让租户的资源分配以及扩缩容更加灵活,更方便地管理不同租户之间的资源分配。

3. Oceanbase实现了严格意义上的用户权限隔离,安全性非常好,与Oracle模式相比,各有千秋。

4. 与Oracle相比,Oceanbase的资源分配模式更注重更少地人工干预,尽量实现标准化的资源分配。



运维管理与可观测性

这部分思量再三,还是决定放到同一个大标题下一起写,这两者有时候是你中有我,我中有你的关系。

3. Oracle的特性表现

3.1 租户管理

Oracle的pdb,可以实现对租户的非常细粒度的管理,从语法树可见一斑

ALTER PLUGGABLE DATABASE
  { pdb_unplug_clause
  | pdb_settings_clauses
  | pdb_datafile_clause
  | pdb_recovery_clauses
  | pdb_change_state
  | pdb_change_state_from_root
  | application_clauses
  | snapshot_clauses
  | prepare_clause
  | drop_mirror_copy
  | lost_write_protection
  } ;

pdb_unplug_clause,顾名思义,就是pdb的插拔选项。unplug的pdb,以XML与PDB等文件的方式保存在存储中,可以通过复制到其他地方,实现pdb的快速迁移

pdb_settings_clauses,对pdb的各个参数做调整,包含临时表空间、默认表空间、重命名、日志管理、时区、端口等内容

pdb_datafile_clause,pdb数据文件的维护,主要功能是对特定数据文件的online与offline操作

pdb_recovery_clauses,pdb级别的热备份或者dataguard恢复功能

pdb_change_state,对pdb状态的操作,与非pdb架构的oracle实例相似,除了close, mounted与open三种状态,还有一个migrate用于升级

pdb_change_state_from_root,在根容器中,批量修改一个或多个pdb状态的子句,与上一个状态范围一样

application_clauses,对pdb单独维护,包括更新application,application补丁的安装与升级

snapshot_clauses,快照管理,包括对pdb做快照、删除快照、将快照克隆成为新pdb等功能

prepare_clause,准备pdb的镜像副本,例如将某个pdb变成HIGH REDUNDANCY,用过ASM的话对这个应该不陌生

drop_mirror_copy,删除镜像副本

lost_write_protection,写丢失保护功能,在打开之后,如果文件进入写丢失保护的恢复状态,会告警

我们几个例子,有关这些命令的:

 --将testpdb拔出并将元数据写入testpdb.xml
ALTER PLUGGABLE DATABASE testpdb
  UNPLUG INTO '/home/oracle/data/testpdb.xml'; 

--将testpdb存储上限设置为5GB
ALTER PLUGGABLE DATABASE pdb2  
  STORAGE (MAXSIZE 5G);

--将testpdb所有数据文件offlin
ALTER PLUGGABLE DATABASE testpdb   e
  DATAFILE ALL OFFLINE;

 --将newpdb端口修改为1599
ALTER PLUGGABLE DATABASE newpdb CONTAINERS PORT=1599; 

--将newppdb关闭
ALTER PLUGGABLE DATABASE newpdb  
  CLOSE;



3.2 租户的高可用

在Oracle19c中,暂时不支持PDB级别的dataguard,在21c之后才支持。然而在19c中,RMAN已经支持了pdb级别的备份恢复,这一点大大提升了日常管理的便利性。

例如,我们使用sys用户登录RMAN

rman target /
RMAN> BACKUP PLUGGABLE DATABASE testpdb;Starting backup at 07-OCT-23
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=1234 device type=DISK

starting full backup set
...
backup set complete, elapsed time: 00:01:23
...

Finished backup at 07-OCT-23


同样,也可以使用pdb的用户直接登录RMAN,使用熟悉的BACKUP DATABASE;

rman target admin/admin1234@testpdb

RMAN> BACKUP DATABASE;Starting backup at 07-OCT-23
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=1234 device type=DISK

starting full backup set
...
backup set complete, elapsed time: 00:01:23
...

Finished backup at 07-OCT-23


PDB的恢复,同样可以使用sys或者pdb的管理员来执行,例如

rman target /

RMAN> RESTORE PLUGGABLE DATABASE testpdb;
Starting restore at 14-OCT-23
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=1234 device type=DISK

restoring pluggable database TESTPDB
...
restore complete, elapsed time: 00:02:15
...

Finished restore at 14-OCT-23

RMAN> RECOVERY GGABLE DATABASE testpdb;
Starting recover at 14-OCT-23
...
Recovery of pluggable database TESTPDB complete.
Finished recover at 14-OCT-23

SQL> ALTER PLUGGABLE DATABASE testpdb open;
Pluggable database altered.

3.3 租户的克隆

Oracle19c提供了pdb的克隆,而19c甚至支持了热克隆,在源库能够继续保持可用的情况下,完成pdb的克隆,当然这期间pdb的性能也会受到影响。例如

CREATE PLUGGABLE DATABASE newpdb FROM testpdb
FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/ora19c/testpdb', '/u01/app/oracle/oradata/ora19c/newpdb');
Pluggable database created.


这样不需要close immediate,就可以完成对pdb的在线克隆。


3.4 可观测性

Oracle的可观测性,一直在诸多数据库中是独一档的。19c在pdb中,提供了如下几种手段:

1. 动态视图。这个在非pdb架构之前,就是很多dba一直津津乐道的,在pdb时代,除了增加了一些v$pdb开头的视图,也增加了一些原有视图关于pdb的字段,例如查看pdb可更新的参数

select * from v$parameter 
where ispdb_modifiable='TRUE';

2. OEM/EMCC。Oracle的EMCC一直以来是我做OracleDBA做喜欢的运维工具。在pdb时代,提供 PDB 级别的性能监控,包括CPU使用率、内存使用、I/O性能等,允许管理员更细致地分析每个PDB的状态。还可以为各个PDB设置自定义告警阈值,以便及时发现问题。支持对不同PDB的性能进行比较,帮助识别资源使用不均衡的情况。帮助DBA更有效地管理多租户环境中的pdb,确保性能优化和资源合理分配。这里推荐尹海文老师的emcc系列文章《数据库管理-第144期 深入使用EMCC-01(20240204)》,比我写的深入。

3. AWR报告。在pdb环境中,已经可以允许pdb的dba单独生成pdba的awr报告,诊断内容与原有的Oracle AWR基本一致,过往的经验可以平移过来。很多针对pdb的性能指标,也有所体现。


3.5 小结

针对Oracle19c提供的运维与可观测特性,我做一个总结:

1. 对pdb的细粒度管理非常到位,在非pdb架构下能做的维护,基本在pdb都能实现。

2. 支持了RMAN对pdb的备份恢复,而且放权给了pdb的dba,在多租户的架构下解放了集群dba。

3. 19c不支持pdb级别的dataguard,后续版本支持,这是这个版本的一个遗憾。

4. 可观测性做的依旧非常优秀,针对pdb的各项优化都很好。

5. 非常重要的是,过往的运维管理经验,都可以迁移到pdb。


3. Oceanbase的特性表现

3.1 租户管理

这一部分,我们依旧通过ALTER TENANT命令来解析,在Oceanbase中,该命令的语法树如下:

ALTER TENANT tenant_name
    [SET] [tenant_option_list] [set_sys_var];

tenant_option_list:
    tenant_option [, tenant_option ...]

tenant_option:
      LOCALITY [=] 'locality_description'
    | PRIMARY_ZONE [=] zone
    | RESOURCE_POOL_LIST [=](pool_name [, pool_name...])
    | ENABLE_ARBITRATION_SERVICE [=] {True | False}
    | [DEFAULT] TABLEGROUP [=] {NULL | tablegroup_name}
    | ENABLE_EXTENDED_ROWID [=] {true | false}  
    | COMMENT [=]'string'   

set_sys_var:
    VARIABLES var_name {TO | =} var_value [,var_name {TO | =} var_value...]

ALTER TENANT tenant_name RENAME GLOBAL_NAME TO new_tenant_name;

ALTER TENANT tenant_name LOCK | UNLOCK;

我们先看tenant_option的几个选项,都包含了哪些功能。

LOCALITY,修改租户副本在各个zone之间分布的情况,作为多副本的分布式数据库,这是在Oceanbase中特有的功能

PRIMARY_ZONE,修改租户的 Primary Zone,这个zone负责储存该租户的所有副本,来确保数据的高可用

RESOURCE_POOL_LIST修改租户的资源池,通过该命令,可以对租户做扩缩容

ENABLE_ARBITRATION_SERVICE,部署了仲裁服务的场景下,修改租户仲裁服务的开启状态,分布式事务相关的参数

[DEFAULT] TABLEGROUP,修改租户的表组,可以控制一组表在物理存储上的邻近关系

ENABLE_EXTENDED_ROWID,指定是否为租户内所有表开启Extended ROWID模式,开启rowid的上限则会大幅提高

system_var_name,修改租户的系统变量,可以涵盖的参数非常多

RENAME GLOBAL_NAME TO,修改租户名称

LOCK | UNLOCK,锁定或解锁租户,租户锁定后,不能在该租户上创建新的连接,已有连接保持不变

从参数列表来看,Oceanbase作为云原生的分布式数据库,相当多的管理命令是集中在分布式的管理,比如zone相关就占了相当高的比例。除此之外,Oceanbase的系统租户,可以对普通租户的参数直接做调整而不需要登录,这一点和Oracle最终实现的结果是一样的。要找出与Oracle的差异,可能没有批量对租户参数做调整的功能。我们照样来看几个例子:

--为tenant1添加资源池rp2

ALTER TENANT tenant1 resource_pool_list=('rp1','rp2');

--将tenant1修改为tenant101

ALTER TENANT tenant1 RENAME GLOBAL_NAME TO tenant101;

--将tenant101的primary zone修改为zone2

ALTER TENANT tenant101 PRIMARY_ZONE 'zone2';

--锁定住户tenant101,并查看所有修改结果结果

ALTER TENANT tenant101 LOCK;

SELECT TENANT_NAME, TENANT_TYPE,PRIMARY_ZONE,LOCKED FROM DBA_OB_TENANTS where TENANT_NAME='tenant101';
+-------------+-------------+--------------+---------+
| TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCKED  |
+-------------+-------------+--------------+---------+
| tenant101   | USER        |  zone2      |  YES     | 
+-------------+-------------+--------------+---------+


3.2 租户的高可用

Oceanbase的高可用,涉及到了多副本、多zone等因素,实际想要描述清楚,就要比Oracle难一些。我尝试着总结提炼,有可能有总结不当,还请指正。

1.高可用与多副本。可以实现多地多副本的数据一致性,这就提供了租户在不同地区的数据高可用,与Dataguard的异地灾备有着接近的效果。这里与Oracle19c不一样的是,可以通过ALTER TENANT命令来实现单个租户的不同副本数,不同的租户可以以不同的副本数量来存在,这一点更为灵活。

2.备用租户。Oceanbase确实是在租户级别实现了主备的逻辑区分。语法树如下:

CREATE STANDBY TENANT [IF NOT EXISTS] tenant_name 
  LOG_RESTORE_SOURCE [=] string_value
  [tenant_characteristic_list];

tenant_characteristic_list: 
tenant_characteristic [, tenant_characteristic...]

 tenant_characteristic: 
   COMMENT 'string'  
 | PRIMARY_ZONE [=] zone_name  
 | RESOURCE_POOL_LIST [=](pool_name [, pool_name...])
 | LOCALITY [=] 'locality description'

语法树来看,备租户的创建其实和普通租户创建步骤差不多,先创建unit在创建resource_pool,最后创建租户时,需要加关键字standby,而效果与Dataguard十分相似,就连用户和权限都可以保持一模一样,唯独角色是STANDBY:

CREATE STANDBY TENANT standby_tenant LOG_RESTORE_SOURCE = "SERVICE=host1:2881;host2:2881;host3:2881 USER=admin@tenant1 PASSWORD=******" RESOURCE_POOL_LIST=('pool_for_standby');
SELECT TENANT_NAME, TENANT_TYPE, TENANT_ROLE FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME = 'standby_tenant';
+----------------+-------------+-------------+
| TENANT_NAME    | TENANT_TYPE | TENANT_ROLE |
+----------------+-------------+-------------+
| standby_tenant | USER        | STANDBY     |
+----------------+-------------+-------------+


如果我们将这个备租户激活,那么状态会发生变化:

ALTER SYSTEM ACTIVATE STANDBY TENANT standby_tenant;SELECT TENANT_NAME, TENANT_TYPE, TENANT_ROLE FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME = 'standby_tenant';
+----------------+-------------+-------------+
| TENANT_NAME    | TENANT_TYPE | TENANT_ROLE |
+----------------+-------------+-------------+
| standby_tenant | USER        | PRIMARY     |
+----------------+-------------+-------------+

3.备份与恢复。Oceanbase能够实现租户级别的备份与恢复,而且备份目标端,可以支持低成本的对象存储。例如在集群中,我们有一个nfs路径,将租户备份至此,备份的历史信息可以通过视图DBA_OB_BACKUP_STORAGE_INFO去查询

ALTER SYSTEM SET DATA_BACKUP_DEST= 'file:///obdata/backup/data' TENANT = tenant1;ALTER SYSTEM BACKUP TENANT = tenant1;

对于恢复租户,同样使用ALTER SYSTEM来实现(此处操作过程丢失,无法还原见谅)

ALTER SYSTEM RESTORE tenent01 FROM 'file:///obdata/backup/data' UNTIL TIME='xxxxxx' WITH 'pool_list=xxxx&locality=F@z1,F@z2&primary_zone=z1';


3.3 租户的克隆

同样,Oceanbase也提供了租户克隆的功能,语法树如下:

CREATE TENANT new_tenant_name FROM source_tenant_name 
   WITH
   RESOURCE_POOL [=] resource_pool_name,
   UNIT [=] unit_config;


语法与Oracle的pdb克隆也有相似之处,new from old的模式。两个参数分别对应了新租户的资源池与资源组,需要在克隆时显式指定资源池的名称,以及资源组的配置。例如,我们创建一个租户tenant2,资源池命名为rp3,而使用的资源规格,仍然是unit1:

CREATE TENANT tenant2 FROM tenant1 WITH
   RESOURCE_POOL = rp3,
	 UNIT= unit1;
SELECT TENANT_NAME, TENANT_TYPE,PRIMARY_ZONE,LOCKED FROM DBA_OB_TENANTS where TENANT_NAME='tenant2'; +-------------+-------------+--------------+---------+ | TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCKED | +-------------+-------------+--------------+---------+ | tenant2 | USER | zone2 | NO |
+-------------+-------------+--------------+---------+

而克隆这一过程,需要时间,根据租户的大小耗时不等,好在Oceanbase提供了取消克隆命令,以及查看克隆历史的视图DBA_OB_CLONE_HISTORY,例如,我们重新登录一个会话,可以取消克隆,并查看结果

ALTER SYSTEM CANCEL CLONE tenant2;
SELECT CLONE_TENANT_NAME,STATUS FROM oceanbase.DBA_OB_CLONE_HISTORY
+--------------+--------------------+ | CLONE_TENANT | STATUS | +--------------+--------------------+ | tenant2 | CLONE_SYS_CANCELED | +--------------+--------------------+


3.4 可观测性

截止到Oceanbase4.3,一共有如下几种手段能够提高我们对数据库的可观测性:

1. 各类视图。和Oracle类似,Oceanbase提供了v$或gv$开头的大量视图。这些视图包含了按照租户级别统计的各类动态指标,例如V$SESSTAT,就包含了一列CON_ID,代表租户ID,通过与租户列表join,就可以获取到所有租户的会话等等。

2. OCP。OCP是Oceanbase开发的WEB管理系统,定位和Oracle的EMCC很像,既包含了实时监控的动态指标,又可以对数据库做比较多的操作。其中对于多租户之间的资源占比、租户内部的统计信息,都有不同维度的可视化参考,基本上涵盖了常用的多租户可视化运维需求。

3. ASH。Oceanbase除了具有Oracle兼容的语法与管理模式,还开发了自己的ASH报告。而工作负载库的名称DBMS_WORKLOAD_REPOSITORY也与Oracle保持一致。ASH作为抓取短期内性能指标用于分析的工具,在性能监控和优化中使用频繁。Oceanbase的版本,基本涵盖了Oracle中对应的概念与指标,也是DBA所关注的。


3.5 小结

最后做一个总结,Oceanbase在多租户运维和可观测性方面的特点:

1. 因为架构上的差异,Oceanbase提供了针对分布式、资源池、zone、租户克隆等特性对应的多租户管理方式,能够覆盖到多租户的日常管理需求。

2. 提供了类似Dataguard的Standby模式,并且支持激活或者主备切换standby的运维,这一点与Oracle Dataguard有着相同的思路。

3. 备份恢复这里,我个人认为,Oceanbase的产品能力,距离RMAN还有差距,备份恢复仍然需要一定的学习门槛。

4. OCP作为自研的管理平台,易用性方面较为不错,而且系统响应的时间,我认为好于Oracle的EMCC,期待后续功能继续增加。

5. Oracle过往的pdb管理经验,能够大部分平移过来,需要适应的是语法和架构差异带来的变化。


不算完结的完结

通过比较两个产品,实际上Oceanbase的多租户特性以及管理能力,已经在诸多方面不亚于Oracle的pdb,而且基于自己分布式和云原生的特性,在许多方面都有自己的见解和路线,比如创建资源池和资源规格的方式,打破了过去大家的思维定势,用另一种方式去解释去定义资源的分配与隔离。而有些地方我认为甚至超越了Oracle19c,例如租户级别的switchover。当然也一些地方,仍然需要努力,比如RMAN一样简单上手,几个命令就能完成的备份恢复工具。还有一些使用体验上的小地方。而且本文没有涉及到两个点,一个是同等配置下的性能对比,另一个是系统的可靠性稳定性的对比,时间所限,我只能从功能层面上来尽力完成。我相信后续,会有更多的DBA去做比我更详细更可靠的对比分析。留给Oceanbase团队的各种考验和挑战,其实并没有结束。


这篇文章写到这里,已经写了八千多字,还是想说点个人情绪相关的。本来还想要不要继续拆成两篇文章,纠结之后还是选择了一篇完成。从9月开始准备,国庆期间断断续续完成操作,终于今天完成落笔。期间因为黑神话悟空的游玩,一度中断,好在假期没有出去玩,不断督促自己完成了。不能不说,还是存在虎头蛇尾的情况,在这里给各位道个歉。实际上在这一个月多月的过程里,我阅读了很多Oracle以及Oceanbase的官方文档。好在Oceanbase的多位朋友一直给予各种帮助,以及Oceanbase文档内容的翔实、产品力的健壮,后面很多例子干脆就拿了官方文档,让我能够完成这篇流水账。

期间我也翻了Oceanbase的历史版本,如同看一个人的成长历程,如何从一个孩子慢慢长大一般。也为我们国产数据库有这样的成长感到喝彩。平心而论,Oceanbase在多租户管理方面的能力和进步,超出了我做整个系列文章之前的预期。从产品设计到研发测试再到文档支持,中间任何一个环节的缺失,都不可能有今天的Oceanbase。曾几何时,我也希望自己你作为国产数据库从业者,开发一款让自己、让客户、让同行感觉很酷的产品。而在Oceanbase这里,我仿佛看到了曾经梦想中的产品。

当然,我仍然像泼一盆冷水。Oracle也在不断演进,很多pdb的特性在21c或者21ai中,也让我眼前一亮。这些新特性在Oceanbase上或者还没有,或者让我感觉做的还不够好。高标准严要求,我希望有一天,Oceanbase也能实现那样的能力和特性,而不是躺在今天的功劳簿上偷懒。国产数据库的和新特性,需要的是十年如一日,持之以恒的投入。

同样我也期望,有一天有更多国产数据库品牌,能够创造更多的惊喜给这个行业。面对滥竽充数的东西,平时我没少骂,而面对好的东西,我也一定会用尽我的言辞去夸奖。每个人都是自己人生路上的天命人,每个成功的数据库品牌,都是自己剧本里的孙大圣。

完结之前,突然想到我的师爷,有着当代毕升之称的王选院士,毕生的遗憾之一,就是没有见过他本人,我入学的时候,他已经作古。然而他的汉字激光排版技术,却照亮了一代又一代后辈。——他走之后,我们不必记挂着他,因为我们就是他。国产数据库这座高峰,就是我们这代人攀登的目标。

最后修改时间:2024-10-25 17:36:15
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论