在开始本次学习之前,我们假设你已经阅读过
https://github.com/cockroachdb/cockroach/blob/master/docs/codelabs/01-sql-statement.md
的创建自定义SQL语句教程,并成功完成编译运行。
目标:实现一个新的SQL语句,如EXPORT <targets…> TO <location>,将指定的表数据并行导出到指定路径。
初始代码:cockroachdb 1.0 ---https://github.com/cockroachdb/cockroach
- 步骤1:添加SQL解析功能
修改pkg/sql/parser/sql.y
(1)定义属于EXPORT的语法
(2)定义解析的状态类型(3)新增stmt列表
(4)实现解析具体过程
(5)添加非保留关键字
找到unreserved_keyword:(6)此时需要对sql.y编译生成sql.go,keywords.go等文件。
运行:make generate 生成相应文件
- 步骤2:对输入的SQL语句进行分发
修改pkg/sql/plan.go
- 步骤3:构建自己的EXPORT结构体
新建pkg/sql/parser/export.go
主要内容如下:
(1)结构体
(2)结构体的格式化函数
新建pkg/sql/export.go
新增Export函数,这样SQL解析之后就会跑这里来
这里你可以简单地打印一些信息,通过 fmt.Println() 函数可以将信息打印到启动数据库的服务端屏幕上,就和c++的printf()功能一样。
不过上线后一般还是通过 log.Infof(ctx, err.Error()) 打到日志里去的,
如 cockroach-data/logs/ndb.log 这个日志文件。
运行:make build 在当前路径下编译出二进制的ndb文件
- 步骤4:为value构建格式化函数
修改pkg/roachpb/data.go
添加函数// FormatValue returns the value in a csv readable format.
func (v Value) FormatValue() string
这个函数可以参考func (v Value) PrettyPrint() string
这个函数为了方便后面对kv的value进行格式化。
我这里是要做成csv的格式,将PrettyPrint()中的‘/’逻辑替换成‘,’,自己再稍微调整一下就好了。
- 步骤5:新建自己的ExportCsvRequest
修改pkg/roachpb/api.proto文件
这里标注主要修改的地方,具体实现可参考ExportRequest的模样弄。
此时,运行 make generate,会生成许多文件,如api.pb.go......
- 步骤6:增加api接口
修改pkg/roachpb/api.go
具体也是参考ExportRequest的模样
主要是以下几个地方:
- 步骤7:添加method常量
修改pkg/roachpb/method.go
修改pkg/storage/cclglue.go
- 步骤8:编写逻辑处理文件(核心)
修改之前步骤3的pkg/sql/export.go
主要添加内容如下
(1)初始化
init()函数和main()函数一样,都会自动被调用一次的。
下面这里就是在程序加载的时候,把各节点收到请求后调用evalExportCsv函数处理逻辑。
(2)一些通用函数,根据pkg/ccl/storageccl/export.go 一样编写而来
(3)修改(*planner).Export的处理逻辑
注意这里的client.SendWrappedWith(context.Background(), p.ExecCfg().DB.GetSender(), header, req)
通过这个函数,可以将我们自定义的ExportCsvRequest请求通过dist_sender下发到节点上。
(4)编写各节点处理的逻辑函数evalExportCsv()
把key,value读出来
导出到路径
命令行make build编译生成相应的文件
- 步骤9:测试
在一个tab中启动数据库
./cockroach start --insecure
在第二个tab启动第二个节点
./cockroach start --insecure --host=MINGLINLU-MB0 --store=node2 --port=26258 --http-port=8081 --join=localhost:26257
在第三个tab启动第三个节点
./cockroach start --insecure --host=ip --store=node3 --port=26259 --http-port=8082 --join=localhost:26257
在一个tab中启动SQL客户端
./cockroach sql –insecure
创建数据库
create database lml;
use lml;
创建测试表
CREATE TABLE student (id INT, "name" STRING, hobby STRING);
insert into lml.student values (1,'tom','running');
insert into lml.student values (2,'jack','swimming');
export table lml.student to ‘nodelocal:///Users/lml’;
查看结果:
存在的问题:
- 若设置主键则会导致value值中没有主键字段的数据,并且不能确定字段的顺序
因为主键索引是在key中的(比如key=/Table/60/1/"tom"/88/0,这里"tom"/88就是双主键)。 - 目前只做到了对表的解析,没有做到对数据库的解析,如果是数据库,需要到出库下的所有表。
- 导出时没有等待的过程,是个异步操作,但是通常需要在前台显示进度,估计需要用到job。