实验环境:企业版V3 1-1-1 

前期准备: 新建一个 oracle 租户 1C2GB

新建资源规格:

create resource unit u1_ora 
max_cpu=1,min_cpu=1,max_memory='2G',min_memory='2G',max_iops=128,max_disk_size='10G',max_session_num=100;

新建资源池:

create resource pool pool_ora 
unit='u1_ora',unit_num=1,zone_list=('z1','z2','z3');

新建租户

CREATE TENANT IF NOT EXISTS ob_pay charset='utf8mb4', replica_num=1, 
zone_list=('z1','z2','z3'), resource_pool_list=('pool_ora') SET 
ob_tcp_invited_nodes='%', ob_compatibility_mode='oracle';

新建 tpcc 用户,授予 dba 权限:

create user tpcc identified by obce_test;
grant dba to tpcc;

开始实验:

步骤 1 登陆 oracle 租户下的 tpcc 用户,创建 3 张表,模拟交易的场景, 第 1 张表和第 2 张表的 结构一致, 第 3 张表为不同结构

create table tab1 (c1 int primary key, c2 int, c3 varchar(10)) partition by 
hash(c1) partitions 10;
create table tab2 (c1 int primary key, c2 int, c3 varchar(10)) partition by 
hash(c1) partitions 10;
create table tab3 (d1 int primary key, d2 int) 
partition by list (d1)
(partition p0 values(1,2,3,4,5),
partition p1 values(6,7,8,9,10), 
partition p2 values (11,12,13,14,15));

步骤 2 向表中插入测试数据

insert into tab1 select level, mod(level,10),'003' from dual connect by 
level<=150;
insert into tab2 select level, mod(level,5),'004' from dual connect by level<=150;
insert into tab3 select level, mod(level,3) from dual connect by level<=15;
commit;

步骤 3 使用端口号 2883(obproxy)登录 sys 租户,查看参数ob_proxy_readonly_transaction_routing_policy 的默认值,修改 query_digest_time_threshold=100us

show parameters like 'ob_proxy_readonly_transaction_routing_policy';

show proxyconfig like 'query_digest_time_threshold';

alter proxyconfig set query_digest_time_threshold='100us'; 

步骤 4 打开一个新的 OS 命令行窗口, 运行以下命令,监测网络的数据流量

netstat -anltp|grep obclient|grep 2883

–此命令查看第一步 obclient 的 session 端口号,记录 第一个 IP 地址后面的端口号,这里为 30652; 注意显示结果中 observer 的 ip 地址相同(这里走了很多弯路,一定要相同不然抓不到包)

tcpdump -i lo port 30652 -w /tmp/tcpdump.raw

–-此命令将 tcpdump 获取的网络包写入一个临时文件

步骤 5 返回第一个步骤的 obclient 窗口,在 TPCC 用户下模拟运行一些查询和 update 语句.

select c1,c2 from tab1 where c1=10; 
select c1,c2 from tab2 where c1=10; 
update tab3 set d2=2 where d1=10;
commit; 
select c1,c2 from tab1 where c1=11; 
select c1,c2 from tab2 where c1=11; 
update tab3 set d2=3 where d1=11;
commit;

步骤 6 在 ssh 终端 tcpdump 命令窗口,使用 ctrl+c 终止命令

步骤 7 使用以下命令将 tcpdump.raw 文件转换为文本格式,便于使用文本编辑器查看

tcpdump -X -r /tmp/tcpdump.raw > /tmp/tcpdump.txt
more tcpdump.txt

步骤 8 登陆 sys 用户, 执行以下命令查询 SQL 语句的执行情况

select svr_ip,query_sql,sql_id,plan_id, trace_id,rpc_count,plan_type,is_hit_plan,elapsed_time,execute_time,get_plan_time from gv$sql_audit where query_sql like '%TA
B1%' or query_sql like '%TAB2%' or query_sql like '%TAB3%' and tenant_id=1001 
and user_name='tpcc' order by request_time \G

观察 rpc_count,plan_type, elapsed_time 等字段获取 SQL 语句执行时间执行计划等详情。

步骤 9 使用以下命令查看 obproxy_digest.log 中 SQL 语句的耗时情况

tail -100 /opt/taobao/install/obproxy/log/obproxy_digest.log

步骤 10 在第一步的 tpcc 窗口, 创建一个表组, 将表 tab1 和 tab2 放入此表组中

create tablegroup tab_group partition by hash partitions 10;
alter table tab1 tablegroup tab_group;
alter table tab2 tablegroup tab_group;

重复执行第 4 步 tcpdump -i lo port 30652 -w /tmp/tcpdump.raw 命令之后的步骤,比较表 组与没有表组的场景下,执行情况的不同

我随机挑选一个:

​​​​

上面是未使用表组,下面是使用表组。

步骤 11 修改参数 ob_proxy_readonly_transaction_routing_policy=False tenant=all,需要注意 最后添加 tenant=all 的控制参数,否则仅对 sys 租户调整

alter system set ob_proxy_readonly_transaction_routing_policy=false tenant=all;

select svr_ip,query_sql,sql_id,plan_id, trace_id,rpc_count,plan_type,is_hit_plan,elapsed_time,execute_time,get_plan_time from gv$sql_audit where query_sql like '%TA
B1%' or query_sql like '%TAB2%' or query_sql like '%TAB3%' and tenant_id=1001 
and user_name='tpcc' order by request_time \G

结论:

第一个场景最慢,第二个次之,第三个最快,下面三张图可以更加明确
个人对ob_proxy_readonlyu_transaction_routing_policy 这个参数的理解是:ob里面有很多分区表,不同分区的主副本可能会在不同的observer上面,那么当一条DML语句过来的时候就会产生分布式事务,降低性能,为了解决这个问题,OBProxy会把事务里所有 SQL 都发往开启事务的那条 SQL 被路由到的节点上去 。
但是如何判断事务开启的标志呢,事务的第一个语句可能是一条DQL语句,这就由ob_proxy_readonlyu_transaction_routing_policy参数控制。
Logo

了解最新的技术洞察和前沿趋势,参与 OceanBase 定期举办的线下活动,与行业开发者互动交流

更多推荐