一、创建oceanbase租户
oceanbase创建好后,会默认自动创建一个sys租户,该租户拥有数据库所有权限。默认租户 sys 的架构是 1-1-1,每个ZONE里的资源单元大小默认是5Cpu 20G内存(创建时做了限制的则以实际限制为准)。
系统租户(sys)有一个内置的集群管理员用户 root。OceanBase 数据库的集群管理员为安装 OceanBase 数据库时自动创建,其主要负责本集群内数据库的安装和升级、租户的创建、资源的分配、数据的导入导出,以及集群中数据的备份和恢复等。
实际工作中,为了安全和资源限制等方面的考虑,可以创建其它租户。
创建租户分为三步:
1)创建资源单元规格。如果有合适的规格可以复用,就不用创建了。
CREATE resource unit rs1 max_cpu=4, min_cpu=2, max_memory='4G', min_memory='2G', max_iops=10000, min_iops=1000, max_session_num=1000000, max_disk_size='1024G';
CREATE resource unit rs2 max_cpu=3, min_cpu=3, max_memory='3G', min_memory='3G', max_iops=10000, min_iops=1000, max_session_num=1000000, max_disk_size='1024G';
注:运维人员先定义几个不同的资源规格。每个规格代表了一定的资源(包括CPU、Mem、Disk、session、IOPS)。实际上目前版本只能对CPU和Mem资源进行限制,其它的设置了也不会生效。
2)创建资源池。可以每个 zone 一个资源池,使用独立的资源单元规格,也可以所有 zone 使用同一个资源单元规格,都在一个资源池下(不指定ZONE_LIST即为对所有zone生效)。
create resource pool p1 unit='rs1' , unit_num=1, zone_list=('zone1' ,'zone2') ;
create resource pool p2 unit='rs2' , unit_num=1, zone_list=('zone3') ;
或所有zone使用同一个资源单元规格
create resource pool p1 unit='rs1' , unit_num=1;
遇到的问题:
MySQL [oceanbase]> create resource pool p1 unit='rs1' , unit_num=1;
ERROR 4624 (HY000): machine resource 'zone1' is not enough to hold a new unit
原因:zone1上剩余可用资源不足。查看zone1资源使用情况:
MySQL [oceanbase]> select a.zone,concat(a.svr_ip,':',a.svr_port) observer,
cpu_total,
cpu_assigned,
(cpu_total-cpu_assigned) cpu_free,
mem_total/1024/1024/1024 mem_total_gb,
mem_assigned/1024/1024/1024 mem_assign_gb,
(mem_total-mem_assigned)/1024/1024/1024 mem_free_gb
from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port)
order by a.zone, a.svr_ip;
+-------+--------------------+-----------+--------------+----------+----------------+----------------+----------------+
| zone | observer | cpu_total | cpu_assigned | cpu_free | mem_total_gb | mem_assign_gb | mem_free_gb |
+-------+--------------------+-----------+--------------+----------+----------------+----------------+----------------+
| zone1 | 192.168.18.28:2882 | 14 | 2.5 | 11.5 | 5.000000000000 | 1.250000000000 | 3.750000000000 |
+-------+--------------------+-----------+--------------+----------+----------------+----------------+----------------+
可见mem_free_gb只剩下3.75GB,而resource rs1中设置的max_memory='4G'无法满足其需求。
解决方法:
修改rs1的max_memory为3GB
alter resource unit rs1 max_memory='3G';
--查询所有单元规格(unit)配置
MySQL [oceanbase]> select name,max_cpu,min_cpu,max_memory,min_memory,max_iops,max_disk_size,max_session_num from __all_unit_config;
+-----------------+---------+---------+------------+------------+----------+---------------+---------------------+
| name | max_cpu | min_cpu | max_memory | min_memory | max_iops | max_disk_size | max_session_num |
+-----------------+---------+---------+------------+------------+----------+---------------+---------------------+
| sys_unit_config | 5 | 2.5 | 1610612736 | 1342177280 | 10000 | 53687091200 | 9223372036854775807 |
| rs1 | 4 | 2 | 3221225472 | 2147483648 | 10000 | 1099511627776 | 1000000 |
+-----------------+---------+---------+------------+------------+----------+---------------+---------------------+
2 rows in set (0.004 sec)
--查资源池分配情况:
select t1.name resource_pool_name,
t2.`name` unit_config_name,
t2.max_cpu, t2.min_cpu,
t2.max_memory/1024/1024/1024 max_mem_gb,
t2.min_memory/1024/1024/1024 min_mem_gb,
t3.unit_id,
t3.zone,
concat(t3.svr_ip,':',t3.`svr_port`) observer,
t4.tenant_id,
t4.tenant_name
from __all_resource_pool t1 join __all_unit_config t2 on (t1.unit_config_id=t2.unit_config_id)
join __all_unit t3 on (t1.`resource_pool_id` = t3.`resource_pool_id`)
left join __all_tenant t4 on (t1.tenant_id=t4.tenant_id)
order by t1.`resource_pool_id`, t2.`unit_config_id`, t3.unit_id;
--查服务器资源使用情况
select a.zone,concat(a.svr_ip,':',a.svr_port) observer,
cpu_total,
cpu_assigned,
(cpu_total-cpu_assigned) cpu_free,
mem_total/1024/1024/1024 mem_total_gb,
mem_assigned/1024/1024/1024 mem_assign_gb,
(mem_total-mem_assigned)/1024/1024/1024 mem_free_gb
from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port)
order by a.zone, a.svr_ip;
--更改资源池中的unit
alter resource pool p1 unit = 'rs2';
3)创建租户(TENANT),关联到这个资源池。
create tenant if not exists obmysql resource_pool_list=('p1','p2'), primary_zone='RANDOM',comment 'mysql tenant/instance', charset='utf8mb4' set ob_tcp_invited_nodes='%' ;
或
CREATE TENANT IF NOT EXISTS test_tenant CHARSET='utf8mb4',ZONE_LIST=('zone1','zone2','zone3'), PRIMARY_ZONE='zone1;zone2,zone3', RESOURCE_POOL_LIST=('pool1') SET ob_tcp_invited_nodes='%' ;
注:
1)参数ob_tcp_invited_nodes='%' 是指允许所有客户端访问。对于 MySQL 模式,可选字符集有:utf8mb4, binary, gbk, gb18030。缺省为utf8mb4。
2)Zone List和primary_zone中的列表写法,使用逗号,则逗号两侧优先级相同,使用分号,则分号左侧优先级高于右侧。此处PRIMARY_ZONE='zone1;zone2,zone3'则表示优先将主副本分配至zone1中,减少跨Zone及跨服务器的操作。
--查询数据库中的租户
MySQL [oceanbase]> select * from gv$tenant;
--查询集群名称
MySQL [oceanbase]> show parameters like 'cluster';
二、租户的登录方法:
OceanBase 开源版的租户只兼容 MySQL ,连接协议兼容 MySQL 5.6 。因此 MySQL 命令行客户端或者图形化工具理论上也是能连接 OceanBase 的租户。此外,OceanBase 也提供专属的命令行客户端工具 OBCLIENT 和图形化客户端工具 ODC。
租户创建好后,会自动为其创建一个密码为空的sys用户
obclient -h 192.168.18.28 -P2883 -uroot@obmysql#obcluster1 -c -A oceanbase
主要参数说明:
-h:OBProxy服务器地址或observer地址
-u:提供租户的连接账户,格式有两种:用户名@租户名#集群名 或者 集群名:租户名:用户名 。MySQL 租户的管理员用户名默认是 root。
-P:端口号
-c:表示在 MySQL 运行环境中不要忽略注释。如果使用MySQL的客户端执行带Hint的SQL语句,需要使用-c选项登陆,否则MySQL客户端会将Hint作为注释从用户SQL中去除,导致系统无法收到用户Hint。
-A:表示在 MySQL 连接数据库时不自动获取统计信息
三、租户中创建其它用户
OceanBase 数据库中的用户分为两类:系统租户下的用户和普通租户下的用户。系统租户与普通租户都属于 MySQL 租户。创建用户时,如果当前会话的租户为系统租户,则新建的用户为系统租户用户,否则为普通租户下的用户。不同租户之间的用户权限相互独立。
关于租户的权限,请参考官方文档:https://open.oceanbase.com/docs/observer-cn/V3.1.2/10000000000014754
使用root登录到租户后,创建用户的方法和mysql相同:
obclient -h 192.168.18.28 -P2883 -uroot@obmysql#obcluster1 -p -c -A oceanbase
MySQL [oceanbase]> create user if not exists cqiwen@'%' identified by 'cqiwen';
Query OK, 0 rows affected (0.128 sec)
MySQL [oceanbase]> create database scoot;
Query OK, 1 row affected (0.086 sec)
MySQL [oceanbase]> grant all on scoot.* to cqiwen@'%';
Query OK, 0 rows affected (0.078 sec)
使用新创建的用户登录obmysql租户:
obclient -h 192.168.18.28 -P2883 -ucqiwen@obmysql#obcluster1 -p -c -A scoot
测试创建表、向表中插入数据:
MySQL [scoot]> create table t1(id int not null auto_increment,name varchar(20),ctime datetime default now());
Query OK, 0 rows affected (0.275 sec)
MySQL [scoot]> insert into t1(name) values('maomao');
Query OK, 1 row affected (0.072 sec)
MySQL [scoot]> select * from t1;
+----+--------+---------------------+
| id | name | ctime |
+----+--------+---------------------+
| 1 | maomao | 2022-03-01 11:15:05 |
+----+--------+---------------------+
1 row in set (0.005 sec)
四、删除租户
删除租户后,租户下的数据库和表也同时被删除。但是租户使用的资源配置不会被删除。资源配置可以继续给其他租户使用。
注意:只有系统管理员(sys 租户的 root 用户)才能执行 DROP TENANT 命令:
DROP TENANT tenant_name [FORCE]
或者
DROP TENANT tenant_name PURGE; --使用purge后不会进入回收站
obclient -h 192.168.18.28 -P2883 -uroot@sys -p -c -A
MySQL [(none)]> drop tenant obmysql force;
Query OK, 0 rows affected (0.116 sec)
MySQL [(none)]> select * from oceanbase.gv$tenant;
+-----------+-------------+-----------+--------------+----------------+---------------+-----------+---------------+
| tenant_id | tenant_name | zone_list | primary_zone | collation_type | info | read_only | locality |
+-----------+-------------+-----------+--------------+----------------+---------------+-----------+---------------+
| 1 | sys | zone1 | zone1 | 0 | system tenant | 0 | FULL{1}@zone1 |
+-----------+-------------+-----------+--------------+----------------+---------------+-----------+---------------+
1 row in set (0.001 sec)
五、删除资源单元
删除资源单元前必须确保当前资源单元未被租户使用。如果资源单元正在被租户使用,则需要先将资源单元从资源池中移出后再删除资源单元。
假设待删除的资源单元为 unit1 , unit1 被指定给了资源池 pool1 ,如果要移除资源单元unit1 ,则:
方案1)如果pool1还要继续使用,则需要先创建资源单元 unit2 ,并将 unit2 指定给 pool1 后,再删除 unit1;
obclient> CREATE RESOURCE UNIT unit2 MAX_CPU 4, MAX_MEMORY '5G', MAX_IOPS 128,MAX_DISK_SIZE '10G', MAX_SESSION_NUM 64, MIN_CPU=4, MIN_MEMORY= '5G', MIN_IOPS=128;
obclient> ALTER RESOURCE POOL pool1 UNIT='unit2';
obclient> DROP RESOURCE UNIT unit1;
方案2)如果pool1不再继续使用,则需要先删除pool1,再删除 unit1。
obclient> DROP RESOURCE pool pool1;
obclient> DROP RESOURCE UNIT unit1;
六、为租户添加zone
思路:可以通过在资源池中增加zone的方法,或者为租户添加资源池的方法(新加的资源池包含新的zone).
以下方法是直接在资源池中增加zone,然后租户上进行更新:
MySQL [oceanbase]> select * from gv$tenant;
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| tenant_id | tenant_name | zone_list | primary_zone | collation_type | info | read_only | locality |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| 1 | sys | zone1;zone2;zone3 | zone1;zone2,zone3 | 0 | system tenant | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
| 1002 | obmysql | zone1;zone2 | zone1,zone2 | 0 | mysql tenant/instance | 0 | FULL{1}@zone1, FULL{1}@zone2 |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
2 rows in set (0.001 sec)
当前obmysql只使用了zone1,zone2,查看其对应的resource pool,也只有2个zone:
MySQL [oceanbase]> select * from __all_resource_pool;
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
| resource_pool_id | name | unit_count | unit_config_id | zone_list | tenant_id | replica_type | is_tenant_sys_pool |
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
| 1 | sys_pool | 1 | 1 | zone1;zone2;zone3 | 1 | 0 | 0 |
| 1003 | pool1 | 1 | 1002 | zone1;zone2 | 1002 | 0 | 0 |
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
2 rows in set (0.006 sec)
向resource pool中添加zone3:
MySQL [oceanbase]> alter resource pool pool1 zone_list=('zone1' ,'zone2','zone3');
Query OK, 0 rows affected (0.851 sec)
MySQL [oceanbase]> select * from __all_resource_pool;
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
| resource_pool_id | name | unit_count | unit_config_id | zone_list | tenant_id | replica_type | is_tenant_sys_pool |
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
| 1 | sys_pool | 1 | 1 | zone1;zone2;zone3 | 1 | 0 | 0 |
| 1003 | pool1 | 1 | 1002 | zone1;zone2;zone3 | 1002 | 0 | 0 |
+------------------+----------+------------+----------------+-------------------+-----------+--------------+--------------------+
2 rows in set (0.014 sec)
MySQL [oceanbase]> select * from gv$tenant;
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| tenant_id | tenant_name | zone_list | primary_zone | collation_type | info | read_only | locality |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| 1 | sys | zone1;zone2;zone3 | zone1;zone2,zone3 | 0 | system tenant | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
| 1002 | obmysql | zone1;zone2 | zone1,zone2 | 0 | mysql tenant/instance | 0 | FULL{1}@zone1, FULL{1}@zone2 |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
2 rows in set (0.001 sec)
但租户上还没有更新zone_list和primary_zone,对其进行更新:
MySQL [oceanbase]> ALTER TENANT obmysql locality='F@zone1,F@zone2,F@zone3';
Query OK, 0 rows affected (0.488 sec)
MySQL [oceanbase]> select * from gv$tenant;
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| tenant_id | tenant_name | zone_list | primary_zone | collation_type | info | read_only | locality |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| 1 | sys | zone1;zone2;zone3 | zone1;zone2,zone3 | 0 | system tenant | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
| 1002 | obmysql | zone1;zone2;zone3 | zone1,zone2;zone3 | 0 | mysql tenant/instance | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
2 rows in set (0.001 sec)
更改primary zone为三个zone负载均衡:
MySQL [oceanbase]> ALTER TENANT obmysql primary_zone='zone1,zone2,zone3';
Query OK, 0 rows affected (0.330 sec)
MySQL [oceanbase]> select * from gv$tenant;
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| tenant_id | tenant_name | zone_list | primary_zone | collation_type | info | read_only | locality |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
| 1 | sys | zone1;zone2;zone3 | zone1;zone2,zone3 | 0 | system tenant | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
| 1002 | obmysql | zone1;zone2;zone3 | zone1,zone2,zone3 | 0 | mysql tenant/instance | 0 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 |
+-----------+-------------+-------------------+-------------------+----------------+-----------------------+-----------+---------------------------------------------+
2 rows in set (0.392 sec)
七、重置普通租户的root密码:
一不小心,把普通租户root的密码给搞忘了,除了通过白屏ocp修改之外,黑屏的修改方法为:通过sys租户登录到ob数据库,通过change tenant进行密码重置。
MySQL [oceanbase]> alter system change tenant obmysql;
Query OK, 0 rows affected (0.001 sec)
MySQL [oceanbase]> select user_name,passwd from __all_user;
+------------+-------------------------------------------+
| user_name | passwd |
+------------+-------------------------------------------+
| root | *9753e2cf9d2dcd5e13c052f581c310ac70c62723 |
| ORAAUDITOR | *9753e2cf9d2dcd5e13c052f581c310ac70c62723 |
+------------+-------------------------------------------+
2 rows in set (0.006 sec)
MySQL [oceanbase]> update __all_user set passwd='' where user_name='root';
Query OK, 1 row affected (0.024 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MySQL [oceanbase]> select user_name,passwd from __all_user;
+------------+-------------------------------------------+
| user_name | passwd |
+------------+-------------------------------------------+
| root | |
| ORAAUDITOR | *9753e2cf9d2dcd5e13c052f581c310ac70c62723 |
+------------+-------------------------------------------+
2 rows in set (0.004 sec)
[admin@master log]$ obclient -h127.0.0.1 -P2883 -uroot@obmysql -p -A -c
Enter password: <直接回车,密码为空>
Welcome to the OceanBase. Commands end with ; or \g.
Your MySQL connection id is 104
Server version: 5.6.25 OceanBase 3.1.2 (r10000392021123010-d4ace121deae5b81d8f0b40afbc4c02705b7fc1d) (Built Dec 30 2021 02:47:29)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>