租户克隆介绍
在实际的业务中,会遇到以下几个场景:
大促期间,产品卖得特别好,老板要一份当前整体销售情况的报表。这个时候数据库 CPU 已经达到了 85% ,这时应该怎么做呢?是选择冒险跑报表任务,还是对老板进行预期管理?
当生产租户的压力非常大时,内部运营系统还会发送些不确定的复杂查询到生产租户上,那么有什么方法能快速将来自内部的复杂查询负载,从生产租户上移走吗?
业务版本升级新版本前先备份数据库再发应用版本。假如应用版本发布出现问题,需要尽快恢复数据库来回退版本,这时有简便易操作的手段来实现目的么?
OceanBase 数据库在 V4.3 版本推出的租户克隆功能就能帮助解决上述问题。
基于租户克隆功能,在系统租户下执行一条租户克隆语句,就可以快速的基于源租户克隆出一个新租户。
正如克隆一词所描述的,新克隆出的租户,在初始时刻,它包含的数据就是源租户在语句执行时刻的一个快照。 克隆租户的操作可以类比为进程的 fork 操作。 fork 操作是父进程把页表信息拷贝一份给子进程,使得子进程在初始时刻访问的是和父进程完全相同的物理页。克隆操作也一样,在克隆的过程中,将源租户的元数据拷贝一份给到新克隆租户,使得新克隆租户在初始时刻,访问的是和源租户完全相同的物理宏块。
因为整个克隆过程中,只拷贝了元数据,没有实际拷贝数据,所以克隆操作可以非常快速的完成。在测试环境中,一个 8 核 64 G 包含 50 万张表 8TB 数据的租户,克隆出一个新的 8 核 64 G的租户,只要两分钟就可以完成。
新克隆出来的租户和源租户是两个完全独立的租户,它们具有各自的 CPU、内存和 IOPS 资源, 不会互相影响。
对于报表任务,可以基于生产租户快速克隆出一个新的报表租户,这个新的报表租户有自己的 CPU、内存 和 IOPS 资源,可以放心地在报表租户上跑报表任务,尽可能减少对生产租户的影响。
OceanBase从 4.3 版本开始,支持行列混存模式 ,如果源租户是行列混存的结构,那么克隆出的新租户也是行列混存结构,可以非常好地支持 AP 负载 。
对于“从生产租户移走复杂查询”,可以基于生产租户克隆出一个新租户,将新租户设置为生产租户的备租户,这样新租户就会主动从生产租户拉取日志进行回放,能够对外提供准实时的弱读服务。如此,就可以把来自内部运营系统中的复杂查询负载,转移到新克隆的只读备租户上了。
对于“应用版本升级”,在版本发布前预发验证时就可以基于生产租户快速克隆出一个预发测试租户,用预发测试租户进行发版前最后的预发验证。
通常版本发布的第一个步骤是备份数据库,在 4.3 版本,就可以调整为基于生产租户快速克隆出一个小规格的临时备份租户。 假如非常不幸,版本发布出现问题,那么便可以用新克隆出来的临时备份租户再克隆出一个新的生产租户,从而实现数据库的快速恢复。因为克隆操作非常快,所以租户克隆技术可以最大限度地减少版本发布的时间。
单个租户可以克隆出多个不同规格的租户,这些租户也可以应用在不同场景中。
使用租户克隆
如何通过租户克隆快速创建一个租户。
- 以 MySQL 模式为例进行说明。
- 所使用的租户及数据库都已预建完成,不需要手动创建,可直接使用对应连接串连接。
- 所使用的租户未设置密码,只供体验使用,在实际环境中,请根据需要配置相关用户密码。
操作步骤
登录用户租户
obclient -h127.0.0.1 -P2881 -uroot@mysql_tenant -A
创建测试数据库
obclient> create database testdb;
创建测试表
obclient> use testdb
obclient> create table test(id int, code1 varchar(10),code2 varchar(10));
插入数据
obclient> insert into test values(1,'apple','a');
obclient> insert into test values(2,'banana','b');
obclient> insert into test values(3,'carambola','c');
退出数据库,创建备份目录
退出数据库
obclient> exit;
创建备份目录
mkdir backup
在 OBserver 节点上,通过本地 Unix Socket 连接集群的 MySQL 租户。
obclient -S /home/admin/oceanbase/observer/run/sql.sock -uroot@mysql_tenant
配置数据库可以访问的路径 /root/backup
obclient> SET GLOBAL secure_file_priv = "/root/backup";
退出后重新用用户租户的租户管理员登录到数据库
obclient> exit;
obclient -h127.0.0.1 -P2881 -uroot@mysql_tenant -A
配置本租户的归档目的端
obclient> ALTER SYSTEM SET LOG_ARCHIVE_DEST='LOCATION=file:///root/backup';
开启归档模式
obclient> ALTER SYSTEM ARCHIVELOG;
查看归档进度
obclient> SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG\G
返回结果如下:
obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG\G
*************************** 1. row ***************************
DEST_ID: 1001
ROUND_ID: 1
INCARNATION: 1
DEST_NO: 0
STATUS: BEGINNING
START_SCN: 1753085421591366000
START_SCN_DISPLAY: 2025-07-21 16:10:21.591366
CHECKPOINT_SCN: 1753085421591366000
CHECKPOINT_SCN_DISPLAY: 2025-07-21 16:10:21.591366
COMPATIBLE: 1
BASE_PIECE_ID: 1
USED_PIECE_ID: 1
PIECE_SWITCH_INTERVAL: 86400000000
UNIT_SIZE: 1
COMPRESSION: none
INPUT_BYTES: 0
INPUT_BYTES_DISPLAY: 0.00MB
OUTPUT_BYTES: 0
OUTPUT_BYTES_DISPLAY: 0.00MB
COMPRESSION_RATIO: 0.00
DELETED_INPUT_BYTES: 0
DELETED_INPUT_BYTES_DISPLAY: 0.00MB
DELETED_OUTPUT_BYTES: 0
DELETED_OUTPUT_BYTES_DISPLAY: 0.00MB
COMMENT:
PATH: file:///root/backup
1 row in set (0.015 sec)
查看返回结果中的 STATUS
值,如果该值为 DOING
,则表示正在归档;如果为 BEGINNING
,则等待其状态变为 DOING
。
执行一次转储
obclient> ALTER SYSTEM MINOR FREEZE;
退出用户租户,使用 root 用户登录到集群的 sys 租户
当查看日志归档进度为 DOING
,则登录 SYS 租户,进行租户克隆。
obclient> exit;
obclient -h127.0.0.1 -P2881 -uroot@sys -A -Doceanbase
创建克隆租户的 Unit
obclient> CREATE RESOURCE UNIT clone_unit_config
MEMORY_SIZE = '2G',
MAX_CPU = 1, MIN_CPU = 1,
LOG_DISK_SIZE = '6G',
MAX_IOPS = 10000, MIN_IOPS = 10000, IOPS_WEIGHT=1;
克隆租户
obclient> CREATE TENANT clone_mysql001 FROM mysql_tenant
WITH
RESOURCE_POOL = clone_tnt_pool,
UNIT= clone_unit_config;
问题处理
创建租户提示ERROR 4179 (HY000): log archive is not ready
问题描述
obclient [oceanbase]> CREATE TENANT clone_mysql001 FROM mysql_tenant
-> WITH
-> RESOURCE_POOL = clone_tnt_pool,
-> UNIT= clone_unit_config;
ERROR 4179 (HY000): log archive is not ready, create tenant snapshot not allowed
分析过程
查看归档进度
obclient> SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG\G
返回结果如下:
obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG\G
*************************** 1. row ***************************
DEST_ID: 1001
ROUND_ID: 1
INCARNATION: 1
DEST_NO: 0
STATUS: BEGINNING
START_SCN: 1753085421591366000
START_SCN_DISPLAY: 2025-07-21 16:10:21.591366
CHECKPOINT_SCN: 1753085421591366000
CHECKPOINT_SCN_DISPLAY: 2025-07-21 16:10:21.591366
COMPATIBLE: 1
BASE_PIECE_ID: 1
USED_PIECE_ID: 1
PIECE_SWITCH_INTERVAL: 86400000000
UNIT_SIZE: 1
COMPRESSION: none
INPUT_BYTES: 0
INPUT_BYTES_DISPLAY: 0.00MB
OUTPUT_BYTES: 0
OUTPUT_BYTES_DISPLAY: 0.00MB
COMPRESSION_RATIO: 0.00
DELETED_INPUT_BYTES: 0
DELETED_INPUT_BYTES_DISPLAY: 0.00MB
DELETED_OUTPUT_BYTES: 0
DELETED_OUTPUT_BYTES_DISPLAY: 0.00MB
COMMENT:
PATH: file:///root/backup
1 row in set (0.015 sec)
查看返回结果中的 STATUS
值,如果该值为 DOING
,则表示正在归档;如果为 BEGINNING
,则等待其状态变为 DOING
。只有STATUS
值等于DOING才能成功创建租户,但是如何手动干预归档,加速BEGINNING变成DOING 暂未找到办法,知晓者可文后留言,感谢。
解决办法
暂无
查看克隆任务状态
obclient [oceanbase]> SELECT * FROM oceanbase.DBA_OB_CLONE_HISTORY\G
返回结果如下:
*************************** 1. row ***************************
CLONE_JOB_ID: 1748484908440725000
TRACE_ID: YB427F000001-0006363CC63E5180-0-0
SOURCE_TENANT_ID: 1002
SOURCE_TENANT_NAME: mysql_tenant
CLONE_TENANT_ID: 1004
CLONE_TENANT_NAME: clone_mysql001
TENANT_SNAPSHOT_ID: 1748484908520451001
TENANT_SNAPSHOT_NAME: _inner_snapshot$1748484908520451000
RESOURCE_POOL_ID: 1004
RESOURCE_POOL_NAME: clone_tnt_pool
UNIT_CONFIG_NAME: clone_unit_config
RESTORE_SCN: 1748484969576788000
STATUS: CLONE_SYS_SUCCESS
CLONE_JOB_TYPE: FORK
CLONE_START_TIME: 2025-05-29 10:15:08.445651
CLONE_FINISHED_TIME: 2025-05-29 10:17:00.888983
RET_CODE: 0
ERROR_MESSAGE: NULL
1 row in set
执行 exit
退出当前租户.
对比源租户与克隆的租户内容
查看源租户的表及数据
登录源租户
obclient -h127.0.0.1 -P2881 -uroot@mysql_tenant -A -Dtestdb
查看数据库内的表
obclient [testdb]> SHOW TABLES;
查看表内数据
obclient [testdb]> SELECT * FROM test;
返回结果如下:
+------+-----------+-------+
| id | code1 | code2 |
+------+-----------+-------+
| 1 | apple | a |
| 2 | banana | b |
| 3 | carambola | c |
+------+-----------+-------+
执行 exit
退出当前租户。
查看克隆的租户的表及数据
登录克隆的租户
obclient -h127.0.0.1 -P2881 -uroot@clone_mysql001 -A -Dtestdb
查看数据库内的表
obclient [testdb]> SHOW TABLES;
查看表内数据
obclient [testdb]> SELECT * FROM test;
返回结果如下:
+------+-----------+-------+
| id | code1 | code2 |
+------+-----------+-------+
| 1 | apple | a |
| 2 | banana | b |
| 3 | carambola | c |
+------+-----------+-------+
通过对比源租户及克隆后的新租户,两者之间的表及数据都完全一致。