CockroachDB开发学习文档02 实现export导出功能

在开始本次学习之前,我们假设你已经阅读过

https://github.com/cockroachdb/cockroach/blob/master/docs/codelabs/01-sql-statement.md

的创建自定义SQL语句教程,并成功完成编译运行。

目标:实现一个新的SQL语句,如EXPORT TO ,将指定的表数据并行导出到指定路径。

初始代码: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’;
    查看结果:


     

存在的问题:

 

  1. 若设置主键则会导致value值中没有主键字段的数据,并且不能确定字段的顺序
    因为主键索引是在key中的(比如key=/Table/60/1/"tom"/88/0,这里"tom"/88就是双主键)。
  2. 目前只做到了对表的解析,没有做到对数据库的解析,如果是数据库,需要到出库下的所有表。
  3. 导出时没有等待的过程,是个异步操作,但是通常需要在前台显示进度,估计需要用到job。

你可能感兴趣的:(Golang)