作者简介:张瑞远,曾经从事银行、证券数仓设计、开发、优化类工作,现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认证包括 OceanBase OBCP、Oracle OCP 11g、OracleOCM 11g 、MySQL OCP 5.7 、腾讯云TBase、腾讯云TDSQL、阿里云ACP 、KingBase KCP。
序章
传统分布式数据库大多都是以多个计算节点的为优势,作为OLAP场景使用,记得多年前第一次接触hadoop1,核心还是HDFS+MapReduce,经典的分布式计算架构,当时熟悉了这个架构之后在我的心里就认为分布式数据库做不了OLTP的业务场景,更别说他组件的多样,对于数据库业务人员,基本都会依赖于HIVE,这些东西在安装这一步就让大部分的初学者知难而退了,所以我在接触ob之后,企业版从开始的antman到oat一直在不断简化安装的过程,甚至最初版本的antman的易用程度感觉已经可以和oracle相媲美了。更别说社区版4.0之后的obd的一键部署,在两分钟之内部署一个单节点的伪分布式系统,试问这是哪个学习者可以拒绝的便利。OceanBase 4.0所采用的架构是单机&分布式一体化架构,这一架构不止是区别于传统中心化的单机数据库也与传统的分布式架构数据库拉开了差距。也是真正如oceanbase的CEO杨冰所说“从分布式到单机分布式的转折,让OceanBase真正可以按需扩展,从0到1再到N“。
正如上所说,传统分布式数据库大多都是应用于OLAP场景,在越来越卷的今天,HTAP才是主流,OB从一开始的定位就不是单纯的AP或者TP数据库,而是我都要。所以从历代版本迭代可以看到对于两阶段提交的优化对于不同场景下rpc的消耗进一步减少,甚至自适应场景进行一阶段提交。对于事务的优化,可以看个例子比如,通过3.x版本对paratition group做的事务优化,在4.x取消了,进一步对unit层面日志流做了优化。当然优化点很多,比如取消了buffer表的设定,默认转储阈值改小,开放了行列混存的配置,修复了系统租户内存持有不释放的问题,对于大事务的优化,SYSBENCH的性能优化和TPCH查询性能优化,对在线ddl的增强,其实对于oracle转型的dba来说支持session和ash的监控和诊断格外友好。在这一系列的迭代中不止看到的是ob对于技术的精益求精,对于客户需求的快速响应,更让我们这些学习和使用者看到了它的日趋完美也看到了国产数据库的明天。
这篇测试内容主要是我从个人角度方便测试,并且也比较关注的点(有些比较关心的问题,像分区数优化、大事务的支持、租户级别备份之类只能等企业版更新上生产测试了~~有了结果也会分享给大家)
1、Online DDL 能力增强 and支持自增列做为分区键
在 OceanBase 早期的版本中,由于架构设计上的限制,对数据库 Online DDL 能力进行了有限支持,例如不支持主键修改操作给业务使用带来了诸多不便。得益于新版本一体化的架构设计,OceanBase 针对涉及到数据搬迁的 Online DDL操作进行增强支持,主要包括:
- 支持添加主键、修改主键和删除主键
- 支持修改列名和列类型,包括字符、数值、日期等类型的相互转换
- 支持普通表转换为分区表
- 支持修改表或列的字符序
obclient [test]> alter table `ob41` add primary key (a);
Query OK, 0 rows affected (21.305 sec)
obclient [test]> desc `ob41`;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a | int(11) | NO | PRI | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.001 sec)
obclient [test]> alter table ob41 drop primary key;
Query OK, 0 rows affected (7.215 sec)
obclient [test]> alter table ob41 modify a varchar(10);
Query OK, 0 rows affected (5.136 sec)
obclient [test]> alter table ob41 PARTITION BY RANGE (a)
-> (PARTITION p1 VALUES LESS THAN(5)
-> , PARTITION p2 VALUES LESS THAN (9 )
-> );
Query OK, 0 rows affected (1 min 7.642 sec)
obclient [test]> ALTER TABLE ob41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin;
Query OK, 0 rows affected (2.543 sec)
obclient [test]> create table t2(inv_id bigint not null auto_increment ,c1 bigint, primary key (inv_id) ) partition by hash(inv_id) partitions 8;
Query OK, 0 rows affected (0.200 sec)
2. 数据编码开源及Queuing 表不再支持,但是我在4.0测试仍然可以创建Queuing,并且也有效果,具体是测试偏差还是特性原因,可能还得生产验证
obclient [test]> CREATE TABLE `ob42` ( `a` int(11) DEFAULT NULL ) row_format = condensed progressive_merge_num=1;
Query OK, 0 rows affected (0.024 sec)
obclient [test]> show create table `ob42`;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ob42 | CREATE TABLE `ob42` (
`a` int(11) DEFAULT NULL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = CONDENSED COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 PROGRESSIVE_MERGE_NUM = 1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.007 sec)
obclient [test]> alter table `ob42` table_mode='queuing';
Query OK, 0 rows affected (0.196 sec)
obclient [test]> show create table `ob42`;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ob42 | CREATE TABLE `ob42` (
`a` int(11) DEFAULT NULL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = CONDENSED COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 PROGRESSIVE_MERGE_NUM = 1 TABLE_MODE = 'QUEUING' |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.002 sec)
对比测试如下,ob4是普通表,ob42是queuing表,我执行了多次插入删除操作。
obclient [test]> insert into ob4 select * from ob44;
Query OK, 131072 rows affected (0.702 sec)
Records: 131072 Duplicates: 0 Warnings: 0
obclient [test]> insert into ob42 select * from ob44;
Query OK, 131072 rows affected (0.665 sec)
Records: 131072 Duplicates: 0 Warnings: 0
obclient [test]> delete from ob4;
Query OK, 131072 rows affected (1.167 sec)
obclient [test]> delete from ob42;
Query OK, 131072 rows affected (4.419 sec)
obclient [test]> insert into ob4 select * from ob44;
Query OK, 131072 rows affected (1.227 sec)
Records: 131072 Duplicates: 0 Warnings: 0
obclient [test]> insert into ob42 select * from ob44;
Query OK, 131072 rows affected (0.931 sec)
Records: 131072 Duplicates: 0 Warnings: 0
obclient [test]> delete from ob4;
Query OK, 131072 rows affected (23.471 sec)
obclient [test]> delete from ob42;
Query OK, 131072 rows affected (1.217 sec)
比较好的一点是,添加了报错建议,这个点是真的太好了
obclient [test]> insert into ob44 select * from ob4;
ERROR 4012 (HY000): Timeout, query has reached the maximum query timeout: 10000000(us), maybe you can adjust the session variable ob_query_timeout or query_timeout hint, and try again.
可以看官网的介绍
https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000887404
3. 支持表锁和死锁检测,生产手动加锁场景较少,所以我只测试了死锁检测,也与生产3.x版本做了对比
####################第一个窗口####################
obclient [(none)]> show variables like '%commit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.002 sec)
obclient [(none)]> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
obclient [test]> insert into `ob41` values(1);
Query OK, 1 row affected (0.000 sec)
obclient [test]> commit;
Query OK, 0 rows affected (0.003 sec)
--第二个时间点
obclient [test]> update `ob41` set a=2 where a=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
obclient [test]>
obclient [test]> show variables like '%timeout%'
-> ;
+---------------------+------------------+
| Variable_name | Value |
+---------------------+------------------+
| connect_timeout | 10 |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| ob_pl_block_timeout | 3216672000000000 |
| ob_query_timeout | 10000000 |
| ob_trx_idle_timeout | 86400000000 |
| ob_trx_lock_timeout | -1 |
| ob_trx_timeout | 86400000000 |
| wait_timeout | 28800 |
+---------------------+------------------+
11 rows in set (0.001 sec)
####################################第二个窗口 ##############3
Database changed
obclient [test]> select * from `ob41`;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.002 sec)
--第一个时间点
obclient [test]>
obclient [test]> delete from `ob41` where a=1;
Query OK, 1 row affected (0.000 sec)
可以明显看出死锁报错,我在3.x版本测试,出现死锁后不会报错会一直等待,直到出现一个session回滚或者提交
4. NTP 服务优化
基于全新的自动选主协议,取消了对 NTP 时钟的依赖,打破原来早期版本对所有节点的时钟偏差控制在 100ms 以内的强需求。OceanBase V4.0 版本允许的时钟偏差可以达到 2s,同时支持动态修改时钟,不会对数据正确性和集群稳定运行带来影响。
其实在3.x版本我们就动态修改过ntp,ob的同学也说过会有风险,但是因为对于ntp的依赖性,ntp的延迟太长会导致节点异常,4.0demo安装后我没找到ntp服务,不确定是否完全取缔了ntp。
5.支持 SESSION 状态的监控和诊断(ASH)
OceanBase 数据库早期版本已经支持获取当前正在执行的 SQL 的状态信息,包括等待事件等信息,但只能通过 __all_virtual_session_wait 查询到 session 最近一次等待事件。OceanBase V4.0 版本支持更全面的 session 与等待事件之间的关系图(ASH),不仅包含当前执行的 SQL 的状态,还包含 SESSION、USER、SQL、WaitEvent 等多个维度状态历史信息。ASH 能够以 1s 为周期采样系统中所有 Active Session 状态,采用过程中全程不加锁不影响业务 SQL 的正常执行。OCP 通过对这些状态采样信息进行综合汇总分析,帮助用户了解过去一段时间里系统的负载以及等待状态,及时发现并预警问题。
####在一个窗口执行一些操作##
insert into ob4 select * from ob44;
delete from ob4;
insert into ob4 select * from ob44;
delete from ob4;
insert into ob4 select * from ob44;
delete from ob4;
##另一个窗口看下等待事件###
obclient [oceanbase]> select a.session_id,a.event,a.state from __all_virtual_session_wait a where a.state not in ('WAITED SHORT TIME','WAITED KNOWN TIME');
+------------+------------------------------+---------+
| session_id | event | state |
+------------+------------------------------+---------+
| 3221489548 | io controller condition wait | WAITING |
+------------+------------------------------+---------+
1 row in set (0.006 sec)
感想:
不积跬步无以至千里。OB已经踏踏实实走了十多个年头了,所谓十年磨一剑,从20年商业化以来,去年OB开源,这两年的发展迭代的速度令人咋舌,作为OB的相关行业人员,一面惊喜于它的发展和变化,一边担心自身的学习和积累被他的飞速成长所拉下甚至淘汰,但是我们仍然应该拥抱变化,去接受更好的OB,从3.x至4.x可以看出改变了很多东西,从运维语句到性能视图,摒弃了很多,新增了很多,也修改了很多,但为了更快,更便捷,更健壮,这些都是要经历的,oracle如此,OB亦会如此,期待完美的OB版本的诞生。
作者:张瑞远,本文转载自墨天轮,已获得作者授权。