OB什么才是分布式事务?

【 使用环境 】生产环境 or 测试环境
【 OB 】
【 使用版本 】4.0
【问题描述】只要有begin和commit,中间带多条SQL就是分布式事务吗?看官网不太明白
https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000887232

+-------------------------------------------------+
|                     observer                    |
+---------------+---------+------+-------+--------+
| ip            | version | port | zone  | status |
+---------------+---------+------+-------+--------+
| 172.16.11.134 | 4.0.0.0 | 2881 | zone1 | ACTIVE |
| 172.16.11.135 | 4.0.0.0 | 2881 | zone2 | ACTIVE |
| 172.16.11.136 | 4.0.0.0 | 2881 | zone3 | ACTIVE |
+---------------+---------+------+-------+--------+
obclient -h172.16.11.134 -P2881 -uroot -Doceanbase

Connect to obproxy ok
+-------------------------------------------------+
|                     obproxy                     |
+---------------+------+-----------------+--------+
| ip            | port | prometheus_port | status |
+---------------+------+-----------------+--------+
| 172.16.11.134 | 2883 | 2884            | active |
| 172.16.5.145  | 2883 | 2884            | active |
+---------------+------+-----------------+--------+
obclient -h172.16.11.134 -P2883 -uroot -Doceanbase

表结构如下,未分区:
[root@172-16-11-134 ~]# obclient -h172.16.11.134 -P2883 -uroot@tenant1 -Dtest -A
# 表结构
obclient [test]> show create table sbtest1 \G
*************************** 1. row ***************************
       Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`) BLOCK_SIZE 16384 LOCAL
) AUTO_INCREMENT = 1000001 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0

做 oltp_read_only 压测,语句如下:
| BEGIN;                                                                                            |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 502016];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 499004];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 505118];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 498083];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 502557];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 467971];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 501913];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 519429];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 501763];                                             |
| SELECT c FROM sbtest8 WHERE id=? [arguments: 499073];      
                                       
# 以下4条语句通过 mysqlslap 单独压测,注入前后性能无明显变化
| SELECT c FROM sbtest10 WHERE id BETWEEN ? AND ? [arguments: (545651, 545750)];                    |
| SELECT SUM(k) FROM sbtest6 WHERE id BETWEEN ? AND ? [arguments: (457437, 457536)];                |
| SELECT c FROM sbtest6 WHERE id BETWEEN ? AND ? ORDER BY c [arguments: (498261, 498360)];          |
| SELECT DISTINCT c FROM sbtest3 WHERE id BETWEEN ? AND ? ORDER BY c [arguments: (504674, 504773)]; |

| COMMIT;  

只跑一种类型的事务SQL,为什么  Local 、Remote 、Distribute 都有?

obclient [oceanbase]> select plan_type, count(1) from gv$ob_sql_audit where  request_time > time_to_usec('2021-08-24 18:00:00') group by plan_type order by plan_type;
+-----------+----------+
| plan_type | count(1) |
+-----------+----------+
|         0 |      260 |
|         1 |     1828 |
|         2 |      430 |
|         3 |       11 |
+-----------+----------+

1 个赞

OB是存算一体架构,
obproxy 会优先发给数据主所在的 observer 节点, 这是local事务才会优先发主?
然而分布式事务跨机器发?

Remote表示当前语句所涉及的分区 Leader 与 Session 所在的机器不同。

这个 Session 是指什么?麻烦老师解答哈

OB对于分布式事务是有优化的。
一个事务内sql都是在一台observer完成,可以说没有分布式事务。
如果一个事务内sql,涉及到两个及两个以上observer,那就是分布式事务了。
一个事务内sql,可以一个sql的dml涉及多个节点上的分区leader,也可以是多个sql,分别涉及多个节点上的分区leader

Session就是connection

事务类型统计

SQL 的执行计划分为四种:Local 、Remote 、Distribute 和 Uncertain。其中 Local 表示当前语句所涉及的分区 Leader 与 Session 所在的机器相同;Remote表示当前语句所涉及的分区 Leader 与 Session 所在的机器不同;Distribute 和 Uncertain 计划不能确定 Leader 和 Session 的关系,可能在同一个机器,也可能跨多机。
https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000881566
对于事务的性能而言,优先使用单机事务,其次才是分布式事务;根据执行计划的类型统计信息,可以大致估算出分布式事务的比例,进而为调优提供数据支持。

老师,怎么从SQL判断是否涉及多个observer呢?

https://www.oceanbase.com/docs/community-observer-cn-10000000000901370

OceanBase 数据库V4.0.0
GV$OB_SQL_AUDIT

SQL 的路由信息
OceanBase 数据库的 SQL 计划类型整体分为如下四类:

Local 计划:指事务 Session 和本语句涉及的分区 Leader 在同一 OBServer。可以涉及多个分区,但不允许同一张表内出现多个分区。

Remote 计划:指事务 Session 和本语句涉及的分区 Leader 在两个 OBServer 上。可以涉及多个分区,但不允许同一张表内出现多个分区。

Distribute 计划:指当前语句的操作涉及多个分区。分区可以分布在一个或多个 OBServer。

Uncertain 计划:指在语句开始执行期间,无法确定分区数目的场景。一般存在于全局索引、外键等场景。

由于单机事务提交的效率比跨机高,用户需要根据实际情况,确认上述计划的比例数是否符合预期。SQL 计划的统计示例语句如下:

select plan_type, count(1) from GV$OB_SQL_AUDIT where tenant_id = *** and request_time > time_to_usec(‘2021-10-08 12:00:00’) group by plan_type;
plan_type 的取值为 1、2、3、4,分别表示 Local 计划、Remote 计划、Distribute 计划和 Uncertain 计划。

https://www.oceanbase.com/docs/community-observer-cn-10000000000901986