Oceanbase为啥新入数据select慢

  大家好,作为一个数据库管理员,在纷繁的数据库产品中想占有一席之地,那么必须是剑在手跟我走,除了有一个看家的产品精通或者熟悉之外,还需要多学其他数据库产品,那么本人作为OB新人,以此开篇进行记录,如博客中有什么不对的地方,还请大家留言更正。让我们一起为数据库领域搬砖添瓦!

  大致情况就是,我们新上了一套V4.2.1社区版的OB,开发在进行洗数据的过程中,我们在count条数,发现count的数据比较慢,用了hint的方式也不行。那用其他数据库思维看,怀疑1,统计信息问题  2,合并问题。

Oceanbase为啥新入数据select慢_数据库

OB里面的统计信息收集的时间,方式与Oracle如出一辙

Oceanbase为啥新入数据select慢_数据库_02

那么我们看一下他的统计信息是不是过期了呢?

Oceanbase为啥新入数据select慢_MySQL_03

统计信息并无过期。那么第一点排除。那么就是怀疑第二点,合并的问题,关于合并相关的说明 与介绍,官网有很多文档。

合并通常是一个比较重的操作,时间也相对较长,在最佳实践中,一般期望在一天只做一次合并操作,并且控制在业务低峰期进行,因此有时也会把合并称之为每日合并。

合并操作(Major Compaction)是将动静态数据做归并,会比较费时。当转储产生的增量数据积累到一定程度时,通过 Major Freeze 实现大版本的合并。它和转储最大区别在于,合并是租户上所有的分区在一个统一的快照点和全局静态数据进行合并的行为,是一个全局的操作,最终形成一个全局快照。

转储(Minor Compaction)	合并(Major Compaction)
Partition 或者租户级别,只是 MemTable 的物化。	全局级别,产生一个全局快照。
每个 OBServer 节点的每个租户独立决定自己 MemTable 的冻结操作,主备分区不保持一致。	全局分区一起做 MemTable 的冻结操作,要求主备 Partition 保持一致,在合并时会对数据进行一致性校验。
可能包含多个不同版本的数据行。	只包含快照点的版本行。
转储只与相同大版本的 Minor SSTable 合并,产生新的 Minor SSTable,所以只包含增量数据,最终被删除的行需要特殊标记。	合并会把当前大版本的 SSTable 和 MemTable 与前一个大版本的全量静态数据进行合并,产生新的全量数据。
合并虽然比较费时, 但是同时为数据库提供了一个操作窗口,在这个窗口内 OceanBase 数据库可以利用合并特征完成多个计算密集任务, 提升整体资源利用效率。

数据压缩

合并期间 OceanBase 数据库会对数据进行两层压缩,第一层是数据库内部基于语义的编码压缩,第二层是基于用户指定压缩算法的通用压缩,使用 lz4 等压缩算法对编码后的数据再做一次瘦身。压缩不仅仅节省了存储空间,同时也会极大地提升查询性能。目前 OceanBase 数据库支持(snappy、lz4、lzo,zstd)等压缩算法,允许用户在压缩率和解压缩时间上做各自的权衡。MySQL 和 Oracle 在一定程度上也支持对数据的压缩,但和 OceanBase 相比,由于传统数据库定长页的设计,压缩不可避免的会造成存储的空洞,压缩效率会受影响。而更重要的是,对于 OceanBase 数据库这样的 LSM-Tree 架构的存储系统,压缩对数据写入性能是几乎无影响的。

数据校验

通过全局一致快照进行合并能够帮助 OceanBase 数据库很容易的进行多副本的数据一致校验, 合并完成后多个副本可以直接比对基线数据来确保业务数据在不同副本间是一致的。另一方面还能基于这个快照基线数据做主表和索引表的数据校验,保障数据在主表和索引表之间是一致的。

Schema 变更

对于加列、减列等 Schema 变更,OceanBase 数据库可以在合并中一起完成数据变更操作,DDL 操作对业务来说更加平滑。

合并方式
合并有很多种不同的方式,具体的描述如下。

全量合并

全量合并是 OceanBase 数据库最初的合并算法,和 HBase 与 RocksDB 的 major compaction 过程是类似的。在全量合并过程中,会把当前的静态数据都读取出来,和内存中的动态数据合并后,再写到磁盘上去作为新的静态数据。在这个过程中,会把所有数据都重写一遍。全量合并会极大的耗费磁盘 IO 和空间,除了 DBA 强制指定外,目前 OceanBase 数据库一般不会主动做全量合并。

增量合并

在 OceanBase 数据库的存储引擎中,宏块是 OceanBase 数据库基本的 IO 写入单位,在很多情况下,并不是所有的宏块都会被修改,当一个宏块没有增量修改时,合并可以直接重用这个数据宏块, OceanBase 数据库中将这种合并方式称之为增量合并。增量合并极大地减少了合并的工作量,是OceanBase 数据库目前默认的合并算法。更进一步地,OceanBase 数据库会在宏块内部将数据拆分为更小的微块,很多情况下,也并不是所有的微块都会被修改,可以重用微块而不是重写微块。微块级增量合并进一步减少了合并的时间。

渐进合并

为了支持业务的快速发展,用户不可避免地要做加列、减列、建索引等诸多 DDL 变更。这些 DDL 变更对于数据库来说通常是很昂贵的操作。MySQL 在很长一段时间内都不能支持在线的 DDL 变更(直到 5.6 版本才开始对 Online DDL 有比较好的支持),而即使到今天,对于 DBA 来说,在 MySQL 5.7 中做 Online DDL 仍然是一件比较有风险的操作,因为一个大的 DDL 变更就会导致 MySQL 主备间的 replication lag。

OceanBase 数据库在设计之初就考虑到了 Online DDL 的需求,目前在 OceanBase 数据库中加列、减列、建索引等 DDL 操作都是不阻塞读写的,也不会影响到多副本间的 paxos 同步。加减列的 DDL 变更是实时生效的,将对存储数据的变更延后到每日合并的时候来做。然而对于某些 DDL 操作如加减列等,是需要将所有数据重写一遍的,如果在一次每日合并过程中完成对所有数据的重写,那么对存储空间和合并时间都会是一个比较大的考验。为了解决这个问题,OceanBase 数据库引入了渐进合并,将 DDL 变更造成的数据重写分散到多次每日合并中去做,假设渐进轮次设置为 60,那么一次合并就只会重写 60 分之一的数据,在 60 轮合并过后,数据就被整体重写了一遍。渐进合并减轻了 DBA 做 DDL 操作的负担,同时也使得 DDL 变更更加平滑。

并行合并

在 OceanBase 数据库 V1.0 中增加了对分区表的支持。对于不同的数据分区,合并是会并行来做的。但是由于数据倾斜,某些分区的数据量可能非常大。尽管增量合并极大减少了合并的数据量,对于一些更新频繁的业务,合并的数据量仍然非常大,为此 OceanBase 数据库引入了分区内并行合并。合并会将数据划分到不同线程中并行做合并,极大地提升了合并速度。

详见:https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218992

(product)[email protected] [omp_profit]>select count(*) from p_mer_day_statistics_extend;
+-----------+
| count(*)  |
+-----------+
| 168273740 |
+-----------+
1 row in set (1 min 18.07 sec)


(product)[email protected] [omp_profit]>select owner,TABLE_NAME,LAST_ANALYZED,NUM_ROWS from  OCEANBASE.DBA_TAB_STATISTICS where table_name='p_mer_day_statistics_extend';
+------------+-----------------------------+----------------------------+-----------+
| owner      | TABLE_NAME                  | LAST_ANALYZED              | NUM_ROWS  |
+------------+-----------------------------+----------------------------+-----------+
| omp_profit | p_mer_day_statistics_extend | 2023-12-30 06:06:37.667557 | 168273740 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |  55604648 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |  56962008 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-30 06:06:37.667557 |  55707084 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
| omp_profit | p_mer_day_statistics_extend | 2023-12-29 22:17:49.337753 |         0 |
+------------+-----------------------------+----------------------------+-----------+
38 rows in set (0.05 sec)

执行合并的话,在OCP平台,集群中进行即可。

Oceanbase为啥新入数据select慢_数据_04

Oceanbase为啥新入数据select慢_MySQL_05

合并完成后,我们再进行查看,看看1.6亿数据,由之前1分18秒,有没有提升

(product)[email protected] [omp_profit]>select count(*) from p_mer_day_statistics_extend;
+-----------+
| count(*)  |
+-----------+
| 168273740 |
+-----------+
1 row in set (0.01 sec)

合并的过程中,除了OCP直观的进行查看以外,也有一些视图参考

(product)[email protected] [oceanbase]>SELECT * FROM __all_zone;
+----------------------------+----------------------------+-------+------------------------+------------------+---------------------+
| gmt_create                 | gmt_modified               | zone  | name                   | value            | info                |
+----------------------------+----------------------------+-------+------------------------+------------------+---------------------+
| 2023-12-22 11:35:58.462321 | 2023-12-22 11:35:58.462321 |       | cluster                |                0 | ompprofit_obcluster |
| 2023-12-22 11:35:58.462530 | 2023-12-26 14:07:26.994154 |       | config_version         | 1703570846988277 |                     |
| 2023-12-22 11:35:58.462530 | 2023-12-26 14:07:26.994154 |       | lease_info_version     | 1703570846993658 |                     |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 |       | privilege_version      |                0 |                     |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 |       | storage_format_version |                4 |                     |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 |       | time_zone_info_version |                0 |                     |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:36:07.215037 | zone1 | idc                    |                0 | pengboshi_idc       |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 | zone1 | recovery_status        |                0 | NORMAL              |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 | zone1 | region                 |                0 | beijing             |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 | zone1 | status                 |                2 | ACTIVE              |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone1 | storage_type           |                0 | LOCAL               |
| 2023-12-22 11:35:58.462530 | 2023-12-22 11:35:58.462530 | zone1 | zone_type              |                0 | ReadWrite           |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:36:07.230996 | zone2 | idc                    |                0 | pengboshi_idc       |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone2 | recovery_status        |                0 | NORMAL              |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone2 | region                 |                0 | beijing             |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone2 | status                 |                2 | ACTIVE              |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone2 | storage_type           |                0 | LOCAL               |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone2 | zone_type              |                0 | ReadWrite           |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:36:07.239490 | zone3 | idc                    |                0 | pengboshi_idc       |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone3 | recovery_status        |                0 | NORMAL              |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone3 | region                 |                0 | beijing             |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone3 | status                 |                2 | ACTIVE              |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone3 | storage_type           |                0 | LOCAL               |
| 2023-12-22 11:35:58.463606 | 2023-12-22 11:35:58.463606 | zone3 | zone_type              |                0 | ReadWrite           |
+----------------------------+----------------------------+-------+------------------------+------------------+---------------------+
24 rows in set (0.00 sec)

(product)[email protected] [oceanbase]> SELECT  svr_ip,svr_port,total_size/1024/1024/1024 AS total, free_size/1024/1024/1024 AS free,(total_size-free_size)/1024/1024/1024 as used 
    -> FROM __all_virtual_disk_stat;
+-------------+----------+------------------+------------------+-----------------+
| svr_ip      | svr_port | total            | free             | used            |
+-------------+----------+------------------+------------------+-----------------+
| 10.3.100.95 |     2882 | 300.000000000000 | 278.591796875000 | 21.408203125000 |
| 10.3.100.86 |     2882 | 300.000000000000 | 278.576171875000 | 21.423828125000 |
| 10.3.100.94 |     2882 | 300.000000000000 | 278.595703125000 | 21.404296875000 |
+-------------+----------+------------------+------------------+-----------------+
3 rows in set (0.01 sec)