OB 集群(包括 OBProxy)的手动部署方法,是入门 OB 运维的第一道门槛,是理解 OBD、OCP 以及 OBSHELL 等工具产品自动化部署 OB 集群的原理的关键,也是解决常见 OB 部署失败问题的关键。
业务要求在 ARM 服务器上部署 OB 4.2 。提供的资源有:2 台 8C16G 内存 200G SSD 的虚拟机。
只有 2 台服务器,组建一个 OB 集群没有意义(缺一台)。为了容灾,架构选择 OB DataGuard 方案。在 4.2 版本里,主备的粒度是租户,所以部署 2 个独立的单副本 OB 集群,创建一对主备租户。
没有提供服务器部署 OCP,所以 OB 集群部署、主备搭建都要手动执行。
服务器 CPU 是 Kunpeng 920,ARM 架构。操作系统是 UOS 1050d 。OB 和 OBProxy 的软件包是:oceanbase-4.2.1.1-101010022023110921.el7.aarch64.rpm 和 obproxy-4.2.1.0-20231017181929.el7.aarch64.rpm 。
服务器初始化
严格的服务器初始化步骤可以参考官网。这里仅列举关键的部分。
首先是内核参数设置。
fs.aio-max-nr=1048576net.core.somaxconn = 2048net.core.netdev_max_backlog = 10000net.core.rmem_default = 16777216net.core.wmem_default = 16777216net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.ip_local_port_range = 3500 65535net.ipv4.ip_forward = 0net.ipv4.conf.default.rp_filter = 1net.ipv4.conf.default.accept_source_route = 0net.ipv4.tcp_syncookies = 1net.ipv4.tcp_rmem = 4096 87380 16777216net.ipv4.tcp_wmem = 4096 65536 16777216net.ipv4.tcp_max_syn_backlog = 16384net.ipv4.tcp_fin_timeout = 15net.ipv4.tcp_max_syn_backlog = 16384net.ipv4.tcp_tw_reuse = 1#net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_slow_start_after_idle=0vm.swappiness = 0vm.min_free_kbytes = 1048576fs.file-max = 6573688vm.max_map_count = 655360
第二是磁盘设置。
第三是新建用户 admin 。
一般建议 OB 运行在用户 admin 下,如果是别的用户,看相关文档的时候都要改变用户为实际用户。这里只是名字叫 admin ,并不表示需要特别权限。有些工具要求这个用户有 sudo 免密权限,纯粹是运维工具为了自己方便。OB 对运行用户没有 sudo 权限要求。
当然,也强烈反对 OB 进程运行在 root 用户下,遗患无穷。这个跟 ORACLE 道理是一样的。
第四是 OS 会话设置。
vim /etc/security/limits.conf* soft nofile 655350* hard nofile 655350* soft stack unlimited* hard stack unlimited* soft nproc 655360* hard nproc 655360* soft core unlimited* hard core unlimitedadmin soft nofile 655350admin hard nofile 655350admin soft stack unlimitedadmin hard stack unlimitedadmin soft nproc 655360admin hard nproc 655360admin soft core unlimitedadmin hard core unlimited
理论上 星号(*)对所有用户都生效,但有些 OS 又说这个配置文件里星号只对 root 生效。为了避免麻烦,干脆把 OB 软件的运行用户(admin)单独再设置一遍。其中 nofile 影响 OB 进程用户能同时打开的文件句柄数。
这个修改后只对后续新建的用户会话生效,所以老的会话窗口需要退出重进,以及在运行的 OB 进程需要关闭并退出会话重新进用户下启动进程才会生效。这是有时候修改了参数但发现不解决问题的主要原因。检查命令:
admin@ob068130:~$ ulimit -acore file size (blocks, -c) unlimiteddata seg size (kbytes, -d) unlimitedscheduling priority (-e) 0file size (blocks, -f) unlimitedpending signals (-i) 64831max locked memory (kbytes, -l) 65536max memory size (kbytes, -m) unlimitedopen files (-n) 655350pipe size (512 bytes, -p) 8POSIX message queues (bytes, -q) 819200real-time priority (-r) 0stack size (kbytes, -s) unlimitedcpu time (seconds, -t) unlimitedmax user processes (-u) 655360virtual memory (kbytes, -v) unlimitedfile locks (-x) unlimited
第五是软件包安装。
rpm2cpio oceanbase-4.2.1.1-101010022023110921.el7.aarch64.rpm |cpio -idvmv home/admin/oceanbase home/admin/oceanbaserpm2cpio obproxy-4.2.1.0-20231017181929.el7.aarch64.rpm |cpio -idvmv opt/taobao/install opt/taobao/installchown -R admin.admin home/admin opt/taobao/install
首先是初始化 OB 数据目录。
cd home/admin/oceanbase && bin/rm -rf audit/* run/* etc/*config* store/obdemo/*/* log/*cd /home/admin/oceanbase && mkdir -p store/obdemo wallet /data/1/obdemo/sstable /data/log1/obdemo/{slog,clog,ilog}ln -s data/log1/obdemo/clog home/admin/oceanbase/store/obdemo/clogln -s /data/log1/obdemo/slog /home/admin/oceanbase/store/obdemo/slogln -s /data/log1/obdemo/ilog /home/admin/oceanbase/store/obdemo/ilogln -s /data/1/obdemo/sstable /home/admin/oceanbase/store/obdemo/sstable
以上目录如果已经存在需要先删除干净,否则后面映射时目录结构还是错的。正确的目录结构如下。目录结构错乱是常见的 OB 集群部署失败原因之一。
admin@ob068130:~/oceanbase$ tree storestore|___ obdemo|___ clog -> /data/log1/obdemo/clog|___ ilog -> data/log1/obdemo/ilog|___ slog -> /data/log1/obdemo/slog|___ sstable -> data/1/obdemo/sstable5 directories, 0 filesadmin@ob068130:~/oceanbase$ tree /data/{1,log1} -L 2/data/1|___ obdemo|___ sstable/data/log1|___ obdemo|___ clog|___ ilog|___ slog6 directories, 0 files
这里就是通过 ln 映射的方法将实际数据目录和日志目录放在非 home 目录下。
其次是进程启动。
bin/observer -i enp3s0 -p 2881 -P 2882 -n obdemo -z zone1 -d /home/admin/oceanbase/store/obdemo -l info -o "rootservice_list=10.0.68.130:2882:2881,cluster_id=20240101,cpu_count=16,system_memory=1G,memory_limit=12G,__min_full_resource_pool_memory=1073741824,datafile_size=10G,datafile_maxsize=50G,log_disk_size=40G"
进程监听的两个端口:mysql 端口(2881)和 RPC 端口(2882)。可以自定义。
集群名:-n obdemo
进程代表的 Zone :-z zone1 。单副本就从 zone1 开始。可以自定义。
进程的数据目录: -d home/admin/oceanbase/store/obdemo ,可以自定义, 这个目录下要有那 4 个文件夹(sstable、clog、ilog、slog)。
进程其他参数:-o "..." ,参数很多,具体如下:
集群 RS 地址 :rootservice_list(集群各个节点的 RS 地址保持统一,单副本集群就只有一个地址,格式是 ip:2882:2881 。)。
集群 ID :cluster_id=20240101,不同集群的集群 ID 尽量不要一样,有 OCP 的时候会要求全局唯一,方便区分。
进程持有的 CPU 个数:cpu_count=16,尽管实际物理 CPU 只有 8 个,可以随意指定(类似超卖)。
进程持有的全部可用内存:memory_limit=12G,这个是看服务器可用内存定。如果超出可用内存,到后面可能会碰到 OOM 问题。带业务的测试,建议最小 12G 。
进程内部保留内存:system_memory=1G,依据物理内存多少而定,经验最小是 1G 。这个参数默认值可能是 30G,不设置的话也是导致 OB 部署失败的常见原因之一。
进程持有的数据文件大小:包括数据文件初始化大小(datafile_size)和最大大小(datafile_maxsize,实际使用空间不会超过这个值),文件是自增的(默认每次增加 1G)。
进程持有的日志空间大小:log_disk_size=40G ,也是预留的空间大小,实际使用空间不会超过这个值。不要设置的太小,否则事务可能会等待日志空间分配。
从后面 4 个参数说明可以看出observer 进程对资源的使用策略是预分配占用策略。即使业务没有数据,OB 的 内存分配率、磁盘使用率也可能会很高,这点是跟传统数据库区别很大的一点。少见勿怪。
mysql -h127.0.0.1 -uroot -P2881 -p -c密码为空set session ob_query_timeout=1000000000; alter system bootstrap zone 'zone1' server '10.0.68.130:2882';
mysql -h127.0.0.1 -uroot@sys -P2881 -p -c密码为空MySQL [oceanbase]> show databases;+--------------------+| Database |+--------------------+| information_schema || LBACSYS || mysql || oceanbase || ORAAUDITOR || SYS || test |+--------------------+7 rows in set (0.015 sec)
alter system set syslog_level='WARN';alter system set enable_syslog_recycle=true;alter system set max_syslog_file_count=5;
实际环境调整看空间大小而定。
最后创建一个 OB 用户 proxyro 方便后面 OBProxy 连接到这个集群。
下面密码是示例。
create user proxyro identified by '';grant select on oceanbase.* to proxyro;
OBProxy 初始化
前面已经将 OBProxy 软件安装在目录 /opt/taobao/install/obproxy-x.x.x.x 下,通常会通过软链接映射到 /opt/taobao/install/obproxy 。
admin@ob068130:/opt/taobao/install/obproxy$ ls -lrth /opt/taobao/install/total 0lrwxrwxrwx 1 admin admin 15 May 20 11:33 obproxy -> obproxy-4.2.1.0drwxr-xr-x 9 admin admin 132 May 21 12:09 obproxy-4.2.1.0
kill -9 `pidof obproxy`cd /opt/taobao/install/obproxy && /bin/rm -rf .conf/ etc/*config*/ log/*cd /opt/taobao/install/obproxy && bin/obproxy -p 2883 -n obproxy -r '10.0.68.130:2881' -o "enable_strict_kernel_release=false,enable_cluster_checkout=false,enable_metadb_used=false,proxy_mem_limited=1G,observer_sys_password=,obproxy_sys_password=" -c obdemo
第一个和第二个命令是为了重复运行这个步骤时清理之前的运行结果的影响。这里特别注意的是 OBProxy 对参数文件的保存还搞了一个隐藏目录 .conf 。如果不清理干净,后面运行时还可能受此前的参数结果影响。
第三个命令主要是指定 OBProxy 启动参数。这里面的参数看懂了,就可以解决 OBProxy 启动失败或者启动成功连接 OB 失败的各种报错,也能理解 OCP 到底在 OBProxy 的部署时干了什么。
监听端口:-p 2883 ,可以自定义。
OBProxy 名称:-n obproxy ,可以自定义。
集群 Rootservice 信息:-r '10.0.68.130:2881',由于这里没有 OCP ,所以指定了具体的集群 RS IP 地址。
其他参数 :-o 。
内部检查参数: 三个 enable 参数,字面意思,照抄即可。
OBProxy 工作内存最大限制:proxy_mem_limited=1G,资源紧张的时候设置为 1G 。
OBProxy 管理员密码:obproxy_sys_password=,强制为空。
OBProxy 连接 OB 集群 SYS 租户的用户(proxyro)的密码:observer_sys_password=,强制为空。
mysql -h127.1 -uroot@sys#obdemo -P2883 -p oceanbase -c -AEnter password:MySQL [oceanbase]> show proxysession\G*************************** 1. row ***************************proxy_sessid: 7230886006340386822Id: 271Cluster: obdemoTenant: sysUser: rootHost: 127.0.0.1:23648db: oceanbasetrans_count: 0svr_session_count: 1state: MCS_ACTIVE_READERtid: 30820pid: 30820using_ssl: 01 row in set (0.001 sec)
也可以直接登录 OBProxy 管理员用户。这个效果跟上面一样。
mysql -h127.1 -uroot@proxysys -P2883 -pEnter password: 空密码
执行下面命令查看 OBProxy 的密码参数,并修改密码为示例密码 aaAA11__ 和 bbBB22__ 。
MySQL [(none)]> show proxyconfig like '%sys_password%';+------------------------+------------------------------------------+--------------------------------+-------------+---------------+| name | value | info | need_reboot | visible_level |+------------------------+------------------------------------------+--------------------------------+-------------+---------------+| observer_sys_password1 | ee0e5138c912aed80b683c05303684be347ce81d | password for observer sys user | false | SYS || observer_sys_password | | password for observer sys user | false | SYS || obproxy_sys_password | | password for obproxy sys user | false | SYS |+------------------------+------------------------------------------+--------------------------------+-------------+---------------+3 rows in set (0.001 sec)MySQL [(none)]> alter proxyconfig set observer_sys_password='aaAA11__';Query OK, 0 rows affected (0.015 sec)MySQL [(none)]> alter proxyconfig set obproxy_sys_password='bbBB22__';Query OK, 0 rows affected (0.009 sec)MySQL [(none)]> show proxyconfig like '%sys_password%';+------------------------+------------------------------------------+--------------------------------+-------------+---------------+| name | value | info | need_reboot | visible_level |+------------------------+------------------------------------------+--------------------------------+-------------+---------------+| observer_sys_password1 | ee0e5138c912aed80b683c05303684be347ce81d | password for observer sys user | false | SYS || observer_sys_password | ce77bdb3aad23ee556c638ea6ed86bad4949f676 | password for observer sys user | false | SYS || obproxy_sys_password | 22c23f5a61a1588b782c641b9887ab85ba75ce7b | password for obproxy sys user | false | SYS |+------------------------+------------------------------------------+--------------------------------+-------------+---------------+3 rows in set (0.002 sec)
同时修改 OB 集群 sys 租户下的 proxyro 的密码。
mysql -h127.1 -uroot@sys -P2881 -p oceanbase -c -AEnter password:alter user proxyro identified by 'aaAA11__';
然后重新通过 OBProxy 连接 OB 集群。
mysql -h127.1 -uroot@sys#obdemo -P2883 -p oceanbase -c -AEnter password:MySQL [oceanbase]> show processlist;+------+--------+------+-----------------+-----------+-------------+-------------------+-------------------+-------+-------+| Id | Tenant | User | Host | db | trans_count | svr_session_count | state | tid | pid |+------+--------+------+-----------------+-----------+-------------+-------------------+-------------------+-------+-------+| 314 | sys | root | 127.0.0.1:23652 | oceanbase | 0 | 1 | MCS_ACTIVE_READER | 30820 | 30820 |+------+--------+------+-----------------+-----------+-------------+-------------------+-------------------+-------+-------+1 row in set (0.003 sec)
并且测试 OBProxy 的管理员连接。
mysql -h127.1 -uroot@proxysys -P2883 -pEnter password:MySQL [(none)]> show proxysession;+--------------+------+---------+----------+------+-----------------+------+-------------+-------------------+-------------------+-------+-------+-----------+| proxy_sessid | Id | Cluster | Tenant | User | Host | db | trans_count | svr_session_count | state | tid | pid | using_ssl |+--------------+------+---------+----------+------+-----------------+------+-------------+-------------------+-------------------+-------+-------+-----------+| 0 | 318 | obdemo | proxysys | root | 127.0.0.1:23654 | NULL | 0 | 0 | MCS_ACTIVE_READER | 30820 | 30820 | 0 |+--------------+------+---------+----------+------+-----------------+------+-------------+-------------------+-------------------+-------+-------+-----------+1 row in set (0.002 sec)
OB 备租户部署
备集群是 OB V3 版本时候的叫法,到了 OB 4.1 后,主备的粒度从集群降到租户,就没有OB 备集群的说法,只有 OB 备租户。备租户可以跟主租户在同一个集群内部,也可以不在一个集群内。前者容灾意义不大,生产大多数时候备租户是独立集群里分配。如果一个集群里所有业务租户(不包括 sys)都是备租户,那是可以说这个集群是备集群。主备租户的资源规格、拓扑不要求严格一致,主备租户所在的集群规格也不要求一致。这是 OB 架构灵活的表现。
所以部署 OB 备租户之前得先部署一个新的 OB 集群,方法跟前面一样,集群名字叫 obdg,集群 ID 也区分一下。除此之外并无特别之处。所以,略去备集群的部署步骤,直接说备租户的部署过程。
备租户的部署过程简单来说就是主租户发起备份,然后将备份在新集群上还原出一个角色为备的租户,设置一下备租户的日志同步方式,这样租户的主备复制关系就建立了。详细步骤如下。
首先主租户设置日志归档路径和数据备份路径。
alter system set log_archive_dest='location=file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/clog' tenant=obmysql;alter system set data_backup_dest='file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/data' tenant=obmysql;
这里日志备份路径跟数据备份路径不能相同。通常如果有 NFS 路径或者 OSS 云盘路径,作为备份的目的地址是最合适的。这里演示的是另外一个情形,先备份到本地磁盘,然后复制到备租户所在服务器还原。
关于备份路径目录的结构形式这里有参考 OCP 设计的目的结构,虽然比较复杂,整体布局还是理的很顺。当然,随意指定一个空目录也是可以的。
主租户还需要创建一个用户 rep_user 用于日志复制。
create user rep_user identified by '********';grant select on oceanbase.* to rep_user;
第二,开启日志备份。日志备份就是日志归档。
开启归档和关闭归档的命令如下。
alter system archivelog ;alter system noarchivelog ;
obclient [oceanbase]> alter system archivelog tenant=obmysql;Query OK, 0 rows affected (0.109 sec)obclient [oceanbase]> select dest_id,round_id,dest_no,status,path from oceanbase.dba_ob_archivelog ;+---------+----------+---------+--------+--------------------------------------------------------------------+| dest_id | round_id | dest_no | status | path |+---------+----------+---------+--------+--------------------------------------------------------------------+| 1002 | 3 | 0 | DOING | file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/clog |+---------+----------+---------+--------+--------------------------------------------------------------------+1 row in set (0.001 sec)
当日志归档进程状态为 DOING 的时候,表示日志开始备份,此时才可以继续发起全量数据备份。
alter system backup tenant = obmysql plus archivelog;obclient [oceanbase]> select tenant_id, job_id, incarnation, backup_set_id,executor_tenant_id,plus_archivelog,backup_type,job_level,start_timestamp,end_timestamp,status,result,path from oceanbase.cdb_ob_backup_jobs;+-----------+--------+-------------+---------------+--------------------+-----------------+-------------+-------------+----------------------------+---------------+--------+--------+--------------------------------------------------------------------+| tenant_id | job_id | incarnation | backup_set_id | executor_tenant_id | plus_archivelog | backup_type | job_level | start_timestamp | end_timestamp | status | result | path |+-----------+--------+-------------+---------------+--------------------+-----------------+-------------+-------------+----------------------------+---------------+--------+--------+--------------------------------------------------------------------+| 1 | 1 | 1 | 0 | 1002 | ON | FULL | CLUSTER | 2024-05-21 14:29:45.375432 | NULL | DOING| 0 | || 1002 | 2 | 1 | 2 | 1002 | ON | FULL | USER_TENANT | 2024-05-21 14:29:45.408365 | NULL | DOING| 0 | file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/data |+-----------+--------+-------------+---------------+--------------------+-----------------+-------------+-------------+----------------------------+---------------+--------+--------+--------------------------------------------------------------------+2 rows in set (0.009 sec)
数据量不大的时候,全量备份很快就会结束,此时可以查看备份作业历史表。
obclient [oceanbase]> select tenant_id, job_id, incarnation, backup_set_id,executor_tenant_id,plus_archivelog,backup_type,job_level,start_timestamp,end_timestamp,status,result,path from oceanbase.cdb_ob_backup_job_history order by start_timestamp desc limit 2\G*************************** 1. row ***************************tenant_id: 1002job_id: 2incarnation: 1backup_set_id: 2executor_tenant_id: 1002plus_archivelog: ONbackup_type: FULLjob_level: USER_TENANTstart_timestamp: 2024-05-21 14:29:45.408365end_timestamp: 2024-05-21 14:32:52.560551status: COMPLETEDresult: 0path: file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/data*************************** 2. row ***************************tenant_id: 1job_id: 1incarnation: 1backup_set_id: 0executor_tenant_id: 1002plus_archivelog: ONbackup_type: FULLjob_level: CLUSTERstart_timestamp: 2024-05-21 14:29:45.375432end_timestamp: 2024-05-21 14:33:15.476795status: COMPLETEDresult: 0path:2 rows in set (0.005 sec)
第三,将备份目录 压缩并复制到备租户所在 OB 服务器上,然后解压缩。
这里选择的是同一个目录 /data/backup/obdemo/20240101/tenant_incarnation_1/1002/data 。
第四,在集群 obdg 上还原该备份租户。
还原之前先创建好租户需要的资源池。
create resource unit u_db max_cpu=6,min_cpu=6,memory_size='6G',log_disk_size='20G';create resource pool p_db unit='u_db',unit_num=1,zone_list=('zone1');ALTER SYSTEM RESTORE standby_tenant FROM 'file:///data/backup/obdemo/20240101/tenant_incarnation_1/1002/data' WITH 'pool_list=p_db';
查看备租户还原结果。
MySQL [oceanbase]> SELECT TENANT_NAME, TENANT_TYPE, CREATE_TIME, STATUS, TENANT_ROLE,SCN_TO_TIMESTAMP(SYNC_SCN) FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME = 'standby_tenantl';+-------------+-------------+----------------------------+--------+-------------+----------------------------+| TENANT_NAME | TENANT_TYPE | CREATE_TIME | STATUS | TENANT_ROLE | SCN_TO_TIMESTAMP(SYNC_SCN) |+-------------+-------------+----------------------------+--------+-------------+----------------------------+| standby_tenant | USER | 2024-05-17 14:30:55.127747 | NORMAL | STANDBY | 2024-05-21 14:46:15.758668 |+-------------+-------------+----------------------------+--------+-------------+----------------------------+1 row in set (0.002 sec)
租户的角色(tenant_role)为 STANDBY 时表示还原成功。
此时发现还原出来的租户名当时没有改,可以再改一下。
alter tenant standby_tenant rename global_name to obmysql;
但是,这个还原的租户还没有继续同步主租户的事务日志,还需要继续设置一下日志同步方式。
这里有两个选项,一是基于主租户事务备份路径(NFS路径),二是基于网络传输。这里选择后者。
alter system set log_restore_source='service=10.0.68.130:2881 user=rep_user@obmysql password=******' tenant='obmysql';
alter system recover standby tenant='obmysql' until unlimited;
MySQL [oceanbase]> select tenant_name,tenant_type, create_time,status,tenant_role,scn_to_timestamp(sync_scn),now() from dba_ob_tenants ;+-------------+-------------+----------------------------+--------+-------------+----------------------------+---------------------+| tenant_name | tenant_type | create_time | status | tenant_role | scn_to_timestamp(sync_scn) | now() |+-------------+-------------+----------------------------+--------+-------------+----------------------------+---------------------+| obmysql | USER | 2024-05-17 14:30:55.127747 | NORMAL | STANDBY | 2024-05-21 14:56:21.625156 | 2024-05-21 14:56:22 |+-------------+-------------+----------------------------+--------+-------------+----------------------------+---------------------+1 row in set (0.002 sec)
至此,备租户就跟主租户保持同步。
更多阅读




