OceanBase 2.2初体验

屠华辉
2023-12-01

OceanBase是蚂蚁金服自研的分布式关系数据库,2019年国庆期间以6088万tpmC值的成绩,超越Oracle荣登TPC-C基准测试性能榜首。最近因为一些原因赶了趟时髦,体验了一把OceanBase,这年头不搞个什么云,大数据,人工智能,…都不好意思说自己是搞IT的,不会点python,都不敢说自己会编程…

Oceanbase在0.4版本前是开源的,1.0版本后不再开源,目前可以在官网(https://oceanbase.alipay.com/)免费下载到2.2版本的试用版,本文是基于2.2版本的,但不涉及他们的OceanBase运维平台/云平台(OceanBase Cloud Platform - OCP)。

OceanBase(下文简称OB)的安装部署还是很简单的,主要的难点是OB对硬件要求是很高的(特别是内存方面, 如果没有闲置的机器, 这个是真的难),如果你只有一台8G,16G的机器,想把集群跑起来,那劝你还是放弃吧,OB不是那种低端的数据库… 安装部署另一个难点是缺少文档, 官网上的文档太少了, 过于简单(相对于Oracle/MySQL接近于简陋), 虽然步骤简单, 但如果报错, 很难找到解决方法.

部署模式使用的是三副本部署, 这也是最小规模的OceanBase集群, 因为没有足够的硬件设备, 我是部署在KVM虚拟机上的, 每个zone一个虚拟机, 操作系统需要的是RHEL/CentOS 7+, RHEL/CentOS 6.X版本是跑不起来的。

1. 准备安装环境

基本上根据官方文档<<OceanBase试用版安装指南>>做就行了, 这里有两个要点:

(1). 运行OB Server的虚拟机的内存不能太小, 推荐64G以上, 如果像我一样只是想尝个鲜, 建议每个虚拟机的内存也不要不低于30G, 要不在bootstrap的时候极可能过不了。如果没这么大的内存也不用太担心, 虚拟机的内存时可以"超分"的,在宿主机看来, 虚拟机只是个进程,KVM分配的内存(对应VSZ), 而不是实际使用的物理内存(RSS)可以, 所以宿主机最好配置一个大的交换区, 虽然可能性能不好,但至少可以让你跑起来, 像我的环境, 一台淘汰的System x3650 M3, 12核, 24线程, 64G的物理内存。3个虚拟机,每个虚拟机设置12CPU, 50G内存。

(2). 必须配置NTP, 且必须确保NTP工作正常(每个节点时间是同步的).

1.1. 创建KVM虚拟机

可以先做好一个虚拟机, 后面通过拷贝导入(–import)就可以快速搭建好剩下的两台虚拟机, 这里每个虚拟机配置了两块网卡:
一个对应桥接网卡, 用于对外通讯(192.168.203.);
一个对应一个虚拟网络(isolated network),用于OB Server之间的内部通讯(192.168.55.
)。

注意,这里我遇到一个坑, KVM虚拟机配置的CPUs选项要勾选"Copy host CPU configuration", 否者会报

"Apr 20 17:50:24 localhost kernel: traps: ob_admin[1966] trap invalid opcode ip:768793c sp:7fc9af6c3c40 error:0 in ob_admin[400000+ab1b000]"。

因为KVM默认不会在虚拟机上启用所有的CPU的指令集, 这将导致observer的程序因为缺少指令集而core掉,无法运行。

创建虚拟机参考:

# virt-install \
  --virt-type kvm \
  --name "oceanbase01" \
  --ram 51200 \
  --vcpus=12,maxvcpus=12 \
  --cdrom /mnt/sw/rhel7.7.iso
  --disk path=/kvm/images/oceanbase01-disk01.qcow2,format=qcow2,size=120,bus=virtio,sparse=yes \ #单位为GB
  --network bridge=br0,model=virtio \
  --network network:private1,model=virtio \
  --graphics vnc,listen=0.0.0.0,port=5901 \
  --boot hd \
  --noautoconsole \

创建3个虚拟机,配置主机名和IP地址:

oceanbase01 : eth1 - 192.168.55.10 / eth0 - 192.168.203.114
oceanbase02 : eth1 - 192.168.55.20 / eth0 - 192.168.203.115
oceanbase03 : eth1 - 192.168.55.30 / eth0 - 192.168.203.116

1.2. 安装依赖软件包

根据oceanbase安装需要的软件包,建议配置网络配个yum仓库, 如果仅安装oceanbase和obproxy, 不需要安装JDK 8+(mariadb应该也是不用的,但会用到客户端,如果不安装obclient)。

# yum install lsof mariadb  mariadb-libs mariadb-devel net-tools ntp ntpdate python python-devel python-setuptools rsync expat expect gcc gcc-c++ glibc libgcc libaio libcurl openssl-libs openldap

1.3. 创建oceanbase用户

# groupadd admin
# useradd -g admin admin

1.4. 配置pam_limits

注意: Linux用户登录时默认是不加载pam_limits.so, limits配置文件是不会加载的。

# vi /etc/pam.d/login
# 添加pam_limits.so
session    required     pam_limits.so

根据oceanbase文档要求创建资源限制配置

# vi /etc/security/limits.d/99-oceanbase.conf 
*               soft    nofile  655350
*               hard    nofile  655350
*               soft    stack   20480
*               hard    stack   20480
*               soft    nproc   655350
*               hard    nproc   655350
*               soft    core    unlimited
*               hard    core    unlimited

登录admin用户检查是否生效(如果还没生效, 很可能是因为你是复制粘贴网页的, 里面的字符集有问题, 可以通过journalctl检查下是否有报错)。

[admin@oceanbase01 ~]$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 97360
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 655350
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 20480
cpu time               (seconds, -t) unlimited
max user processes              (-u) 655350
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

学习环境可以不开core文件限制, 生成基本也没用, 还占空间,除非淘宝的工程师。因为observer编译没带调试信息(应该是和程序分开了), gdb看到调用堆栈都是???, 没什么有用信息。

1.5. 配置内核参数

# vi /etc/sysctl.conf
# for oceanbase
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

net.ipv4.ip_local_port_range = 3500 65535
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_slow_start_after_idle=0

vm.swappiness = 0
kernel.core_pattern = /data/1/core-%e-%p-%t 
vm.min_free_kbytes = 524288 #官方文档预留的内存太多了,学习环境可以调小一些。

1.6. 修改内核异步I/O限制

# echo 65536 > /proc/sys/fs/aio-max-nr

1.7 关闭防火墙和SELinux

(1). 关闭防火墙

# systemctl disable firewalld  
# systemctl stop firewalld
# systemctl status firewalld

(2). 关闭SELinux

# vi /etc/selinux/config 
SELINUX=disabled

# setenforce 0
# sestatus 
SELinux status:                 disabled 

1.8. NTP时钟同步

(1). 服务器端配置

使用KVM宿主机作为时钟源(192.168.55.1)

# cat /etc/ntp.conf
driftfile /var/lib/ntp/drift

restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1 
restrict ::1

restrict 192.168.55.0 mask 255.255.255.0 nomodify notrap # 允许192.168.55网段

server 127.127.1.0
fudge  127.127.1.0 stratum 10

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

# systemctl enable ntpd
# systemctl start ntpd
# systemctl status ntpd

(2). 客户端配置

为每个虚拟机配置:

# cat /etc/ntp.conf
driftfile /var/lib/ntp/drift

restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1 
restrict ::1

server 192.168.55.1 iburst  

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

# systemctl enable ntpd
# systemctl start ntpd
# systemctl status ntpd

注意:配置完成启动后可能需要5-10分钟后才能成功连接和同步。在执行bootstrap之前一定要先确保时钟已经同步(synchronised)。

# ntpstat 
synchronised to NTP server (192.168.55.1) at stratum 12
   time correct to within 20 ms
   polling server every 128 s

# ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.55.1    LOCAL(0)        11 u   94  128  377    0.150    0.374   0.158

至此, 已经完成环境准备。

2. 安装/配置OB

2.1. 安装启动

下载的试用版提供的OB安装包是rpm格式,安装非常简单,上传,直接安装即可。

# yum install ./oceanbase-2.2.30-1855102.el7.x86_64.rpm

OB运行需要一些目录结构, 按照官方文档来就好,OB第一次启动需要提供参数。后续集群的自举和初始化会可能反复多次(反正我失败了好几次),最好把这些操作做成脚本,提高效率。

说明:
  1). 每个OB Server的参数是有不同的,需要根据实际情况修改;
  2). 脚本是root用户执行的;
  3). 如果OB所在的主机的内存比较小,没有到达文档要求的64G,那么需要修改默认的内存参数(system_memory和memory_limit)让你的OB集群跑起来的关键:
    memory_limit:
    - 如果不指定memory_limit, 那么OB是根据主机物理内存的百分比进行设置的,如果你的主机内存比较小, 在bootstap时就会失败。
	- 如果指定了memory_limit, 就是根据指定的值, 指定该配置项的意义在于你可以指定超出你实际的物理内存,bootstap也会顺利完成,但是很可能跑着跑着内存越用越多发生oom;
    - 在你主机内存有限的情况下,至少可以bootstap这步能够通过,可以让你连如OB对一些内存相关的参数进行调整。
	- memory_limit也不能太小(至少20G), 我测试设置为20G的时候, bootstrap也是会报错的:
	  "ERROR 1235 (0A000) at line 1: unit min memory less than __min_full_resource_pool_memory not supported"
	- 最好是你的虚拟机内存设置尽可能大。
	
  	system_memory: observer自身预留内存的百分比?,该内存将不能分配给租户。默认20G;
    - 网络上文章说system_memory不能小于10g,对于我用的版本(2.2.30),我配置system_memory为4G是可以正常跑起来的

为保持文章简洁, 所有用到的脚本附在最后,供参考。

2.2. 初始化执行

每个OB服务器执行init_ob.sh.

[root@oceanbase01 oceanbase]# ./init_ob.sh 
该脚本将删除已有(如果有)的oceanbase的配置和数据,是否继续?[YES|y|NO|n]:
y

关闭observer进程 ...
清空observer数据 ...
初始化observer目录结构 ...
启动observer...
/home/admin/oceanbase/bin/observer -i eth1 -p 2881 -P 2882 -n ghob -z zone1 -d /home/admin/oceanbase/store/ghob -l warn -o rootservice_list=192.168.55.10:2882:2881;192.168.55.20:2882:2881;192.168.55.30:2882:2881,system_memor
y=4G,memory_limit=30G,sql_audit_memory_limit=256M,datafile_size=60G,cluster_id=100,config_additional_dir=/data/log1/ghob/etc2;/data/1/ghob/etc3devname: eth1
mysql port: 2881
rpc port: 2882
appname: ghob
zone: zone1
data_dir: /home/admin/oceanbase/store/ghob
log level: warn
optstr: rootservice_list=192.168.55.10:2882:2881;192.168.55.20:2882:2881;192.168.55.30:2882:2881,system_memory=4G,memory_limit=30G,sql_audit_memory_limit=256M,datafile_size=60G,cluster_id=100,config_additional_dir=/data/log1
/ghob/etc2;/data/1/ghob/etc3

等待片刻, 等待每个节点都启动完成,才可以执行下一步。

[root@oceanbase01 oceanbase]# ./check.sh 
检查oceanbase进程...
admin     4481     1 99 Jan01 ?        4-06:31:45 /home/admin/oceanbase/bin/observer -i eth1 -p 2881 -P 2882 -n ghob -z zone1 -d /home/admin/oceanbase/store/ghob -l warn -o rootservice_list=192.168.55.10:2882:2881;192.168.55.20:2882:2881;192.168.55.30:2882:2881,system_memory=4G,memory_limit=34G,sql_audit_memory_limit=256M,datafile_size=60G,cluster_id=100,config_additional_dir=/data/log1/ghob/etc2;/data/1/ghob/etc3
检查oceanbase监听端口...
tcp        0      0 0.0.0.0:2881            0.0.0.0:*               LISTEN      4481/observer       
tcp        0      0 0.0.0.0:2882            0.0.0.0:*               LISTEN      4481/observer       

2.3. 集群自举和初始化

这个步骤类似于Oracle RAC安装过程执行root.sh和之后的dbca建库,OB这步骤为bootstrap, 这步过了, 集群即可用了。

bootstrap只需要在一个OB服务器上执行, 只能执行一次, 如果bootstrap失败,根据报错调整,重复2.1 - 2.2 步骤,直到成功。

我这里做成了脚本bootstrap.sh, 执行前需要确认NTP是同步的, 每个节点都已正常启动。

[root@oceanbase01 oceanbase]# ./bootstrap.sh 
Enter password:

注意, 默认root的密码是空,直接输入回车,如果脚本返回没有报错,即成功。

2.4. 修改参数/配置项(可选)

通过mysql/obclient连入, 可以根据需要设置参数和配置项。

[root@oceanbase01 oceanbase]# mysql -u root -h 127.0.0.1 -P2881 -p

ALTER SYSTEM SET enable_syslog_recycle=true;
ALTER SYSTEM SET max_syslog_file_count=4;

ALTER SYSTEM SET enable_merge_by_turn=false;
ALTER SYSTEM SET minor_freeze_times=100;
ALTER SYSTEM SET freeze_trigger_percentage=70;

ALTER RESOURCE UNIT sys_unit_config min_memory=5368709120;
ALTER RESOURCE UNIT sys_unit_config max_memory=5368709120;
ALTER RESOURCE UNIT sys_unit_config max_cpu=3;

3. OBProxy安装

OBProxy类似于网关, 你只需要将SQL发给OBProxy,他会帮你以最优的方式到集群中获取数据,你可以不需要关系集群的拓扑。安装OBProxy也非常简单。我是部署在KVM宿主机上的。

注意! OBProxy安装之前需要先在OB中创建一个用户,OBProxy应该是通过这个用户获取集群信息的,这个用户名和密码是固定的(代码写死?,没查到有配置项),
但创建用户这步在官方文档上提都没提,折腾了很久...

以下是我的安装步骤:

# cd /u01/mysql/bin
# ./obclient -u root -h 192.168.55.10 -P2881 -p
obclient> create user 'proxyro' IDENTIFIED BY '3u^0kCdpE';
obclient> grant select on oceanbase.* to proxyro IDENTIFIED BY '3u^0kCdpE';

# groupadd admin
# useradd -g admin admin
# yum install obproxy-1.5.7-1850374.el7.x86_64.rpm
# cd /opt/taobao/install/
# ln -s obproxy-1.5.7/ obproxy
# chown -R admin.admin ./obproxy
# su - admin
$ cd /opt/taobao/install/obproxy/
$ ./bin/obproxy -p2883 -r'192.168.55.10:2881;192.168.55.20:2881;192.168.55.30:2881' -o syslog_level=WARN  -c 'ghob' -n obapp
./bin/obproxy -p2883 -r192.168.55.10:2881;192.168.55.20:2881;192.168.55.30:2881 -o syslog_level=WARN -c ghob -n obapp
listen port: 2883
rs list: 192.168.55.10:2881;192.168.55.20:2881;192.168.55.30:2881
optstr: syslog_level=WARN
cluster_name: ghob
appname: obapp

通过客户端连接OBProxy,确认部署成功。

# obclient -h192.168.55.1 -uroot@sys#ghob -P2883 -proot1234 -c -A sys
obclient: [Warning] Using a password on the command line interface can be insecure.
Welcome to the OceanBase monitor.  Commands end with ; or \g.
Your OceanBase connection id is 13
Server version: 5.6.25 OceanBase 2.2.30 (r1855102-84b6e091e26eceeadac680f087494e6d7871bac3) (Built Dec 28 2019 01:29:48)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

obclient> 

注意,连接OBProxy和直接连OB是由区别的:连接observer的时候不能带集群名,只有连接obproxy需要带集群名。

4. 创建租户(Tenant)

OceanBase通过租户实现资源隔离, 你可以认为一个租户就是一个oracle/mysql数据库实例, 一个OB集群中运行了多个租户(oracle/mysql/…数据库实例)。OB集群有一个特殊的租户,就是系统租户,存储了集群的元数据和租户共有部分。

  • OB通过资源池(Resource Pool)来限定租户可以使用的资源(CPU/Memory/IO/Disk/…);
  • 一个租户拥有一个或多个资源池;
  • 一个资源池由具有相同规格(Unit Config)的若干个UNIT(资源单元)组成一个资源池只能属于一个租户;

先通过以下语句获取集群中可用的资源, 分配的资源的最大值不能超过剩余(remaining)的值,否者报错.

select
	zone,
	sum(cpu_total) - sum(cpu_max_assigned) as 'CPU remaining C',
	(sum(mem_total) - sum(mem_max_assigned))/ 1024 / 1024 / 1024 as 'Memory remaining G'
from __all_virtual_server_stat
group by zone;

4.1. 定义资源规格

create resource unit unit_config_01 max_cpu=5, min_cpu=2, max_memory='5G', min_memory='5G', max_iops=10000, min_iops=6000, max_session_num=5000, max_disk_size='30G';

查询: select * from oceanbase.`__all_unit_config`
修改: ALTER RESOURCE UNIT unit_config_01 max_cpu=3;
删除: drop resource unit unit_config_01;

4.2. 创建资源池

create resource pool pool_01 unit=unit_config_01, unit_num=1; 

4.3. 创建租户

只有用root用户连接到sys租户(root@sys)才能执行CREATE TENANT创建租户。连接到指定租户的方法是在用户名中指定,其格式为:用户@租户名#集群,再次说明,如果直连OB,不需要集群名。

注意, Oracle租户是不能直接用mysql客户端连接的,需要用obclient,否者报错:

# mysql -h192.168.203.154 -P2883 -usys@tenant_oracle_1#ghob SYS -A -p
Enter password: 
ERROR 1235 (0A000): Oracle tenant for current client driver is not supported

1). 创建一个MySQL租户

create tenant if not exists tenant_mysql_1 
charset = 'utf8mb4',
resource_pool_list =('pool_01'),
replica_num = 1,
zone_list=('zone1;zone2;zone3'),
primary_zone='RANDOM',
comment 'mysql tenant 1#' 
set ob_tcp_invited_nodes = '%', ob_compatibility_mode = 'mysql';

2). 创建一个Oracle租户

create tenant if not exists tenant_oracle_1 
resource_pool_list =('pool_02'),
replica_num = 1,
zone_list=('zone1;zone2;zone3'),
primary_zone='RANDOM',
comment 'oracle tenant 1#' 
set ob_tcp_invited_nodes = '%', ob_compatibility_mode = 'oracle';

至此, 就可以连接租户, 建库/schema,建用户,建表,…

5. 部署应用(tpcc-mysql)测试

OB的MySQL的兼容性还是不错的,测试tpcc-mysql过程中, 基本不需要做任何修改, 直接就能用。Oracle的兼用性并没有宣传的好,我拿oracle的sample的HR的脚本的语句来跑, 不修改基本都跑不过。

TPCC-MySQL可以安装在任意能连通的机器, 我是用源代码编译安装的, 需要MySQL的库文件(我的环境是安装在/usr/local/mysql/lib), MySQL客户端mysql_config程序必须在$PATH环境变量中。

5.1. Build binaries

# unzip to /usr/local/tpcc-mysql
# export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/mysql/lib
# cd /usr/local/tpcc-mysql/src ; make 

5.2. Load data

#建库和建表
# mysql -u root@tenant_mysql_1#ghob -h192.168.203.154 -P2883 -p
root@192.168.203.154 [(none)]> create database if not exists tpcc default charset utf8mb4 collate utf8_general_ci;
root@192.168.203.154 [(none)]> use tpcc;
root@192.168.203.154 [tpcc]> source /usr/local/tpcc-mysql/create_table.sql 
root@192.168.203.154 [tpcc]> source /usr/local/tpcc-mysql/add_fkey_idx.sql

#创建用户tpcc_user
root@192.168.203.154 [tpcc]> CREATE USER 'tpcc_user'@'%' IDENTIFIED BY 'root1234';
root@192.168.203.154 [tpcc]> GRANT ALL ON tpcc.* TO 'tpcc_user'@'%';
root@192.168.203.154 [tpcc]> SHOW GRANTS FOR tpcc_user;

#装载测试数据
# 避免报"4012, 25000, Transaction is timeout", 修改OB参数。
root@192.168.203.154 [tpcc]> set global ob_query_timeout=1000000000;
root@192.168.203.154 [tpcc]> set global ob_trx_idle_timeout=1200000000;
root@192.168.203.154 [tpcc]> set global ob_trx_timeout=1000000000;
# cd /usr/local/tpcc-mysql/
# ./tpcc_load -h192.168.203.154 -P2883 -d tpcc -u tpcc_user@tenant_mysql_1#ghob  -p "root1234" -w 5

5.3. start benchmark

# ./tpcc_start -h192.168.203.154 -P2883 -d tpcc -u tpcc_user@tenant_mysql_1#ghob -p "root1234" -w 5 -c 6 -r 60 -l 360 -f tpcc_mysql_ob.log
***************************************
*** ###easy### TPC-C Load Generator ***
***************************************
option h with value '192.168.203.154'
option P with value '2883'
option d with value 'tpcc'
option u with value 'tpcc_user@tenant_mysql_1#ghob'
option p with value 'root1234'
option w with value '5'
option c with value '6'
option r with value '60'
option l with value '360'
option f with value 'tpcc_mysql_ob.log'
<Parameters>
     [server]: 192.168.203.154
     [port]: 2883
     [DBname]: tpcc
       [user]: tpcc_user@tenant_mysql_1#ghob
       [pass]: root1234
  [warehouse]: 5
 [connection]: 6
     [rampup]: 60 (sec.)
    [measure]: 360 (sec.)

RAMP-UP TIME.(60 sec.)

MEASURING START.

  10, trx: 87, 95%: 643.499, 99%: 898.462, max_rt: 1139.508, 83|760.359, 9|175.069, 10|1208.298, 9|2900.172
  20, trx: 93, 95%: 565.272, 99%: 602.307, max_rt: 626.478, 96|471.920, 9|132.261, 8|489.537, 10|1855.287
  30, trx: 95, 95%: 517.341, 99%: 562.235, max_rt: 572.280, 95|411.440, 10|28.200, 11|699.581, 9|1836.048
  40, trx: 93, 95%: 466.441, 99%: 508.741, max_rt: 513.065, 94|545.495, 9|37.875, 9|801.999, 10|1907.535
  50, trx: 99, 95%: 557.208, 99%: 764.590, max_rt: 764.861, 100|293.745, 10|28.064, 9|495.630, 9|1807.347
  60, trx: 93, 95%: 546.962, 99%: 817.371, max_rt: 824.722, 94|339.207, 10|49.272, 10|911.153, 10|2261.837
  70, trx: 91, 95%: 579.145, 99%: 790.895, max_rt: 972.483, 88|456.351, 9|34.193, 9|726.047, 9|2284.060
  80, trx: 99, 95%: 467.979, 99%: 601.586, max_rt: 677.787, 102|604.893, 9|37.303, 10|546.463, 10|1867.506
  90, trx: 97, 95%: 481.478, 99%: 605.561, max_rt: 627.143, 96|297.166, 10|225.747, 10|725.926, 10|1755.157
 100, trx: 90, 95%: 629.779, 99%: 683.201, max_rt: 857.083, 90|766.705, 9|40.586, 8|735.763, 9|1914.525
 110, trx: 93, 95%: 655.357, 99%: 1214.537, max_rt: 1485.661, 91|436.557, 9|135.649, 10|1170.694, 8|2140.299
 120, trx: 88, 95%: 625.645, 99%: 961.346, max_rt: 997.529, 90|431.145, 9|29.171, 8|584.504, 10|2288.028
 130, trx: 89, 95%: 543.372, 99%: 703.118, max_rt: 859.035, 90|515.092, 9|50.424, 10|1031.663, 9|2293.454
 140, trx: 98, 95%: 516.877, 99%: 594.070, max_rt: 598.502, 98|393.809, 9|31.823, 10|789.789, 10|1907.105
 150, trx: 97, 95%: 547.946, 99%: 624.149, max_rt: 638.279, 93|518.923, 11|175.149, 9|784.863, 9|1795.820
 160, trx: 94, 95%: 512.409, 99%: 685.454, max_rt: 864.963, 97|378.241, 9|38.124, 9|687.189, 9|1855.132
 170, trx: 91, 95%: 593.359, 99%: 684.839, max_rt: 703.433, 92|344.992, 9|32.331, 9|555.482, 10|1838.396
 180, trx: 95, 95%: 677.093, 99%: 934.673, max_rt: 982.723, 92|529.508, 9|39.388, 10|1156.036, 9|1847.924
 190, trx: 89, 95%: 622.656, 99%: 844.480, max_rt: 1262.023, 92|543.264, 10|32.366, 9|998.262, 9|2639.389
 200, trx: 98, 95%: 498.192, 99%: 548.274, max_rt: 552.178, 95|506.290, 9|27.955, 10|818.900, 9|2077.615
 210, trx: 95, 95%: 486.695, 99%: 535.941, max_rt: 559.454, 98|515.572, 10|41.039, 9|831.173, 11|1829.129
 220, trx: 90, 95%: 605.017, 99%: 1008.510, max_rt: 1071.358, 92|509.577, 9|29.999, 10|967.728, 9|2251.865
 230, trx: 92, 95%: 524.828, 99%: 875.103, max_rt: 912.630, 91|829.435, 9|29.228, 9|492.051, 9|2133.734
 240, trx: 97, 95%: 578.626, 99%: 824.250, max_rt: 1103.394, 94|434.274, 9|44.936, 10|715.093, 9|2250.188
 250, trx: 91, 95%: 620.052, 99%: 777.283, max_rt: 806.387, 88|813.520, 9|30.873, 8|743.692, 9|2324.576
 260, trx: 97, 95%: 480.902, 99%: 580.534, max_rt: 607.764, 100|423.358, 11|40.653, 10|519.725, 9|1858.249
 270, trx: 102, 95%: 449.714, 99%: 549.588, max_rt: 599.280, 104|312.553, 9|27.796, 10|557.505, 10|2000.499
 280, trx: 82, 95%: 812.006, 99%: 1297.989, max_rt: 1522.554, 79|678.561, 8|30.634, 9|1217.812, 9|2130.190
 290, trx: 96, 95%: 532.264, 99%: 682.383, max_rt: 748.621, 96|369.589, 11|26.809, 9|654.635, 10|1876.904
 300, trx: 90, 95%: 639.850, 99%: 870.141, max_rt: 956.221, 91|461.084, 8|28.465, 8|587.885, 9|2449.306
 310, trx: 94, 95%: 536.905, 99%: 1126.965, max_rt: 1218.487, 94|871.759, 10|48.911, 11|697.707, 9|2150.458
 320, trx: 97, 95%: 501.184, 99%: 572.595, max_rt: 622.648, 99|415.710, 9|32.035, 9|687.813, 10|1802.564
 330, trx: 97, 95%: 467.419, 99%: 569.689, max_rt: 600.547, 95|622.937, 10|30.872, 10|726.256, 10|1848.349
 340, trx: 98, 95%: 520.915, 99%: 616.535, max_rt: 936.423, 100|399.368, 10|26.508, 9|666.657, 10|1824.047
 350, trx: 86, 95%: 674.060, 99%: 958.186, max_rt: 1096.451, 85|714.003, 8|536.682, 9|716.807, 8|2298.966
 360, trx: 96, 95%: 577.933, 99%: 935.793, max_rt: 1055.003, 95|402.823, 10|32.665, 10|684.716, 9|2438.963

STOPPING THREADS......

<Raw Results>
  [0] sc:0 lt:3369  rt:0  fl:0 avg_rt: 363.7 (5)
  [1] sc:0 lt:3369  rt:0  fl:0 avg_rt: 125.8 (5)
  [2] sc:0 lt:337  rt:0  fl:0 avg_rt: 30.6 (5)
  [3] sc:0 lt:338  rt:0  fl:0 avg_rt: 591.4 (80)
  [4] sc:0 lt:337  rt:0  fl:0 avg_rt: 1963.1 (20)
 in 360 sec.

<Raw Results2(sum ver.)>
  [0] sc:0  lt:3369  rt:0  fl:0 
  [1] sc:0  lt:3369  rt:0  fl:0 
  [2] sc:0  lt:337  rt:0  fl:0 
  [3] sc:0  lt:338  rt:0  fl:0 
  [4] sc:0  lt:337  rt:0  fl:0 

<Constraint Check> (all must be [OK])
 [transaction percentage]
        Payment: 43.47% (>=43.0%) [OK]
   Order-Status: 4.35% (>= 4.0%) [OK]
       Delivery: 4.36% (>= 4.0%) [OK]
    Stock-Level: 4.35% (>= 4.0%) [OK]
 [response time (at least 90% passed)]
      New-Order: 0.00%  [NG] *
        Payment: 0.00%  [NG] *
   Order-Status: 0.00%  [NG] *
       Delivery: 0.00%  [NG] *
    Stock-Level: 0.00%  [NG] *

<TpmC>
                 561.500 TpmC

呵呵,测试数据还好吗?别太在意,这个环境性能没有参考意义。。。。

6.关于GUI客户端工具

图形化客户端我测试Navicat和DBeaver都可用,Navicat比较简单, DBeaver可配置的更多,推荐。

需要注意的是DBeaver连Oracle租户, 驱动设置里:

添加OB的JDBC驱动库: guava-18.0.jar + oceanbase-client-1.0.9.jar
类名: com.alipay.oceanbase.obproxy.mysql.jdbc.Driver
URL模板: jdbc:oceanbase://{host}[:{port}]/[{database}]

7. Java开发(JDBC)

MySQL租户和Oracle租户都是一样的,以下是一个简单案例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Oceanbase {
	public static void main(String[] args) throws Throwable {
		final String driver = "com.alipay.oceanbase.obproxy.mysql.jdbc.Driver";
		final String username = "sys@tenant_oracle_1#ghob";
		final String password = "root1234"; 
		final String url = "jdbc:oceanbase://192.168.203.154:2883/SYS?useUnicode=true&characterEncoding=utf-8";
		Class.forName(driver);
		Connection connection = DriverManager.getConnection(url, username, password);
		Statement stmt = connection.createStatement();
		ResultSet rs = stmt.executeQuery("select username, to_char(created,'yyyy-mm-dd hh24:mi:ss') created from dba_users");
	    while(rs.next()) {
	    	System.out.println("user="+rs.getString("username")+", created="+rs.getString("created"));
	    }
	    rs.close();
	    stmt.close();
	    connection.close();
	}
}

8. 后记

这么长的文章你都能看到最后,我看好你… 以我的体验上来说, OB 2.2对MySQL的兼容性还不错, 对于Oracle的兼容性还有很长的路要走, 你不能期待你的关键应用直接迁移到OB上就能用,除非厂家全力深度配合。个人的感受上,最为企业级数据库,OB也还没有达到成熟的地步,最多只达到可用的级别, 商用和自用还是有区别的,也不懂OB的支持团队构建如何。

采用不成熟/熟悉的技术, 是软件项目中常提到的失败的原因, 软件是以业务为导向的, 而不是以技术为导向, 对于大部分的企业来说, 为什么要用这个技术是个好问题, 是不是真的MySQL/Oracle不能胜任?或者只为一个噱头。

OB是个闭源的商业数据库,除了厂家的人,基本上都是盲人摸象,别人想让你知道多少,你就能知道多少。上了别人的船,就只能依赖别人,但上船之前还要先掂量下自己的分量,别人能给你多少支持和资源倾斜。

9. 附录

init_ob.sh

#!/bin/bash

#set -x 
echo "该脚本将删除已有(如果有)的oceanbase的配置和数据,是否继续?[YES|y|NO|n]:"
read input 
    case "$input" in
      [yY][eE][sS]|[yY]) 
        echo "" 
	  ;;
    *) 
      echo  "你选择了退出,脚本执行结束!"
	  exit 3
	;;
esac

obcluster_name=ghob  #ob集群名称
cluster_id=100       #ob集群唯一标识(编号)
data_dir=/data/1
log_dir=/data/log1

echo "关闭observer进程 ..."
ps -eaf | grep "observer" | grep -v grep | awk '{ print $2 }'| xargs -r kill -9

echo "清空observer数据 ..."

rm -rf $data_dir/*
rm -rf $log_dir/*
rm -rf /home/admin/oceanbase/store/ghob
rm -rf /home/admin/oceanbase/log/*
rm -rf /home/admin/oceanbase/etc/observer.config.*
rm -rf /home/admin/oceanbase/run

echo "初始化observer目录结构 ..."

mkdir -p $data_dir/$obcluster_name/{sstable,etc3,sort_dir} $log_dir/$obcluster_name/{slog,clog,ilog,ob_clog,etc2} /home/admin/oceanbase/store/$obcluster_name && chown -RL admin:admin $data_dir && chown -RL admin:admin /home/admin/oceanbase && chown -RL admin:admin $log_dir

#这步很耗时, 测试环境可跳过这步, 可以找个节点执行一次, 拷贝/home/admin/oceanbase/etc/io_resource.conf到其它OB server上;
#su - admin -c "/home/admin/oceanbase/bin/ob_admin io_bench -c /home/admin/oceanbase/etc -d $data_dir/$obcluster_name"

#创建目录结构
su - admin -c "ln -sf $data_dir/$obcluster_name/sstable /home/admin/oceanbase/store/$obcluster_name/sstable && ln -sf $data_dir/$obcluster_name/sort_dir /home/admin/oceanbase/store/$obcluster_name/sort_dir && ln -sf $log_dir/$obcluster_name/slog /home/admin/oceanbase/store/$obcluster_name/slog && ln -sf $log_dir/$obcluster_name/clog /home/admin/oceanbase/store/$obcluster_name/clog && ln -sf $log_dir/$obcluster_name/ilog /home/admin/oceanbase/store/$obcluster_name/ilog && ln -sf $log_dir/$obcluster_name/ob_clog /home/admin/oceanbase/store/$obcluster_name/ob_clog"

echo "启动observer..."

mysql_port=2881
rpc_port=2882
rootservice_list="192.168.55.10:2882:2881;192.168.55.20:2882:2881;192.168.55.30:2882:2881" #rootservice列表

resource_options=system_memory=4G,memory_limit=34G,sql_audit_memory_limit=256M,datafile_size=60G 
zone=zone1                                          #当前zone的名称, 需要根据执行的机器不同修改  , 我这里配置的是oceanbase01-> zone1; oceanbase02-> zone2; oceanbase03-> zone3 
dev_name=eth1                                       #服务ip对应的网卡, 需要根据机器的实际情况修改, 我这里是192.168.55.*地址对应的网卡

su - admin -c "cd /home/admin/oceanbase; mkdir run; touch run/observer.pid; ulimit -s 10240; ulimit -c unlimited; LD_LIBRARY_PATH=/home/admin/oceanbase/lib:/usr/local/lib:/usr/lib:/usr/lib64:/usr/local/lib64:$LD_LIBRARY_PATH LD_PRELOAD=\"\" /home/admin/oceanbase/bin/observer -i $dev_name -p $mysql_port -P $rpc_port -n $obcluster_name -z $zone -d /home/admin/oceanbase/store/$obcluster_name -l warn -o \"rootservice_list=$rootservice_list,$resource_options,cluster_id=$cluster_id,config_additional_dir=$log_dir/$obcluster_name/etc2;$data_dir/$obcluster_name/etc3\""

check.sh

echo "检查oceanbase进程..."
ps -fu admin|grep observer

echo ""
echo "检查oceanbase监听端口..."
netstat -ltunp |grep observer

boostrap.sh

mysql -u root -h127.0.0.1 -P2881 -p -e "set session ob_query_timeout=1000000000;alter system bootstrap ZONE 'zone1' SERVER '192.168.55.10:2882', ZONE 'zone2' SERVER '192.168.55.20:2882', ZONE 'zone3' SERVER '192.168.55.30:2882';"
 类似资料: