【注意】最后更新于 January 30, 2023,文中内容可能已过时,请谨慎使用。
oceanbase探索之旅开始,成为oceanbase贡献者第5天
历史文章
# 一、Overview (任务是什么)
前言
大家好,今天是成为oceanbase贡献者第5天。
https://github.com/watchpoints/oceanbase/commit/eb331d4f0d8d7887201b835b07ea1f3528b934c2
https://github.com/oceanbase/oceanbase/issues/1383
[status: confirmed](https://github.com/oceanbase/oceanbase/labels/status%3A confirmed)
https://github.com/oceanbase/oceanbase/issues/1355
https://github.com/oceanbase/oceanbase/issues?q=is%3Aissue+is%3Aopen+label%3A%22type%3A+bug%22
今天主要任务是:
请教下,在查询数据时候ob有办法绕过kvcache缓存吗?我想做一个不常用的查询但是数据量太大,避免影响其它查询的命中率。
为解决该问题 查缺补漏
任务拆分
todo1: 在虚拟机搭建一个mysql最新版本,验证mysql语—-结果:提示语法错误
todo2: 源码编译验证最新代码—结果:已经被官方修复,你看如何修复的
todo3: ssues/1119源码分析
#二 、 思考分析过程(why)
todo1: 在虚拟机搭建一个mysql最新版本,验证mysql语法。
root/root mydb/root
- 虚拟机设置固定ip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
cd /etc/sysconfig/network-scripts
vi fcfg-ens160
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
IPADDR=192.168.192.163
NETMASK=255.255.255.0
GATEWAY=192.168.192.2
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=ens160
UUID=1a6a9936-2ba7-46d3-9b40-f2681f0ee9ab
DEVICE=ens160
ONBOOT=yes
设置dns:
vi /etc/resolv.conf
//重启
dnf install network-scripts
ifdown ens160
|
Q1:小王遇到这个问题:NETMASK,GATEWAY,dns怎么 这个设置。
NETMASK=255.255.255.0
GATEWAY=10.141.163.254
A1:
在虚拟网络编译器查看
https://www.jianshu.com/p/6fdbba039d79
-
mysql8安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
https://blog.csdn.net/DDJ_TEST/article/details/115867125
wget https://repo.mysql.com//mysql80-community-release-el8-4.noarch.rpm
禁用默认的MySQL模块、
sudo yum module disable mysql
yum install mysql80-community-release-el8-4.noarch.rpm
systemctl start mysqld(可以运行在1G单机内存上)
查看’root’@'localhost创建的超级用户帐户及临时密码
sudo grep 'temporary password' /var/log/mysqld.log
2023-01-30T08:16:07.224630Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: k2D+&9hpd+wc
使用生成的临时密码登录
mysql -uroot -p
进入mysq修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Qwer@1234';
select host, user, authentication_string, plugin from user;
update user set host='%' where user='root';
mysql -uroot -pQwer@1234
show databases;
|
-
造数据
1
2
3
4
5
6
7
|
CREATE TABLE v4 ( v5 INT, v6 INT , v7 INT) ;
INSERT INTO v4 VALUES (4, 5, 6);
SELECT DISTINCT JSON_ARRAYAGG ( DISTINCT v6 ) OVER ( PARTITION BY v7 ) FROM v4;
SELECT DISTINCT JSON_ARRAYAGG ( DISTINCT v6 ) OVER ( PARTITION BY v7 ) FROM v4;
ERROR 5798 (HY000): DISTINCT not allowed here
|
所有标志成status: confirmed的,在内部都有记录,这种issue一般我们会找内部同学修复 官方更新记录。
官方说:代码修复了
todo2: 源码编译验证最新代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
git reset --hard origin/master //把HEAD指向最新下载的版本
# 编译代码
//1. clean cluster
obd cluster destroy test
//2 make
bash build.sh debug --init --make -j8
cd /root/src/oceanbase/build_debug
//3 make install
make DESTDIR=./ install
cd /root/src/oceanbase/build_debug/usr/local/bin
./observer --version
observer (OceanBase_CE 4.1.0.0)
REVISION: 1-f61eb3f9672a877c9d6bf543c459d74e43fd839b
BUILD_BRANCH: master
BUILD_TIME: Nov 24 2022 12:38:57
BUILD_FLAGS: Debug
BUILD_INFO:
Copyright (c) 2011-2022 OceanBase Inc.
禁用远程镜像仓库
obd mirror disable remote
obd demo -c oceanbase,obproxy,obagent,prometheus,grafana
- 镜像版本
make DESTDIR=./ install &&
obd mirror create -n oceanbase-ce -V 4.1.0.0 -p ./usr/local -t my-oceanbase
Package ok
name: oceanbase-ce
version: 4.1.0.0
release:20221125211638
arch: x86_64
md5: 5379c1f155f3a7a49a3cf1a14093f3ab
//部署
mkfs.ext4 /dev/nvme3n1
mkdir -p /data/
mount /dev/sda /data/
obd cluster destroy test
obd cluster deploy test -c ./mini-local-example.yaml
https://gitee.com/oceanbase/obdeploy/blob/master/example/mini-local-example.yaml
oceanbase-ce:
tag: my-oceanbase
global:
home_path: /root/src/observer
memory_limit: 8G
system_memory: 4G
obd cluster list
obd cluster start test
启动失败:
obd cluster edit-config test
//后续每次更新就替换
cd /root/src/oceanbase/build_debug/usr/local/bin
cp observer /root/.obd/repository/oceanbase-ce/3.1.4-1/my-oceanbase/bin/
//后续每次更新就替换
cd /root/src/oceanbase/build_debug/usr/local/bin
cp observer /root/.obd/repository/oceanbase-ce/3.1.4-1/my-oceanbase/bin/
//后续每次更新就替换
cd /root/src/oceanbase/build_debug/usr/local/bin
cp observer /root/.obd/repository/oceanbase-ce/3.1.4-1/my-oceanbase/bin/
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
obclient -h127.0.0.1 -P2881 -uroot -Doceanbase -A
obclient -uroot@sys -h127.0.0.1 -P2881 oceanbase
obd cluster start test
Load cluster param plugin ok
Check before start observer ok
[WARN] (127.0.0.1) clog and data use the same disk (/data/storage)
# 客户端操作
修改日志级别
obd cluster edit-config test
tail -f /data/storage/observer/log/observer.lo
|
todo3: ssues/1119源码分析
第一次gdb调试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
src/sql/engine/aggregate/ob_aggregate_processor.cpp
dir /root/src/oceanbase
set pagination off
SELECT DISTINCT JSON_ARRAYAGG ( DISTINCT v6 ) OVER ( PARTITION BY v7 ) FROM v4;
SELECT DISTINCT JSON_ARRAYAGG ( EmpSalary) OVER(PARTITION BY EmpDepartment) sum_sala FROM Employee;
# int ObSql::handle_physical_plan
thread apply all break ob_sql.cpp:1947
thread apply all break ob_sql.cpp:3700
# ObSql::handle_text_query
thread apply all break ob_sql.cpp:1902
# int ObSql::handle_text_query(const ObString &stmt, ObSqlCtx &context, ObResultSet &result)
thread apply all break ob_sql.cpp:1830
D\note_oceanbase\src\sql\ob_sql.cpp
# ObMPQuery::do_process
thread apply all break obmp_query.cpp:701
thread apply all break obmp_query.cpp:777
thread apply all break obmp_query.cpp:828
逻辑:
stmt_query
response_result
# ObMPQuery::process_single_stmt
thread apply all break obmp_query.cpp:501
逻辑:
first_exec_sql true -do_process
没有逻辑
dir /root/src/oceanbase
set pagination off
CREATE TABLE v4 ( v5 INT, v6 INT , v7 INT) ;
INSERT INTO v4 VALUES (4, 5, 6);
SELECT DISTINCT JSON_ARRAYAGG ( DISTINCT v6 ) OVER ( PARTITION BY v7 ) FROM v4;
obclient [test]> SELECT DISTINCT JSON_ARRAYAGG ( DISTINCT v6 ) OVER ( PARTITION BY v7 ) FROM v4;
ERROR 5798 (HY000): DISTINCT not allowed here
|
sql 查询返回结果流程
- 入库:gdb调试
1
2
3
4
5
6
7
8
9
|
dir /root/src/oceanbase
set pagination off
# ObMPQuery::response_result
thread apply all break obmp_query.cpp:1258
流程:
ob_sync_plan_driver.cpp
int ObSyncPlanDriver::response_result
|
- 流程代码
1
2
3
4
5
6
|
// 通过判断 plan 是否为 null 来确定是 plan 还是 cmd
// 针对 plan 和 cmd 分开处理,逻辑会较为清晰。
result.get_physical_plan()) 有物理计划的就普通的查询sql
ObSyncPlanDriver::response_result(ObMySQLResultSet &result)
|
2
流程分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
ObQueryDriver::response_query_result
----->
| for 循环获取每一行。
| while (result.get_next_row(result_row)) )
如果是第一行,则先给客户端回复field等信息
response_query_header //返回查询的列 --没仔细看回到住流程
|
|
根据列 获 每row的 字段 ObObj& value = row->get_cell(i);
文件类型:
| 和miniob 逻辑一致 判断 值的类型 和列的类型是不一致。
| ObObjCaster::to_type 每看
| ObSMRow sm
| 发送给客户端 sender_.response_packet
------------------------------ob_result_set.cpp ------------------------------
ObResultSet::get_next_row ---->ObResultSet::inner_get_next_row
| ObPhysicalPlan* physical_plan --->ObIExecuteResult *exec_result_;
| ObICmd *cmd_;
------------------------------thread apply all break ob_execute_result.cpp:38------------------------------
ObExecuteResult::get_next_row --->
ObOperator *static_engine_root_;
| 1 创建 row_.cells_
| 2 创建 new (&row_.cells_[i]) ObObj();
3 转换 int ObExpr::eval
------------------------------thread apply all break ob_operator.cpp:1293------------------------------
ObOperator *op_;
-------> ObOperator::get_next_batch --->virtual int inner_get_next_batch(const int64_t max_row_cnt)
ObHashDistinctOp::inner_get_next_batch --->
ob_hash_distinct_op.cpp
------------------------------thread apply all break ob_hash_distinct_op.cpp:675------------------------------
(gdb) p get_next_batch_func_
$3 = (int (oceanbase::sql::ObHashDistinctOp::*)(oceanbase::sql::ObHashDistinctOp * const, const int64_t)) 0x84dffc0 <oceanbase::sql::ObHashDistinctOp::do_unblock_distinct_for_batch(long)>
OB_FAIL((this->*get_next_batch_func_)(batch_size))
------------------------------thread apply all break ob_window_function_op.cpp:2926------------------------------
thread apply all break ob_window_function_op.cpp:2926
thread apply all break ob_window_function_op.cpp:3099
thread apply all break ob_window_function_op.cpp:2971
thread apply all break ob_window_function_op.cpp:1373
thread apply all break ob_window_function_op.cpp:1373
------------------------------thread apply all break ob_aggregate_processor.cpp:1422------------------------------
|
# sql 查询返回结果流程
1. gdb
1
2
3
4
5
6
7
8
9
|
dir /root/src/oceanbase
set pagination off
# ObMPQuery::response_result
thread apply all break obmp_query.cpp:1258
流程:
ob_sync_plan_driver.cpp
int ObSyncPlanDriver::response_result
|
2. ob_sync_plan_driver.cpp –>int ObSyncPlanDriver::response_result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
和miniob返回解决过类似
读取:result.open()
1. 标记指定阶段 in_sql_execution_
union {
uint64_t exec_phase_; // phase of execution bitmap
struct {
uint64_t in_parse_ : 1;
uint64_t in_pl_parse_ : 1;
uint64_t in_get_plan_cache_ : 1;
uint64_t in_sql_optimize_ : 1;
uint64_t in_sql_execution_ : 1;
uint64_t in_px_execution_ : 1;
uint64_t in_sequence_load_ : 1;
};
};
2、
result.is_with_rows 这个是查询有多个列意思,多少行。
-------const common::ColumnsFieldIArray *p_field_columns_;
---2.1 ObQueryDriver::response_query_result
class ObQueryDriver 这是个虚函数
D:\db\oceanbase\src\observer\mysql\ob_sync_cmd_driver.cpp ---没看
src\observer\mysql\ob_query_driver.cpp (看这里)
3. ObQueryDriver::response_query_result
循环读取每一行记录 get_next_row ---这个没什么逻辑
is_first_row 如果是第一行,则先给客户端回复field等信息。
循环读取每一行的列 -----2个for循环这里没有什么逻辑
ObObj& value ,类型不一致 ObObjCaster::to_type ---->具体怎么cast 这里跳过没看,看主要逻辑
没有压缩 charset lob text转化 ----> 具体什么类型,没看
|
2个最基本的for循环,list各种东西都没有,这里结束来了吗?奇怪
|
3.3 返回结果 sender_.response_packet
4. 每一行是如何获取的,这里有什么逻辑!!!
ObResultSet::get_next_row ---->ObResultSet::inner_get_next_row
| ObPhysicalPlan* physical_plan --->ObIExecuteResult *exec_result_;
| ObICmd *cmd_;
这个完全是不符合标准定义,纯靠自己看得懂 physical_plan_ 和cmd区分,谁这样写代码。
https://docs.pingcap.com/tidb/v6.3/dev-guide-unstable-result-set
参考文章:https://cn.pingcap.com/blog/tidb-source-code-reading-3 TiDB 源码阅读系列文章(三)SQL 的一生
TiDB 源码阅读系列文章(二十三)Prepare/Execute 请求处理
TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
https://cn.pingcap.com/blog/tidb-source-code-reading-10
src\sql\executor\ob_execute_result.cpp
----------------src\sql\executor\ob_execute_result.cpp---------------
--------> int ObExecuteResult::get_next_row(ObExecContext &ctx, const common::ObNewRow *&row)
int ObExecuteResult::get_next_row(ObExecContext &ctx, const common::ObNewRow *&row)
|
如何读取一行
1
2
3
4
5
6
7
|
------------------------------thread apply all break ob_execute_result.cpp:38------------------------------
ObExecuteResult::get_next_row --->
ObOperator *static_engine_root_;
| 1 创建 row_.cells_
| 2 创建 new (&row_.cells_[i]) ObObj();
3 转换 int ObExpr::eval
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
mkdir -p /data/storage
mkfs.ext4 /dev/nvme3n1
mount /dev/nvme3n1 /data/storage
vi mini-local-example.yaml
obd cluster edit-config test
obd cluster redeploy test
obd cluster deploy test -c ./mini-local-example.yaml
obd cluster start test
# Connect to the OceanBase Database by using a MySQL client.
mysql -h127.1 -uroot -P2883
alias cdob="obclient -uroot@sys -h127.0.0.1 -P2881 oceanbase"
启动失败:
ERROR] (127.0.0.1): when production_mode is True, memory_limit can not be less then 16.0G
解决:
production_mode false
编译:
bash build.sh debug --init --make -j8
|
# 三. 如何解决的(how)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<<<<<<< HEAD
=======
vi mini-local-example.yaml
obd cluster edit-config watchpoints
obd cluster redeploy watchpoints
obd cluster stop watchpoints
obd cluster deploy wathchpoints -c ./mini-local-example.yaml
obd cluster start watchpoints
# Connect to the OceanBase Database by using a MySQL client.
mysql -h127.1 -uroot -P2883
alias cdob="obclient -uroot@sys -h127.0.0.1 -P2881 oceanbase"
启动失败:
ERROR] (127.0.0.1): when production_mode is True, memory_limit can not be less then 16.0G
解决:
production_mode false
编译:
bash build.sh debug --init --make -j8
>>>>>>> 5f6cb77ef99db04dd94448ed20f6c0a0f5424ad6
|
慢慢来,多看、多问、多总结,肯定是可以攻克的。
沟通步骤
-
准备好一个ppt,在写代码之前演示最终目标 和架构设计 就是如何去实现的 【不要说公司部门环境不对 着就是最终结果,不要试着看看,一定是可以完全上线的项目,非demo和一个知识点。自己认为真的 不是闹着玩的。。】
一、这个技术出现的背景、初衷和要达到什么样的目标或是要解决什么样的问题
二、这个技术的优势和劣势分别是什么
三、这个技术适用的场景。任何技术都有其适用的场景,离开了这个场景
四、技术的组成部分和关键点。
五、技术的底层原理和关键实现
六、已有的实现和它之间的对比
-
经过领导,专家 进行鸡蛋里挑骨头。【自己做好了别人路了胡扯,不会对别人产生任何影响,做事和做人一样,无论熟悉人,还是老师,领导,不相关人 反对 他们反馈信号,接受质疑,经过九九八十一难考验,并且你还在坚持认为对的。】
-
最后融合别人建议,然后完善你项目。【不听老人言,吃亏在眼前,不敢接受别人批评,说明自己完全没有把握,才去否定 愤怒方式】