巨杉分布式数据库-学习笔记

巨杉分布式数据库-SCDA

各节点介绍 :
  • SQL节点,关于Sql节点的补充,在官方例图中并没有显示出sql节点,结合文档个人理解是在Sql实例中的,类似c3p0这类连接池,但是SQL节点的可以直接配置MySQL,PostgreSQL 和 SparkSQL 实例,综合性强;用于实现不同数据库实例的访问,个人在操作后得知sql节点相当于没有接入sdbsql驱动的数据库实例;

  • 协调节点进行数据路由,不存储任何用户数据。作为外部访问的接入与请求分发节点,协调节点将用户请求分发至相应的数 据节点,最终合并数据节点的结果应答对外进行响应。

  • 编目节点作为数据字典,主要存储系统的节点信息用户信息分区信息以及对象定义等元数据。在特定操作下,协调节点与数据节点均会向编目节点请求元数据信息,以感知数据的分布规律和校验请求的正确性。

    • 编目节点包括以下节点

    • SYSCAT: 系统编目集合空间,包含以下系统集合:

      集合名描述
      SYSCOLLECTIONS保存了该集群中所有的用户集合信息
      SYSCOLLECTIONSPACES保存了该集群中所有的用户集合空间信息
      SYSDOMAINS保存了该集群中所有用户域的信息
      SYSNODES保存了该集群中所有的逻辑节点与复制组信息
      SYSTASKS保存了该集群中所有正在运行的后台任务信息
    • SYSAUTH: 系统认证集合空间,包含一个用户集合,保存当前系统中所有的用户信息

      集合名描述
      SYSUSRS保存了该集群中所有的用户信息
    • SYSPROCEDURES: 系统存储过程集合空间,包含一个集合,用于存储所有的存储过程函数信息

      集合名描述
      STOREPROCEDURES保存所有存储过程函数信息
    • SYSGTS: 系统自增字段集合空间,包含一个集合,用于存储所有的自增字段信息

      集合名描述
      SEQUENCES保存所有自增字段信息

    除编目节点外,集群中所有其他的节点不在磁盘中保存任何全局元数据信息。当需要访问其他节点上的数据时,除编目节点外的其他节点需要从本地缓存中寻找集合信息,如果不存在则需要从编目节点获取。

    编目节点与其它节点之间主要使用编目服务端口(catalogname参数)进行通讯。

  • 数据节点为用户数据的物理存储节点,海量数据通过分片切分的方式被分散至不同的数据节点。在关系型与 JSON 数据库实例中每一条记录会被完整地存放在其中一个或多个数据节点中;而在对象存储实例中,每一个文件将会依据数据页大小被拆分成多个数据块,并被分散至不同的数据节点进行存放。

  • 资源管理节点:sdbcm它是一个守护进程,类是JVM里的daemon进程,Sequoiadb的所有集群管理和操作都需要参与,他的作用如下,摘选自官网:

    • 远程启动,关闭,创建和修改节点:通过 SequoiaDB 客户端或者驱动连接数据库时,可以执行启动,关闭,创建和修改节点的操作,该操作向指定节点物理机器上的 sdbcm 发送远程命令,并得到 sdbcm 的执行结果。
    • 本地监控:对于通过 sdbcm 启动的节点,都会维护一张节点列表,其中保存了所有本地节点的服务名和启动信息,如启动时间、运行状态等。如果某个节点是非正常终止的,如进程被强制终止,引擎异常退出等,sdbcm 会尝试重启该节点。
事务执行流程:

​ 1.协调节点发送事务;

​ 2.编目节点作为集群事务管理,分配事务号;

​ 3.数据节点以本地事务的方式执行事务;

数据库分布及个节点作用:

1. 1.1 1.2 1.3 各有一个主节点存储数据 (图中深色部分为主节点,浅色为复制节点)

  1. 1.4 1.5 1.6为实例接入服务器,Coord为上述的协调节点,负责数据路由(协调节点尽量在实例接入服务器内,不推荐走网络IO);

相关特性(A102)

高可用问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Y2qRsTO-1607938015427)(C:\Users\sdb\AppData\Roaming\Typora\typora-user-images\image-20201123141550851.png)]

事务能力

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hEytZaz-1607938015429)(C:\Users\sdb\AppData\Roaming\Typora\typora-user-images\image-20201123143359701.png)]

容灾

SequoiaDB巨杉数据库使用集群切分与归并功能,能够在同城双中心的环境中进行秒级集群分裂,将原本处于两个数据中心内的单集群分裂为两个独立部署的集群,保证在存活数据中心内的数据服务能够以秒级启动并提供完整的数据库读写服务,同时保证交易数据的稳定可靠,做到秒级 RTO、RPO=0。

安装(A301)

过程

  • 需要3台物理机/虚拟机,本md采用虚拟机形式;

  • 将每一台虚拟机防火墙关闭;

firewall-cmd --state #查看当前防火墙状态
systemctl stop firewalld.service#禁用防火墙
systemctl disable firewalld.service#关闭防火墙
  • 将每一台虚拟机的hostname分别改为:sdb1,sdb2,sdb3;

    http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1432191002-edition_id-500

     ./sequoiasql-mysql-5.0-linux_x86_64-installer.run --mode text 
    

默认安装目录:/opt/sequoiadb

默认端口:11790

默认帐号密码:sdbadmin

巨杉数据库事例

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-paz7szmW-1607938015446)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606184164429.png)]

所支持实例(A401-403)

关系型

  • mysql(OLTP,联机事务处理)
  • postgreSQL(OLTP,OLAP,联机事务处理和联机分析处理)
  • Sparksql(OLAP)
  • S3(OLTP)
MySQL:

​ 实例管理工具:sdb_sql_ctl;

​ 工具命令行:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lobguOiZ-1607938015446)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606267995652.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-36AVQo0R-1607938015447)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606268033255.png)]

命令:

sdb_sql_ctl start (实例名称) :启动实例

sdb_sql_ctl status (实例名称):查看实例状态

默认存储引擎:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9h22146A-1607938015448)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606269086857.png)]

关于系统架构

复制
复制组原理(复制组是数据节点):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pOA34ovp-1607938015449)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606278629817.png)]

主节点

​ 主节点是唯一接受复制组的写操作成员,发生写操作的时候,主节点写入数据,并将记录写入replicalog,备份节点从主节点异步复制replicalog,通过释放replicalog来复制数据;

备节点

​ 备节点持有主节点数据的副本,一个复制组可以有多个备节点。

事物日志-replicalog

​ 文件的大小和个数可以通过 logfileszlogfilenum 参数分别进行设置。默认日志文件大小为 64MB(不包括头大小),日志个数是 20 个。

用户可以通过 sdbdpsdump 工具查看到写入的事务日志。例如,插入一条记录,用工具查看事务日志.

数据复制:
增量同步:

​ 在数据节点和编目节点中,任何增删改操作均会写入日志。节点会将日志写入日志缓冲区,然后再异步写入本地磁盘

​ 数据复制在两个节点间进行:

  • 源节点:含有新数据的节点
  • 目标节点:请求进行数据复制的节点

目标节点会选择一个与其数据最接近的节点,然后向它发送一个复制请求。源节点收到复制请求后,会打包目标节点请求的同步点之后的日志,并发送给目标节点。目标节点接收到同步数据包后,会重放事务日志中的操作。

节点之前的复制有两种状态:

  • 对等状态(Peer):目标节点请求的日志,存在于源节点的日志缓冲区
  • 远程追赶状态(Remote Catchup):目标节点请求的日志,不存在于源节点的日志缓冲区中,但存在于源节点的日志文件中

如果目标节点请求的日志,已经不存在于源节点的日志文件中,目标节点则进入全量同步状态。

全量复制:

以下情况需要进行全量同步:

  • 一个新的节点加入复制组
  • 节点故障导致数据损坏
  • 节点日志远远落后于其他节点,即当前节点的日志已经不存在于其他节点的日志文件中

全量同步在两个节点间进行:

  • 源节点:指含有有效数据的节点,全量同步的源节点必定是主节点
  • 目标节点:指请求进行全量同步的节点,全量同步时,该节点下原有的数据会被废弃
节点选举:

当主节点发生故障,如主节点所在的机器宕机,其余节点一段时间内收不到主节点心跳后就会发起复制组选举。所有的备节点会进行投票,日志最接近原先主节点的备节点会成为新的主节点。在选出主节点之前,复制组无法提供写操作服务。当组内成员不足半数,主节点会自动降级为备节点,同时断开主节点的所有用户连接。

采用了Raft算法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5AFo66SQ-1607938015452)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606291990306.png)]

脑裂操作:takeover工具

选举机制(序列号优先级由上往下):
  1. LSN-事务版本号,越大版本号优先级越大;
  2. weight-权重,大的优先;
  3. NodeId-节点号,大的优先;
主备一致性:

当发生写操作时,数据库会确保所有复制组节点都同步完成才返回。写操作处理成功后,后续读到的数据一定是当前复制组内最新的。优势是能够有效得保证数据的完整性和安全性,劣势则是会降低复制组的写入性能,并且当集群内有一个节点故障或者异常时,无法写入数据,降低高可用性。集合的 ReplSize 参数描述了在写操作返回成功之前,写操作执行成功了的节点个数。可以将 ReplSize 设为 0,或者设为复制组节点个数。以下以复制组 3 副本为例。强一致性示意图

关于Replsize:
  • 集合的 ReplSize 参数描述了在写操作返回成功之前,写操作执行成功了的节点个数。可以将 ReplSize 设为 0,或者设为复制组节点个数。以下以复制组 3 副本为例。
  • 创建集合默认是 ReplSize 为 1。
  • 复制组为 3 副本,大多数为 ( n - 1 ) / 2,即 ReplSize 设为 2.
复制组健康快照:

var db=new Sdb('localhost',11810)//连接协调节点
db.snapshot(SDB_SNAP_HEALTH,{GroupName:"group1"})//查看复制组 group1 的节点健康状态

复制组同步状态

  • IsPrimary:该节点是否为复制组的主节点
  • BeginLSN:在事务日志文件中记录的第一条 LSN
  • CurrentLSN:该节点当前处理的事务日志 LSN
  • CommittedLSN:该节点已刷盘的事务日志 LSN
  • CompleteLSN:备节点已重放完成的事务日志 LSN
  • LSNQueSize:备节点待重放的事务日志数量
  • DiffLSNWithPrimary:该节点与主节点的 LSN 差异。备节点在计算与主节点的 LSN 差异时,所取的主节点 LSN 可能是一个心跳间隔前的,因此 DiffLSNWithPrimary 可能与实际值存在一定偏差。
  • SyncControl:该节点是否处于同步控制。默认情况下,当主备节点 LSN 差距过大时,为避免引发备节点的全量同步,主节点会主动降低处理操作的速度。用户可以通过配置 syncstrategy 参数来修改同步控制的策略。
分区:

一个分区只存在一个复制组,一个复制组可以存在多个分区;

创建集合空间时候,如果不加入分区参数,分区的集合可能会存放到一个复制组里;

  1. 分区内的所有数据记录都是完整的记录
  2. 一个分区只能映射一个子集合
  3. 子集合可以通过挂在操作,将分区从一个子集映射到另一个子集;
  4. 当需要访问某个特定范围内的记录时,只会访问所属分区的子集合,避免访问所有分区数据,从而减少了数据访问量;(减少不必要的IO )

关于分区2种方式:

分区键:每个分区键可以包括一个或者多个字段;

范围分区
  • 分区键是作为划分范围的字段,对集合中的数据进行切分的分区方式。
  • 如下图所示,步长为100/一年作为一个分区范围
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CibkMilC-1607938015455)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606352592676.png)]
散列分区
  • 分区键用来计算hash值的字段,先对集合数据做散列运算 (时间复杂度:O(n));
  • 再根据散列数据的hash值做切分分区,经过hash出来的数据量基本相同,在遍历时候,各节点的并行计算能力,IO负载能力基本一致;

注意:
  1. 在字段取值相对离散的情况下(如集合中的唯一键),通过散列分区方式,每个 hash 值对应的数据量基本相同。而在范围分区方式中,相同范围内的数据量不一定是相同的。
  2. 不同的分区类型可以选择使用不同的分区方式去划分数据。数据库分区既可以使用范围分区方式,也可以使用散列分区方式,而表分区只能使用范围分区方式
数据库分区实操

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tqgs5XMl-1607938015456)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606701767089.png)]

创建集合 business.orders_2019 ,分区键为 id 字段,分区方式为 hash ,集合所在复制组为 prod_part1:

> db.createCS( "business" )
> db.business.createCL( "orders_2019", { ShardingKey: { id: 1 }, ShardingType: "hash", Group: "prod_part1" } )
> db.business.orders_2019.split( "prod_part1", "prod_part2", { id: 2048}, { id: 4096} )

执行切分操作,将集合 business.orders_2019 中,字段 id 的 hash 值范围在 [2048, 4096) 的记录,从复制组 prod_part1 切分到复制组 prod_part2 中:

> db.business.orders_2019.split( "prod_part1", "prod_part2", { id: 2048}, { id: 4096} )
db.snapshot( SDB_SNAP_CATALOG, { Name: "business.orders_2019" } )
{
...
"Name": "business.orders_2019",
"ShardingType": "hash",
"ShardingKey": {
"id": 1
}
"Partition": 4096,
"CataInfo": [
{
  "ID": 0,
  "GroupID": 1000,
  "GroupName": "prod_part1",
  "LowBound": {
    "": 0
  },
  "UpBound": {
    "": 2048
  }
},
{
  "ID": 1,
  "GroupID": 1001,
  "GroupName": "prod_part2",
  "LowBound": {
    "": 2048
  },
  "UpBound": {
    "": 4096
  }
}
]
}
表分区实操:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYwN5TMG-1607938015457)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606702395769.png)]

创建集合 business.orders ,指定为主集合,分区键为 create_date 字段,分区方式为 range:

> db.business.createCL( "orders", { IsMainCL: true, ShardingKey: { create_date: 1 }, ShardingType: "range" } )
> db.business.orders.attachCL( "business.orders_2018", { LowBound: { create_date: "201801" }, UpBound: { create_date: "201901" } } )
> db.business.orders.attachCL( "business.orders_2019", { LowBound: { create_date: "201901" }, UpBound: { create_date: "202001" } } )
范围分区键

使用范围分区方式做数据分区时,分区键格式如下:

{
  ShardingKey: { <字段1>: <1|-1>, [<字段2>: <1|-1>, ...] },
  ShardingType: "range"
}

Copy

  • 可以指定多个字段做为分区键
  • 对于每个字段可以指定其值为 1 或者 -1 ,表示正向或是逆向排序

范围分区方式的分区键一般选择具有序列性的字段,比如时间字段。

> db.business.createCL( "orders", { ShardingKey: { create_date: 1 }, ShardingType: "range", Group: "group1" } )
散列分区键
格式说明

使用散列分区方式做数据分区时,分区键格式如下:

{
  ShardingKey: { <字段1>: <1>, [<字段2>: <1>, ...] },
  ShardingType: "hash",
  Partition: <分区数>
}

Copy

  • 可以指定多个字段做为分区键。
  • 散列分区方式中字段没有正向或是逆向的属性
  • Partition 必须是 2 的幂,范围在[ 23 , 220 ],默认为 4096
示例

散列分区方式的分区键一般选择具有关键属性的字段,比如用户 id 字段。

> db.business.createCL( "orders2", { ShardingKey: { id: 1 }, ShardingType: "hash", Partition: 4096, Group: "group1" } )
水平分区:

水平分区:用户可以通过将一个集合中的数据切分到多个复制组中,以达到并行计算的目的。

垂直分区:

垂直分区:用户也可以将一个集合全局关系的属性分成若干子集,并在这些子集上作投影运算,将这些子集映射到另外的集合上,从而实现集合关系的垂直切分.

多维分区:

多维分区是指将集合先通过垂直分区映射到多个子集合中,再通过水平分区将子集合切分到多个复制组中的方式。

多维分区的优势:

通常流水类数据选择创建多维分区表进行存放,把不同时间段的数据分布在不同的数据组。多维分区表的好处有:

1)当访问某时间范围的数据能够直接定位到子分区,避免扫描全表数据从而降低 IO。

2)在集群扩容时,把扩展的子表创建在新的机器,无需执行rebalance的操作即可完成表存储空间的扩容。

请点击右侧选择使用的实验环境

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gTIq7uIu-1607938015458)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606703398815.png)]

  • 对主集合进行表分区,将多个分区映射到不同的子集合上
  • 针对某一个子集合,使用数据库分区,将子集合中的数据切分到不同的数据组中
  • 当需要访问某一范围内的数据时,既可以将数据访问集中在若干个子集合中,又能同时发挥不同复制组并行计算的能力,从而提高处理速度和性能
关于数据域/逻辑域

数据域(Domain)是指由若干个复制组组成的逻辑单元,其主要作用是数据隔离。

  • 一个复制组可以属于多个域。

  • 复制组个数为0的域,称作空域。用户在空域中不能创建集合空间。

  • SYSDOMAIN 为预定义的系统域。所有复制组均属于系统域,用户不能直接操作系统域。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JIjBcEjg-1607938015459)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606704052800.png)]

db.dropDomain("company_domain");

删除域前必须保证域中不存在任何数据。

db.createDomain("company_domain", [ "group1", "group2", "group3" ], { AutoSplit: true } );//创建逻辑域
db.createCS("company", { Domain: "company_domain" } );//将创建的集合空间加入到逻辑域
db.getDomain("company_domain").removeGroups( { Groups: [ 'group4' ] } );//移除逻辑域
注意:
db.company.createCL("employee", { "ShardingKey": { "_id": 1}, "ShardingType": "hash", "ReplSize": -1, "Compressed": true, "CompressionType": "lzw", "AutoSplit": true, "EnsureShardingIndex": false } );

在创建集合时候开启AutoSplit;

关于shell编程

基本命令:

交互性命令:
	//有点类似Mongodb的语言
var db=new Sdb() //建立数据库
var cs=db.createCS("emp") //建立集合空间 CollectSpace
db.emp.createCL("employees") //创建employees集合,注意:emp属性在上一条属性自动生成;
db.emp.employees.insert({"emo_no":1001,"birth_date":"19950130","first_name":"Albert","last_name":"Wenty","gender":"M","hire_date":"2018-11-12"})
db.emp.employees.find({"emo_no":1001})
嵌入式命令:
	./sdb '<sequoiadb语句>'  #直接通过该语句进行对内操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sr87NqRq-1607938015460)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606356150295.png)]

js脚本模式

我们编写一个js的脚本查询1001的员工:test.js

var db=new Sdb();//建立数据库对象
var cs=db.getCS("emp");//获取数据库emp数据集对象
var cl=cs.getCL("employees");//获取数据集的集合对象
var condition={"emo_no":1001};//编写查询对象信息,类似mybatis+的wrapper
var result =cl.find(condition);//获取结果集
while(result.next()){ //遍历结果集
   var single =result.current().toString();
   println(single);

}
result.close();//关闭结果集对象
db.close();//关闭数据库连接
                                 

使用 SequoiaDB Shell 的 -f 命令参数指定执行 test.js 脚本

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ro5ehGtH-1607938015461)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606357416338.png)]

关于SDB各节点的操作

​ 我们可以在/opt/sequoiadb/bin(默认安装路径)中找到

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HTm6TbSI-1607938015461)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606358652258.png)]

fap sdbbp sdbcm sdbcmd sdbdmsdump sdbexprt sdbimprt sdblist sdbomtool sdbreplay sdbseadapter sdbstop sdbwsart sequoiadb stpq stpstop sdb sdbbp.log sdbcmart sdbcmtop sdbdpsdump sdbfmp sdbinspect sdblobtool sdbpasswd sdbrestore sdbstart sdbtop sdbwstop stp stpstart

Sql节点:

​ 进入/opt/sequoiasql/<实例>/bin后

创建SQL节点:
./sdb_sql_ctl addinst myinst -D pg_data/ 
./sdb_sql_ctl start myinst 
./sdb_sql_ctl status myinst
./sdb_sql_ctl listinst 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zNwF39dg-1607938015462)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606371412270.png)]

在SAC上添加刚才所创建的实例:

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U5TWhWaI-1607938015462)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606371735235.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TtV9J7ej-1607938015464)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606371758499.png)]

添加成功!

对接DB引擎(命令行):
./sdb_sql_ctl createdb sample myinst
./psql -p 5432 sample 进入pgsql
sample=# create extension sdb_fdw;
sample=#create server sdb_server foreign data wrapper sdb_fdw options(address '127.0.0.1', service '11810', user 'sdbadmin', password 'sdbadmin', preferedinstance 'A', transaction 'off');

这样就可以将sql节转成pgsql的实例了

协同节点

对于操作协同节点我们得通过资源管理节点sdbcm来操作,但是我们实际操作得进入sdb内操作

我们在上述知道 sdbcm所在位置在**:/opt/sequoiadb/bin**(默认安装目录)

创建临时协调节点
./sdb #进入sdb命令行
var oma =new Oma("sdb1",11790)//链接到sdbcm
oma.createCoord(,) //创建临时协调节点
oma.startNode(18800)//开跑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JZLNRyf0-1607938015465)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606373589905.png)]

创建协调节点组和协调节点

假设现在有一个现成的协同节点组在hostname1上,我们去获取他的协调节点

var db=new Sdb("hostname1",11810)
var rg=db.getCoordRG() //返回指定分区组的引用

参考Sdb方法大全

在hostname2机器上建立新的协同节点

var node =rg.createNode("hostname2",11810,"/opt/sequoiadb/database/coord/11810")

编目节点:

​ 编目节点在这个数据库结构起到非常重要的角色;

​ 编目节点不保存用户数据

db.createCataRG(<host>,<service>,<dbpath>,[config])

官方参数解析

注意:

  • 在编目节点事务默认开启
  • 如果var db=new Sdb(“主机号”,协调节点端口),不知道节点组端口可以通过SAC配置下查看;
  • 在访问其他节点是得用协调节点的sdb对象访问;
var cataRG = db.getCatalogRG()
var node1 = cataRG.createNode( <host>, <service>, <dbpath>, [config] )//创建一个新的编目节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIxPbDeh-1607938015466)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606376841527.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tuiPVLXm-1607938015466)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606376856578.png)]

数据节点:

建立节点组:
var db=new Sdb("sdb1",11810) //创建连接对象
var dataRG=db.createRG("TESTRG") 
dataRG.createNode("sdb3",11850,"/opt/sequoiadb/database/data/11850")
  • host:指定数据节点的主机名;
  • service:指定数据节点的服务端口;用户需确保该端口号,以及往后延续的五个端口号未被占用。如设置为11820,请确保11820/11821/11822/11823/11824/11825端口都未被占用;
  • dbpath:数据文件路径用于存放数据节点的数据文件,需确保数据管理员(安装时创建,默认为sdbadmin)用户有写权限;
  • config:该参数为可选参数,用于配置更多细节参数,格式必须为 json 格式,参数参见数据库配置一节;如需要配置日志大小参数{logfilesz:64}。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AjYcGJgq-1607938015467)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606379663908.png)]

创建成功!

我们看看SAC

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zE4tfDia-1607938015469)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606379780116.png)]

通过数据节点创建复制组
var rg=db.getRG("")

var node=rg.createRG("copyTestRG")

rg.createNode("sdb1",11910,"/opt/sequoiadb/database/data/11910",{weight:20})//作为master节点

rg.createNode("sdb2",11920,"/opt/sequoiadb/database/data/11920")

rg.createNode("sdb3",11930,"/opt/sequoiadb/database/data/11930")
rg.start();

资源管理节点:

​ 关于sdbcm我们就不多赘述;

​ sdbcm是无法通过sdb获取对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2ZwHK6E-1607938015470)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606380531684.png)]

关于事务:(11.30)

语句:http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1432190808-edition_id-500
db.transBegin();//开启事务
db.transCommit();
db.transCommit();

transisolation 参数为事务隔离级别,默认是 0 。取值列表:

  • 0: RU,读未提交。
  • 1: RC, 读已提交。
  • 2: RS,读稳定性。
  • 3: RR, 可重复

db.snapshot(SDB_SNAP_CONFIGS, {}, { NodeName: “”, transisolation: “”, transactionon: “” } );

终端1”设置事务隔离级别为1,1代表读已提交;

db.updateConf( { transisolation: 1 }, { Global: true } );

Note:

  • transisolation参数指定隔离级别,为在线生效。
  • Global为true表示对所有节点生效。

关于数据库快照

sdblist #sdblist工具 查看所有节点信息 C: 编目节点,S:协调节点,D:数据节点

如何使用sequoiadb快照:

var db=new Sdb("localhost",11810) #1.连接协调节点
db.snapshot(<参数>)#通过协调节点对象+参数获取当前的快照
参数列表
快照标示快照类型
SDB_SNAP_CONTEXTS上下文快照
SDB_SNAP_CONTEXTS_CURRENT当前会话上下文快照
SDB_SNAP_SESSIONS会话快照
SDB_SNAP_SESSIONS_CURRENT当前会话快照
SDB_SNAP_COLLECTIONS集合快照
SDB_SNAP_COLLECTIONSPACES集合空间快照
SDB_SNAP_DATABASE数据库快照
SDB_SNAP_SYSTEM系统快照
SDB_SNAP_CATALOG编目信息快照
SDB_SNAP_TRANSACTIONS事务快照
SDB_SNAP_TRANSACTIONS_CURRENT当前事务快照
SDB_SNAP_ACCESSPLANS访问计划缓存快照
SDB_SNAP_HEALTH节点健康检测快照
SDB_SNAP_CONFIGS配置快照
SDB_SNAP_SVCTASKS服务任务快照
SDB_SNAP_SEQUENCES序列快照

关于备份的操作

全面备份

var db=new Sdb("localhost",11810)
db.backup({Name:"cluster_backup",Path:"/tmp/%g",Overwrite:true,Description:"full ackup"})

Path 中的 “%g”是一个通配符代表group name,当在协调节点上执行命令使用该参数时,需要使用通配符,以避免所有的节点往同一个路径下进行操作而导致未知IO错误。其中overwrite:true 为开启全量备份

增量备份

db.backup( { Name: "cluster_backup", Path: "/tmp/%g", EnsureInc: true } );

其中EnsureInc:true为开启增量备份

恢复操作

db.dropCS("company")#模拟删除集合空间
quit
sdbstop -t all#恢复前暂停所有
sdbrestore -p /tmp/SYSCatalogGroup/ -n cluster_backup -b 0 -i 0
sdbrestore -p /tmp/group1/ -n cluster_backup -b 0 -i 0
sdbrestore -p /tmp/group2/ -n cluster_backup -b 0 -i 0
sdbrestore -p /tmp/group3/ -n cluster_backup -b 0 -i 0#增量恢复

-b 后面带的参数代表需要从第几次备份开始恢复,从 0 开始算起,缺省由系统自动计算 ( -1 )。

-i 后面带的参数代表需要恢复到第几次数据备份,从 0 开始算起,缺省恢复到最后一次 ( -1 )。

工具

关于sdbtop的使用

步骤

su sdbadmin#切换到sdbadmin 
sdbtop -i localhost -s 11810

关于sdbtopd的参数

sdbtop监控数据库状态

在 SequoiaDB 安装目录 bin 中执行:sdbtop –h 显示参数信息

参数缩写描述
–help-h返回基本帮助和用法文本
–version-vsdbtop版本信息
–confpath-csdbtop 的配置文件,sdbtop 界面形态以及输出字段都依赖该文件(缺省使用默认配置文件)
–hostname指定需要监控的主机名
–servicename指定监控的端口服务名
–usrname数据库用户名
–password数据库密码
–ssl使用 SSL 连接。

关于sdbtop的快捷键=

主窗口选择快捷键说明:

参数描述
m返回主窗口
s列出数据库节点上的所有会话
c列出数据库节点上的所有集合空间
t列出数据库节点上的系统资源使用情况
d列出数据库节点的数据库监视信息

进入主窗口后快捷操作键说明:

参数描述
Gglobal_snapshot,监控所有的数据节点组
ggroup_snapshot,指定监控某个数据节点组
nnode_snapshot,列出指定的数据库节点的监视信息
r设置刷屏的时间间隔,单位秒/s
A将监视信息按照某列进行顺序排序
D将监视信息按照某列进行逆序排序
C将监视信息按照某个条件进行筛选
Q返回没有使用条件进行筛选前的监视信息
N将监视信息中对应行号的记录过滤不显示
W返回没有使用行号进行过滤前的监视信息
h查看使用帮助
Esc取消已进入的操作
Enter返回上一次监视界面,(在已进入 help 帮助输出中有效)
F5强制刷新后台监视信息
<向左移动,以查看隐藏的左边列的监视信息
>向右移动,以查看隐藏的右边列的监视信息
q退出程序
Tab切换数据计算的模式(绝对值,平均值,差值三个模式)

关于实例管理工具:

​ 我们可以通过在**/opt/sequoiadbsql/<实例>/bin**中找到sdb_xxx_ctl;

例子:Postgresql

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3yF9mrmZ-1607938015471)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606359233587.png)]

参数说明,复制与官方http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1576573830-edition_id-500

关于语句:

语句参数作用
addinst <-D DATADIR> [-l LOGFILE] [–print] [-p PORT] [-f PIDFILE] [-s SOCKETFILE] [-w PASSWORD]添加/创建实例
start [–print]开启实例
status查看实例状态
restart重启实例
stop[–print]停止实例
delinst [–baklog]删除实例
listinst-查看现有实例
startall-启动所有实例
stopall-停止所有实例
chconf [-p PORT] [-e LEVEL] [-a MAX-CON] [–sdb-conn-addr=ADDR] [–sdb-user=USER] [–sdb-passwd=PASSWD] [–sdb-auto-partition=BOOL] [–sdb-use-bulk-insert=BOOL] [–sdb-bulk-insert-size=SIZE] [–sdb-use-autocommit=BOOL] [–sdb-debug-log=BOOL] [–sdb-token=TOKEN] [–sdb-cipherfile=PATH] [–sdb-error-level=ENUM] [–sdb-replica-size=SIZE] [–sdb-use-transaction=BOOL] [–sdb-optimizer-options=SET] [–sdb-rollback-on-timeout=BOOL] [–sdb-execute-only-in-mysql=BOOL] [–sdb-selector-pushdown-threshold=THRESHOLD] [–sdb-alter-table-overhead-threshold=THRESHOLD]修改实例配置

*关于chconf的参数详细可以参考官网文档 *

例子:

​ 添加一个 myinst 的实例,指定数据库存储路径为 database/3306/,指定密码为 123456

sdb_mysql_ctl addinst myinst -D database/3306/ -l database/myinst.log --print -p 3306 -f database/myinst.pid -s database/myinst.sock -w 123456 

​ 修改 myinst 实例的 SequoiaDB 连接地址

sdb_mysql_ctl chconf myinst --sdb-conn-addr=sdbserver1:11810,sdbserver2:11810
#修改是可能要求root密码

参数说明

参数描述是否必填
-h返回帮助说明
-D指定数据库储存路径
-l指定日志文件,默认在安装路径下,与实例名同名
-p指定 MySQL 服务的监听端口,默认为 3306
-f指定 pid 文件,默认为数据库储存路径下的 mysqld.pid
-s指定 mysqld.sock 文件,默认为数据库储存路径下的 mysqld.sock
-w指定本地连接 root 用户的密码
-a客户端最大连接数,默认为 1024
-e错误日志级别,默认为 3
-v输出版本信息
–print打印日志信息
–baklog删除实例时是否备份日志文件

关于mysql工具:

mydumper和mysqlpump:

mysqlpumpmysqldump一样,属于逻辑备份,备份以SQL形式的文本保存。逻辑备份相对物理备份的好处是不关心undo log的大小,直接备份数据即可。它最主要的特点是:

  • 并行备份数据库和数据库中的对象的,加快备份过程。
  • 更好的控制数据库和数据库对象(表,存储过程,用户帐户)的备份。
  • 备份用户账号作为帐户管理语句(CREATE USER,GRANT),而不是直接插入到MySQL的系统数据库。
  • 备份出来直接生成压缩后的备份文件。
  • 备份进度指示(估计值)。
  • 重新加载(还原)备份文件,先建表后插入数据最后建立索引,减少了索引维护开销,加快了还原速度。
  • 备份可以排除或则指定数据库。

mysqlpump:

  • 轻量级C语言写的
  • 多线程备份,备份后会生成多个备份文件
  • 事务性和非事务性表一致的快照(适用于0.2.2以上版本)
  • 快速的文件压缩
  • 支持导出binlog
  • 多线程恢复(适用于0.2.1以上版本)
  • 以守护进程的工作方式,定时快照和连续二进制日志(适用于0.5.0以上版本)
  • 开源 (GNU GPLv3)

关于SequoiaFS

使用例子

SequoiaFS 实例将集合 fscl 作为文件系统挂载到 /opt/sequoiafs/mountpoint 目录。

Note:

/opt/sequoiafs/mountpoint 目录只是本章节用于测试的例子,在实际环境中使用时可根据系统架构调整修改。

1)创建挂载点 mountpoint;

mkdir -p /opt/sequoiafs/mountpoint

2)创建 SequoiaFS 的配置文件目录和日志目录;

mkdir -p /opt/sequoiafs/conf/fscs_fscl/001/
mkdir -p /opt/sequoiafs/log/fscs_fscl/001/

3)产生一个空配置文件,SequoiaFS 服务在启动时会将指定的值写入该文件中,其他参数使用缺省值;

touch /opt/sequoiafs/conf/fscs_fscl/001/sequoiafs.conf

关于实例的操作-SCDP

Mysql

创建mysql实例

./opt/sequoiasql/mysql/bin/sdb_sql_ctl addinst myinst -D database/3306 #创建实例
./opt/sequoiasql/mysql/bin/sdb_sql_ctl status #实例状态

查看auto.cnf

cat /opt/sequoiasql/mysql/database/3306/auto.cnf<< EOF
secure_file_priv = "/opt/sequoiasql/mysql/tmp"
EOF

配置参数有三种修改方式:

  • 使用工具 sdb_sql_ctl 修改配置,配置生效需重新启动 MySQL 服务。例如: bin/sdb_sql_ctl chconf myinst --sdb-auto-partition=OFF
  • 修改实例数据目录下的配置文件 auto.cnf,在 [mysqld] 下添加/更改对应配置项,配置生效需重新启动 MySQL 服务。例如: sequoiadb_auto_partition=OFF
  • 通过 MySQL 命令行修改,配置临时有效,当重启MySQL服务后配置将失效。例如: SET GLOBAL sequoiadb_auto_partition=OFF ;

配置实例

bin/sdb_sql_ctl chconf myinst --sdb-conn-addr=sdbserver1:11810,sdbserver2:11810

需要巩固语句:

CREATE USER 'metauser'@'%' IDENTIFIED BY 'metauser'; #创建用户
GRANT ALL ON *.* TO 'metauser'@'%';#授权用户权限
FLUSH PRIVILEGES;#刷新权限
创建分区表(12.01)

在 SequoiaSQL-MySQL 实例中创建的表将会默认使用 SequoiaDB 数据库存储引擎,包含主键或唯一键的表将会默认以唯一键作为分区键,进行自动分区。

1)在 MySQL 实例的 company 数据库中创建数据表 employee;

CREATE TABLE employee 
(
    empno INT,
    ename VARCHAR(128),
    age INT,
    PRIMARY KEY (empno)
) ENGINE = sequoiadb COMMENT = "雇员表, sequoiadb: { table_options: { ShardingKey: { 'empno': 1 }, ShardingType: 'hash', 'Compressed': true, 'CompressionType': 'lzw', 'AutoSplit': true, 'EnsureShardingIndex': false } }";

关于mysql审计工具(12.01)

[用于查询每个数据库用户操作]

使用前需要将/opt/sequoiasql/mysql/tools/lib/server_audit.so 拷贝到/mysql/lib/plugin

cp /opt/sequoiasql/mysql/tools/lib/server_audit.so /opt/sequoiasql/mysql/lib/plugin/
审计插件配置

1)修改 MySQL 实例的配置文件;

echo 'plugin-load=server_audit=server_audit.so' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_logging=ON' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_file_path=/opt/sequoiasql/mysql/database/auditlog/server_audit.log' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_file_rotate_now=OFF' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_file_rotate_size=10485760' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_file_rotations=999' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_output_type=file' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 
echo 'server_audit_query_log_limit=102400' >> /opt/sequoiasql/mysql/database/3306/auto.cnf 

Note:

  • add server_audit.so config :加载审计插件;
  • plugin-load=server_audit=server_audit.so :审计记录的审计,建议只记录需要同步的DCL和DDL操作 server_audit_events=CONNECT,QUERY_DDL,QUERY_DCL ;
  • server_audit_logging=ON :开启审计;
  • server_audit_file_path=/opt/sequoiasql/mysql/database/auditlog/server_audit.log :审计日志路径及文件名 ;
  • server_audit_file_rotate_now=OFF :强制切分审计日志文件 ;
  • server_audit_file_rotate_size=10485760 :审计日志文件大小10MB,超过该大小进行切割,单位为byte ;
  • server_audit_file_rotations=999 :审计日志保留个数,超过后会丢弃最旧的 ;
  • server_audit_output_type=file : 输出类型为文件 ;
  • server_audit_query_log_limit=102400 :限制每行查询日志的大小为100kb,若表比较复杂,对应的操作语句比较长,建议增大该值 ;

2)创建审计日志存放的文件夹;

mkdir /opt/sequoiasql/mysql/database/auditlog/
重启 MySQL 实例并检查审计日志

1)检查 MySQL 实例;

/opt/sequoiasql/mysql/bin/sdb_sql_ctl listinst

2)重启 MySQL 实例;

/opt/sequoiasql/mysql/bin/sdb_sql_ctl restart myinst

3)检查 MySQL 实例进程;

/opt/sequoiasql/mysql/bin/sdb_sql_ctl listinst

4)检查审计日志文件目录,确保生成了审计日志文件 server_audit.log;

ls -alt /opt/sequoiasql/mysql/database/auditlog/

元数据同步工具配置(用于多服务元数据同步)

1)拷贝生成一份元数据同步工具的配置文件;

cp /opt/sequoiasql/mysql/tools/metaSync/config.sample /opt/sequoiasql/mysql/tools/metaSync/config

2)进行元数据同步工具配置文件修改;

sed -i 's/hosts = sdb1,sdb2,sdb3/hosts = sdbserver1,sdbserver2/g' /opt/sequoiasql/mysql/tools/metaSync/config

3)确认配置文件 hosts 参数是否为 sdbserver1,sdbserver2 ;

cat /opt/sequoiasql/mysql/tools/metaSync/config

4)拷贝一份元数据同步的日志配置文件同步工具使用 python 的 logging 模块输出日志,配置文件为 log.config。如果是全新安装,开始该文件是不存在的,需要从 log.config.sample 拷贝。配置项如下(日志目录会自动创建);

cp /opt/sequoiasql/mysql/tools/metaSync/log.config.sample /opt/sequoiasql/mysql/tools/metaSync/log.config
启动元数据同步工具

1)在完成所有配置后,在各实例所在主机的 sdbadmin 用户下,执行以下命令在后台启动同步工具;

python /opt/sequoiasql/mysql/tools/metaSync/meta_sync.py &

2)可以通过配置定时任务提供基本的同步工具监控,定期检查程序是否在运行,若进程退出了,会被自动拉起。配置命令如下(在 SequoiaSQL-MySQL 安装用户下配置);

crontab -e

3)去到最后一行按 i 然后添加以下内容;

#每一分钟运行一次
*/1 * * * * /usr/bin/python /opt/sequoiasql/mysql/tools/metaSync/meta_sync.py >/dev/null 2>&1 &

4)添加后按 Esc 键输入 :wq 进行保存退出;

5)linux 系统后台进程作业配置检查,最后一行可以显示上一步骤输入内容;

crontab -l
关于SDBSQL的mysql事务管理

MySQL 实例的事务是基于 SequoiaDB 巨杉数据库存储引擎的,如果需要 MySQL 实例支持事务,存储引擎也必须开启事务,本小节将讲解如何查看并关闭 MySQL 的事务功能,并对关闭事务功能后的 MySQL 实例进行验证。

查看 MySQL 是否已打开事务;

SHOW VARIABLES LIKE '%sequoiadb_use_transaction%';

通过Sequoiadb关闭mysql事务:

cat >> /opt/sequoiasql/mysql/database/3306/auto.cnf << EOF
sequoiadb_use_transaction = OFF
EOF
/opt/sequoiasql/mysql/bin/sdb_sql_ctl restart myinst#需要重启

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SQxRWiO-1607938015473)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606878925641.png)]

关于导出CSV

导出导入参数配置

1)在 auto.cnf 文件中加入导入导出路径的参数配置;

cat >> /opt/sequoiasql/mysql/database/3306/auto.cnf << EOF
secure_file_priv = "/opt/sequoiasql/mysql/tmp"
EOF

2)创建存放数据路径;

mkdir /opt/sequoiasql/mysql/tmp

Note:

secure_file_priv默认为NULL, 表示不允许导入导出操作,需要在配置文件中进行更改。

3)重启 MySQL 数据库实例;

/opt/sequoiasql/mysql/bin/sdb_sql_ctl restart myinst
/opt/sequoiasql/mysql/bin/mysql -h 127.0.0.1 -P 3306 -u root#进mysql

导出csv

SELECT * FROM xxx   
INTO OUTFILE '/opt/sequoiasql/mysql/tmp/xxx.csv'   
FIELDS TERMINATED BY ','		//逗号分割
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '"' //跳过
LINES TERMINATED BY '\r\n'; //每行以回车换行结束

关于mysqldump导出sql文件

mysqldump 工具导入

1)mysqldump 工具导出,路径为(/opt/sequoiasql/mysql/tmp/employee_import_test.sql);

/opt/sequoiasql/mysql/bin/mysqldump -h 127.0.0.1 -u root   company employee_import_test > /opt/sequoiasql/mysql/tmp/employee_import_test.sql

Note:

mysqldump 导出的是 SQL 逻辑执行语句, 其有比较多的参数命令,可通过 mysqldump --help 罗列其中的参数进行查看

2)mysqldump 导出后生成的文件是sql语句的集合,可以直接执行;

SOURCE /opt/sequoiasql/mysql/tmp/employee_import_test.sql;

PostgreSQL (12.01-12.02)

创建PGSQL实例先创建sdb的数据域

  1. 在数据域中创建CS,在创建CL
  2. 再用sdb_sql_ctl创建pgsql实例,再在pgsql实例下使用sdb_sql_ctl创建数据库
  3. ./psql -p 5432 <数据库名>
  4. 连接sdb数据库驱动
  5. 配置sdb数据链接参数
  6. 创建表的时候映射sdb的CL
配置

cd到 /opt/sequoiasql/bin/

bin/sdb_sql_ctl addinst myinst -D database/5432/ 
bin/sdb_sql_ctl start myinst
bin/sdb_sql_ctl createdb sample myinst
bin/psql -p 5432 sample
CREATE EXTENSION sdb_fdw;//连接数据库驱动
CREATE SERVER sdb_server FOREIGN DATA WRAPPER sdb_fdw 
OPTIONS (address '127.0.0.1', service '11810', preferedinstance 'A', transaction 'on'); #配置sdb的连接参数

preferedinstance 设置 SequoiaDB 的连接属性。多个属性以逗号分隔,如:preferedinstance ‘1,2,A’。详细配置请参考 preferedinstance 取值

transaction 设置 SequoiaDB 是否开启事务,默认为off。开启为on 更多 SequoiaDB 连接参数说明请参考 PostgreSQL 实例连接

  • 如果没有配置数据库密码验证,可以忽略 user 与 password 字段。
  • 如果需要提供多个协调节点地址,options 中的 address 字段可以按格式 'ip1:port1,ip2:port2,ip3:port3’填写。此时,service 字段可填写任意一个非空字符串。
  • preferedinstance 设置 SequoiaDB 的连接属性。多个属性以逗号分隔,如:preferedinstance ‘1,2,A’。详细配置请参考 preferedinstance 取值
  • preferedinstancemode 设置 preferedinstance 的选择模式
  • sessiontimeout 设置会话超时时间 如:sessiontimeout ‘100’
  • transaction 设置 SequoiaDB 是否开启事务,默认为 off。开启为 on
  • cipher 设置是否使用加密文件输入密码,默认为 off。开启为 on
  • token 设置加密口令
  • cipherfile 设置加密文件,默认为 ./passwd

pgsql的事务管理

  1. 上述在配置sdb的连接的时候可以配置配置是否开启

    CREATE SERVER sdb_server FOREIGN DATA WRAPPER sdb_fdw 
    OPTIONS (address '127.0.0.1', service '11810', preferedinstance 'A', transaction 'on'); #配置sdb的连接参数
    
  2. 表内操作(类似mysql)

    xxx#=Begin;
    xxx#=Rollback;
    xxx#=Commit;
    
  3. 查看事务是否开启

    \des+ sdb_server;
    
  4. 开关服务的事务

    ALTER SERVER sdb_server OPTIONS ( SET transaction 'on' );
    ALTER SERVER sdb_server OPTIONS ( SET transaction 'off' );
    \q //需要退出
    /opt/sequoiasql/postgresql/bin/psql -p 5432 xxx #重新连接
    

关于PGsql的创建视图

例子:

CREATE VIEW xxx_view AS
SELECT
 e.ename, m.department
FROM
 employee AS e, manager AS m
WHERE 
 e.empno = m.empno;
SELECT * FROM xxx_view;

关于创建自定义函数

CREATE OR REPLACE FUNCTION totalRecords () RETURNS INTEGER AS $total$
DECLARE
    total INTEGER;
BEGIN
    SELECT COUNT(*) INTO total FROM employee;
RETURN total;
END;
$total$ language plpgsql;
SELECT totalRecords(); 

关于数据导出导入

导出数据
COPY (SELECT * FROM xxx) TO '<存储路径>' with delimiter ',' csv;

例子

COPY (SELECT * FROM employee) TO '/opt/sequoiasql/postgresql/employee.csv' with delimiter ',' csv;
导入数据
sdbimprt --hosts=localhost:11810 --type=csv --file=<存放路径> --fields="字段1, 字段2, 字段3"  -c <现有集合空间> -l <现有集合>

例子

sdbimprt --hosts=localhost:11810 --type=csv --file=/opt/sequoiasql/postgresql/employee.csv --fields="empno int, ename string, age int"  -c company -l employee

关于执行计划的操作

在 PostgreSQL 中执行条件查询语句,并查看执行计划;

EXPLAIN ANALYZE SELECT * FROM employee a INNER JOIN manager b ON a.empno = b.empno WHERE a.empno = 1;

操作截图:

图片描述

从执行计划可以看出:

  1. 两个表的连接方式为 Nested Loop Join;

  2. “Foreign Namespace”, 表示查询涉及到的外部表分别映射到 SequoiaDB 巨杉数据库的 company.employee 和 company.manager 集合中;

  3. “Filter”,表示把 SQL 语句的查询条件转为 JavaScript 语法的查询条件。而最终,PostgreSQL 会把 JavaScript 语法的查询条件下压到 SequoiaDB 巨杉数据库对应的集合中执行;

    在 PostgreSQL 中执行分页查询语句,并查看执行计划;

    EXPLAIN ANALYZE SELECT * FROM employee ORDER BY empno ASC LIMIT 5 OFFSET 0;
    EXPLAIN ANALYZE SELECT * FROM employee2 ORDER BY empno ASC LIMIT 5 OFFSET 0;
    

    操作截图:

    图片描述

    对比以上两个外部表的执行计划,可以看到:

    1. employee 外部表的执行计划,PostgreSQL 把 limit、offset 和排序条件下压到 SequoiaDB 巨杉数据库中执行(分页和排序是在 SequoiaDB 巨杉数据库中完成),因为创建 employee 外部表时,没有指定 pushdownsort 和 pushdownlimit 参数,默认为开启。
    2. employee2 外部表的执行计划,PostgreSQL 没有把 limit、offset 和排序条件下压到 SequoiaDB 巨杉数据库中执行(由 PostgreSQL 完成分页和排序),因为创建 employee2 外部表时,设置了 pushdownsort 和 pushdownlimit 参数为关闭。

关于元数据同步

前置条件

1若 PostgreSQL 实例开启了用户鉴权,需要创建元数据同步用户以及配置免密登录。

1)进入 sdbadmin 的 home 目录;

cd /home/sdbadmin

2)同步工具已提前放置在 sdbadmin 的 home 目录,解压同步工具;

tar xvf SsqlDisseminateDDL.tar

3)进入解压目录;

cd SsqlDisseminateDDL

4)拷贝免密文件到 home 目录;

cp .pgpass /home/sdbadmin/

5)将文件权限设置为0600;

chmod 0600 /home/sdbadmin/.pgpass

1)进入 myinst 实例的数据目录,修改部分配置;

cd /opt/sequoiasql/postgresql/database/5432

2 为了配合元数据同步,需要对应修改 postgresql.conf 配置文件的参数;

echo "log_destination = 'csvlog'" >> postgresql.conf
echo "logging_collector = on" >> postgresql.conf
echo "log_directory = '/opt/sequoiasql/postgresql/database/5432/pg_log'" >> postgresql.conf
echo "log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'" >> postgresql.conf
echo "log_rotation_age = 28d" >> postgresql.conf
echo "log_rotation_size = 20MB" >> postgresql.conf
echo "log_statement = 'ddl'" >> postgresql.conf

Note:

  • log_destination:设置输出的日志类型;
  • logging_collector:是否开启日志功能,默认为关闭(off),开启为 on;
  • log_directory:日志输出目录;
  • log_filename:日志文件名称命名规则;
  • log_rotation_age:单个日志文件的保存周期,默认保存 1 天(1d);
  • log_rotation_size:单个日志文件的大小, 若超过指定大小,那么将新生成一个日志文件;
  • log_statement:控制记录哪些 SQL 语句;

3将元数据同步程序及 config 配置文件拷贝到本地,并查看 config 文件内容。

1)拷贝元数据同步工具到数据目录;

cp /home/sdbadmin/SsqlDisseminateDDL/SsqlDisseminateDDL ./

2)拷贝元数据同步工具配置到数据目录;

cp /home/sdbadmin/SsqlDisseminateDDL/config ./

4手动创建日志目录

1)创建日志目录;

mkdir /opt/sequoiasql/postgresql/database/5432/pg_log
mkdir /opt/sequoiasql/postgresql/database/5432/log

2)重启 myinst 实例;

/opt/sequoiasql/postgresql/bin/sdb_sql_ctl restart myinst

元数据同步工具在启动后会一直常驻后台运行,主要用于定时解析主 PostgreSQL 实例日志中新增的 DDL 操作语句并下发到各备 PostgreSQL 实例中执行。

nohup python /opt/sequoiasql/postgresql/database/5432/SsqlDisseminateDDL &

注意事项:

  1. 在创建PGsql的表时候应连接sdb的数据驱,关键词CREATE EXTENSION sdb_fdw;

  2. 连接完后在添加sdb的连接参数.

  3. 在创建表时候在语句尾部加入

     SERVER sdb_server OPTIONS (collectionspace '集合空间', collection '集合', decimal 'on');
    
  • 集合空间与集合必须已经存在于 SequoiaDB,否则查询出错。

  • 如果需要对接 SequoiaDB 的 decimal 字段,则需要在 options 中指定 decimal ‘on’ 。

  • pushdownsort 设置是否下压排序条件到 SequoiaDB,默认为 on,关闭为 off。

  • pushdownlimit 设置是否下压 limit 和 offset 条件到 SequoiaDB,默认为 on,关闭为 off。

  • 开启 pushdownlimit 时,必须同时开启 pushdownsort,否则可能会造成结果非预期的问题。

  • 默认情况下,表的字段映射到 SequoiaDB 中为小写字符,如果强制指定字段为大写字符,创建方式参考“注意事项1”。

  • 映射 SequoiaDB 的数组类型,创建方式参考“注意事项2”。

    在PG执行计划的那一章的字段

    db.company.employee.find( { "empno": 1 } ).explain( { "Run": true } );
    

    explain( { “Run”: true } )详细查看

需要巩固语句:

ANALYZE 表;

Sparksql(12.01-12.02)

前置条件

用户配置

1)使用 MySQL Shell 连接 SequoiaDB-MySQL 实例;

/opt/sequoiasql/mysql/bin/mysql -h 127.0.0.1 -P 3306 -u root

2)创建 metauser 用户;

CREATE USER 'metauser'@'%' IDENTIFIED BY 'metauser';

3)给 metauser 用户授权;

GRANT ALL ON *.* TO 'metauser'@'%';

4)刷新权限;

FLUSH PRIVILEGES;

5)创建元数据库;

CREATE DATABASE metastore CHARACTER SET 'latin1' COLLATE 'latin1_bin';
环境配置
  • cd /opt/spark-2.4.4-bin-hadoop2.7/conf

  • 将从模板中拷贝 spark-env.sh 文件;

    cp spark-env.sh.template spark-env.sh
    
  • 设置 Spark 实例的 Master;

    echo "SPARK_MASTER_HOST=sdbserver1" >> spark-env.sh
    
  • 查看 spark-env.sh 文件是否设置成功;

    cat spark-env.sh
    
  • 指定 Spark 实例的元数据信息存放的数据库信息。

  • 创建设置元数据数据库配置文件 hive-site.xml;(根据实际实况变动)以下是模板

    cat > /opt/spark-2.4.4-bin-hadoop2.7/conf/hive-site.xml << EOF
    <configuration>
       <property>
         <name>hive.metastore.schema.verification</name>
         <value>false</value>
       </property>
       <property>
          <name>javax.jdo.option.ConnectionURL</name>
          <value>jdbc:mysql://localhost:3306/metastore?useSSL=false</value>
          <description>JDBC connect string for a JDBC metastore</description>
       </property>
       <property>
          <name>javax.jdo.option.ConnectionDriverName</name>
          <value>com.mysql.jdbc.Driver</value>
          <description>Driver class name for a JDBC metastore</description>
       </property>
       <property>
          <name>javax.jdo.option.ConnectionUserName</name>
          <value>metauser</value>
       </property>
       <property>
          <name>javax.jdo.option.ConnectionPassword</name>
          <value>metauser</value>
       </property>
       <property>
          <name>datanucleus.autoCreateSchema</name>
          <value>true</value>
          <description>creates necessary schema on a startup if one doesn't exist. set this to false, after creating it once</description>
       </property>
    </configuration>
    EOF
    
JDK配置

在/xxx/xxx/spark-3.0.1-bin-hadoop2.7/sbin/spark.config-sh最尾加入

export JAVA_HOME=XXXX
配置日志级别

由于 Spark 默认日志级别为 INFO ,运行 spark-sql 客户端时会打印大量日志输出屏幕,为了避免这个问题把日志级别改为 ERROR。

1)拷贝 log4j.properties;

cp log4j.properties.template  log4j.properties

2)log4j.properties 中设置日志级别;

sed -i 's/log4j.rootCategory=INFO, console/log4j.rootCategory=ERROR, console/g' log4j.properties

3)检查日志输出配置是否成功;

cat log4j.properties

创建实例

假如sdb现有company集合空间,employee集合.

在创建映射表时候注意表尾:

CREATE TABLE company.employee 
(
empno INT,
ename STRING,
age INT
) USING com.sequoiadb.spark OPTIONS (host 'localhost:11810', collectionspace 'company', collection 'employee', username '', password '');

关于在Beeline客户端对Sdb的CRUD

踩大坑

在启动thriftserver 时候执行成功但是服务器没启动

查看opt/spark-3.0.1-bin-hadoop2.7/logs/spark-sdbadmin-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-sdb1.out日志
发现报错原因

Hive--MetaException(message:Required table missing : “`DBS`“ in Catalog ““ Schema ““. DataNucleus 

在hive.site.xml加入

<property>
    <name>datanucleus.schema.autoCreateAll</name>
    <value>true</value>
 </property>

再次启动

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fgISsSxR-1607938015476)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606978345181.png)]

使用下语句查看进程

netstat -anp | grep 10310

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fcyBUVqO-1607938015477)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606978415711.png)]

启动成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8F4rOyjf-1607938015479)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1606978730090.png)]

但是

插入的时候遇到了

java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;(15269)

百度后发现是版本问题

这是SDB-spark要求的

Note:

Spark-SequoiaDB连接组件的环境要求:

  • JDK 1.7+
  • Scala 2.11
  • Spark 2.0.0+

我现在的配置是Scala 2.11+JKD1.8+spark3.0

估计是spark版本过高

创建表并且与employee关联
CREATE TABLE employee 
(
empno  INT,
ename  STRING,
age    INT
) 
USING com.sequoiadb.spark OPTIONS 
( 
host 'localhost:11810', 
collectionspace 'company', 
collection 'employee'
);
SequoiaDB-SparkSQL 建表语法说明

在 SparkSQL 中关联 SequoiaDB 集合空间和集合的 SQL 语法如下;

CREATE <[TEMPORARY] TABLE | TEMPORARY VIEW> <tableName> [(SCHEMA)]
USING com.sequoiadb.spark OPTIONS (<option>, <option>, ...);

语法说明:

  • TEMPORARY 表示为临时表或视图,只在创建表或视图的会话中有效,会话退出后自动删除。
  • 表名后紧跟的 SCHEMA 可不填,连接器会自动生成。自动生成的 SCHEMA 字段顺序与集合中记录的顺序不一致,因此如果对 SCHEMA 的字段顺序有要求,应该显式定义 SCHEMA。
  • OPTIONS 为参数列表,参数是键和值都为字符串类型的键值对,其中值的前后需要有单引号,多个参数之间用逗号分隔。
SequoiaDB-SparkSQL 建表参数说明

下面是部分常用的 SequoiaDB-SparkSQL 建表参数说明,完整的建表参数请参考 SequoiaDB-SparkSQL 参数说明

  • host :SequoiaDB 协调节点/独立节点地址,多个地址以 “,” 分隔。例如:“server1:11810, server2:11810”。
  • collectionspace :集合空间名称。
  • collection :集合名称(不包含集合空间名称)。
  • username :数据库用户名。
  • passwordtype : 密码类型,取值为“cleartext”或“file”,分别表示明文密码和文件密钥。
  • password :数据库用户名对应的用户密码。
  • preferredinstance :指定分区优先选择的节点实例。

SequoiaDB-SparkSQL 支持通过连接器自动生成 SCHEMA 来创建关联表,这样可以在建表时不指定 SCHEMA 信息。

1)通过连接器自动生成 SCHEMA 来创建 employee_auto_schema 表;

CREATE TABLE employee_auto_schema USING com.sequoiadb.spark OPTIONS 
(
host 'localhost:11810',
collectionspace 'company',
collection 'employee'
);

Note:

通过连接器自动生成 SCHEMA,要求在建表时 SequoiaDB 的关联集合中就已经存在数据记录。

2)查看表 employee_auto_schema 的结构信息;

DESC employee_auto_schema;

操作截图:

1542-610-14

3)查询 employee_auto_schema 的数据记录;

SELECT * FROM employee_auto_schema;

Note:

SparkSQL 表 employee 和 employee_auto_schema 关联的都是 SequoiaDB 中的集合 company.employee,所以这两张 SparkSQL 表的对应数据是完全一致的。

JSON

关于JSON实例

初始判断是sdb和mongodb这类文档型数据库.

例子

创建顺序:

  1. 经典进入协调节点;
  2. 创建逻辑域,cs,cl;

关于restful接口

​ 协调节点(coord)和数据节点(data)对外提供REST接口访问,同时支持HTTP和HTTPS协议。

通用请求头
字段说明例子
Content-Type请求的数据类型application/x-www-form-urlencoded;charset=UTF-8
Content-Length请求的长度54
Host主机名(协调节点或数据节点的服务地址)192.168.1.214:11814
Accept希望应答的数据类型,如果不指定该字段,默认响应 text/html (文本格式)的数据类型application/json
POST / HTTP/1.0
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: application/json
Content-Length: 54
Host: 192.168.1.214:11814

S3实例操作

创建顺序

  1. 先保证电脑配置了jdk

  2. 保证sequoiadb/tools/ 存在sequoias3

  3. 经典进入协调节点;

  4. 开启RC级别的事务,配置等锁模式

    db.updateConf( { transactionon: true, transisolation: 1, translockwait: true } );
    
  5. 创建存储元数据的集合空间所在的逻辑域

    db.createDomain("metaDomain", [ "group1", "group2", "group3" ], { AutoSplit: true} );
    
  6. 创建存储对象数据的集合空间所在的域;

    db.createDomain("dataDomain", [ "group1", "group2", "group3" ], { AutoSplit: true} );
    
  7. 进入sequoiadb/tools/sequoias3

  8. 配置 SequoiaS3,配置对外监听端口;

    echo 'server.port=8002' >> config/application.properties
    

    配置 coord 节点的 IP 和端口,可以配置多组并使用逗号分隔

    echo 'sdbs3.sequoiadb.url=sequoiadb://localhost:11810' >> config/application.properties
    

    配置 SequoiaS3 的存储创建了专属的域

    echo 'sdbs3.sequoiadb.meta.domain=metaDomain' >> config/application.properties
    echo 'sdbs3.sequoiadb.data.domain=dataDomain' >> config/application.properties
    

关于S3存储桶

https://blog.csdn.net/iloveaws/article/details/103858409

关于CS(集合空间)和CL(集合)的操作

操作

http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1432190854-edition_id-0

创建域:

db.createDomain( "xxx", [ "group1", "group2", "group3" ], { "AutoSplit": true } );

创建主集合空间:

db.createCS("cs", { "Domain": "xxx" } );

创建主集合:

db.cs.createCL("maincl", { "IsMainCL": true, "ShardingKey": {"<通常是主键>": 1 }, "ShardingType": "range/hash" } );

创建子集合空间;

db.createCS("subcl", { "Domain": "xxx" } );

创建集合:

db.cs.createCL("xxx", { "ShardingKey": { "_id": 1 }, "ShardingType": "hash", "ReplSize": -1, "Compressed": true, "CompressionType": "lzw", "AutoSplit": true, "EnsureShardingIndex": false } );
分区组弹性扩容

1)新建一个分区组语法;

var rg = db.createRG( < name > );

参数描述:

参数名参数类型描述是否必填
namestring分区组名,同一个数据库对象中,分区组名唯一。

2)在当前分区组中创建节点语法;

rg.createNode( < host >, < service >, < dbpath >, [ config ] );

参数描述:

参数名参数类型描述是否必填
hoststring指定节点的主机名。
serviceint/string节点端口号。
dbpathstring1. 数据文件路径,用于存放节点数据文件,请确保数据管理员(安装时创建,默认为 sdbadmin )用户有写权限; 2. 如果配置路径不以“/”开头,数据文件存放路径将是数据库管理员用户(默认为 sdbadmin )的主目录(默认为 /home/sequoiadb )+ 配置的路径。
configJson 对象节点配置信息,如配置日志大小,是否打开事务等,具体可参考数据库配置。

3)查看数据库扩容后状态

sdblist  -t all -l -m local

4)查看域信息

db.listDomains();

5)关于数据分切到别的组

db.XXXCS.XXXCL.split("分切组","目标组",<百分比>)

SCDD(12.06)

SCDD主要偏向实类型,前两者是理论向,SCDP是偏向于熟悉操作;

Mysql的实例应用开发

配置连接池:

教程里面的连接池是C3P0的,我偏于性能倾向,选择用了Springboot自带的HikariCP,更加方便快捷,而且性能是几大连接池最强的.https://blog.csdn.net/qq_31125793/article/details/51241943

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bWl1RHtj-1607938015480)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1607074566893.png)]

关于DDL和DML

一、DML与DDL的含义:

1、DML(Data Manipulation Language)数据操作语言-数据库的基本操作,SQL中处理数据等操作统称为数据操纵语言,简而言之就是实现了基本的“增删改查”操作。包括的关键字有:select、update、delete、insert、merge

2、DDL(Data Definition Language)数据定义语言-用于定义和管理 SQL 数据库中的所有对象的语言,对数据库中的某些对象(例如,database,table)进行管理。包括的关键字有:

create、alter、drop、truncate、comment、grant、revoke

二、DML与DDL的区别:

1.DML操作是可以手动控制事务的开启、提交和回滚的。

2.DDL操作是隐性提交的,不能rollback!

数据类型

整数
MySQL数据类型含义(有符号)
tinyint(m)1个字节 范围(-128~127)
smallint(m)2个字节 范围(-32768~32767)
mediumint(m)3个字节 范围(-8388608~8388607)
int(m)4个字节 范围(-2147483648~2147483647)
bigint(m)8个字节 范围(±9.22*10的18次方)
浮点型
MySQL数据类型含义
float(m,d)单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d)双精度浮点型 16位精度(8字节) m总个数,d小数位
日期时间类型
MySQL数据类型含义
date日期 ‘2008-12-2’
time时间 ‘12:25:36’
datetime日期时间 ‘2008-12-2 22:06:44’
timestamp自动存储记录修改时间
字符串
MySQL数据类型含义
char(n)固定长度,最多255个字符
varchar(n)固定长度,最多65535个字符
tinytext可变长度,最多255个字符
text可变长度,最多65535个字符
mediumtext可变长度,最多2的24次方-1个字符
longtext可变长度,最多2的32次方-1个字符
char和varchar对比
  • char(n) 若存入字符数小于 n,则以空格补于其后,查询之时再将空格去掉。所以 char 类型存储的字符串末尾不能有空格,varchar 不限于此。
  • char(n) 固定长度,char(4) 不管是存入几个字符,都将占用4个字节,varcha r是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以 varchar(4) ,存入3个字符将占用4个字节。
  • char 类型的字符串检索速度要比 varchar 类型的快。
varchar和text对比
  • varchar 可指定 n,text 不能指定,内部存储 varchar 是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text 是实际字符数+2个字节。
  • text 类型不能有默认值。
  • varchar 可直接创建索引,text 创建索引要指定前多少个字符。
字符串函数处理

常用的字符串处理函数有如下几种

函数说明例子
LOWER(column|str)将字符串参数值转换为全小写字母后返回SELECT lower(‘SQL Course’) ;
UPPER(column|str)将字符串参数值转换为全大写字母后返回SELECT upper(‘SQL Course’) ;
CONCAT(col|str1,col|str2,…)将多个字符串参数首尾相连后返回SELECT concat(‘My’, ‘S’, ‘QL’);
LENGTH(str)返回字符串的存储长度SELECT length(‘text’),length(‘你好’);
TRIM()去掉字符两端的空格SELECT trim('bar ') ;
REPEAT(str,count)将字符串str重复count次后返回SELECT repeat(‘MySQL’, 3);
REVERSE(str)将字符串str反转后返回SELECT reverse(‘abc’);
SUBSTR(str,pos[,len])从源字符串str中的指定位置pos开始取一个字串并返回。len指定子串的长度,如果省略则一直取到字符串的末尾。该函数是函数SUBSTRING()的同义词。len为负值表示从源字符串的尾部开始取起SELECT substring(‘hello world’,5);

例子

SELECT LOWER('SQL Course'); //输出sql course

关于全表删除

概述

  • DELETE 命令删除的数据可以恢复。
  • TRUNCATE 命令删除的数据是不可以恢复的。
  • DROP 命令删除的数据不可恢复,连表结构都删除。

相同点

TRUNCATE 和不带 WHERE 子句的 DELETE, 以及 DROP 都会删除表内的数据。

不同点

  • TRUNCATE 和 DELETE 只删除数据不删除表的结构,DROP 语句将删除表的结构被依赖的约束( CONSTRAIN ), 触发器( TRIGGER ), 索引( INDEX ); 依赖于该表的存储过程/函数将保留, 但是变为 invalid 状态。

  • DELETE 语句是 DML, 这个操作会放到 Rollback Segment 中, 事务提交之后才生效; 如果有相应的 TRIGGER, 执行的时候将被触发。 TRUNCATE, DROP 是 DDL, 操作立即生效, 原数据不放到 Rollback Segment 中, 不能回滚。 操作不触发 TRIGGER。

  • 速度:一般来说: DROP > TRUNCATE > DELETE。

  • 安全性: 谨慎使用 DROP 和 TRUNCATE,尤其没有备份的时候。

关于执行计划

执行计划说明
字段说明
id查询的执行顺序号
select_type查询类型
table当前执行的表
type查询使用了那种类型
possible_keys显示可能应用在这张表中的索引,一个或多个。
key实际使用的索引
key_len表示索引中使用的字节数
ref显示索引的那一列被使用了
rows根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
filtered存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例
extra包含不适合在其他列中显式但十分重要的额外信息

select_type 常见和常用的值有如下几种:

SIMPLE、PRIMARY、SUBQUERY 、DERIVED、UNION 、UNION RESULT

type 包含的类型包括如下几种,从最好到最差依次是:

system > const > eq_ref > ref > range > index > all

关于case表达式

MySQL 的 CASE 表达式有2种形式,一种更像是编程语言当中的 CASE 语句,拿一个给定的值(变量)跟一系列特定的值作比较,称之为 CASE 类型。另一种则更像是编程语言中的 if 语句,当满足某些条件的时候取特定值,称之为 IF 类型。

case类型

此类型的语句结构如下:

if表达式

CASE value

WHEN compare_value_1 THEN result_1

WHEN compare_value_2 THEN result_2

ELSE result END

此情况下,拿 value 与各个 compare_value 比较,相等时取对应的值,都不相等时取最后的 result。

例子:

String sql3 = "SELECT ename," +
    "    CASE ename" +
    "        WHEN 'Parto' THEN 'P'" +
    "        WHEN 'Georgi' THEN 'G'" +
    "        WHEN 'Chirs' THEN 'C'" +
    "        ELSE 'XX'" +
    "    END AS mark\n" +
    "FROM" +
    "    employee";

​ 结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6evbgL2S-1607938015481)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1607305113000.png)]

关于MySQL函数

FIND_IN_SET(str,strlist)
FIND_IN_SET(str,strlist)

假如字符串 str 在由 N 子链组成的字符串列表 strlist 中,则返回值的范围在 1 到 N 之间。一个字符串列表就是一个由一些被‘,’符号分开的自链组成的字符串。如果第一个参数是一个常数字符串,而第二个是 type SET 列,则 FIND_IN_SET() 函数被优化,使用比特计算。如果 str 不在 strlist 或 strlist 为空字符串,则返回值为 0 。如任意一个参数为 NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。返回值为 str 在strlist中的位置,从1开始计数。

详细用法

LOCATE(substr,str) / POSITION(substr IN str)

这两个函数都是返回子串 substr 在字符串 str 中第一次出现的位置。如果子串 substr 在 str 中不存在,返回值为0。

检索 SQL 在字符串中第一次出现的位置

字符串函数处理(在上面字符串有)
聚合函数

聚合数据通常不是存储在数据表中,而是通过对数据表中符合条件的数据进行聚合计算得出。

例如,由于 orderDetails 表仅存储每个项目的数量和价格,因此无法通过从 orderdetails 表直接查询获得每个订单的总金额。必须为每个订单查询项目的数量和价格,并计算订单的总额。

要在查询中执行此类计算,就要使用聚合函数了。

根据定义,聚合函数对一组值执行计算并返回单个值。

MySQL 提供了许多聚合函数,包括 AVG,COUNT,SUM,MIN,MAX 等。除 COUNT 函数外,其它聚合函数在执行计算时会忽略 NULL 值。

常用的聚合函数有如下几种:

函数说明
AVG()计算一组值的平均值
COUNT()返回表中的行数
SUM()返回一组值的总和
MAX()返回一组值中的最大值
MIN()返回一组值中的最小值

例子:

查询成绩最低的学生

select <字段1,如学生名> as '学生名' ,<字段2,如学生成绩> as '学生成绩' from <表名>
where <字段2,如成绩> in (select MIN(<字段2,如成绩>));
关于时间函数

相关字段,datatime,timestamp(通常用于处理乐观锁问题)

常用的日期时间函数有如下几种:

函数说明
CURDATE()返回当前日期
CURTIME()返回当前时间
NOW()返回当前的日期和时间
UNIX_TIMESTAMP(date)返回日期date的UNIX时间戳
FROM_UNIXTIME返回UNIX时间戳的日期值
WEEK(date)返回日期date为一年中的第几周
YEAR(date)返回日期date的年份
HOUR(time)返回time的小时值
MINUTE(time)返回time的分钟值
MONTHNAME(date)返回date的月份名
DATE_FORMAT(date,fmt)返回按字符串fmt格式化日期date值
DATE_ADD(date,INTERVAL expr type)返回一个日期或时间值加上一个时间间隔的时间值
DATEDIFF(expr,expr2)返回起始时间expr和结束时间expr2之间的天数
关于系统函数

常用的系统信息函数有如下几种:

函数说明
VERSION()返回数据库的版本号
CONNECTION_ID返回服务器的连接数
DATABASE()返回当前数据库名
USER()返回当前用户
CHARSET(str)返回字符串str的字符集
COLLATION(str)返回字符串str的字符排列方式
LAST_INSERT_ID()返回最近生成的AUTO_INCREMENT值
关于加密函数
Password()和MD5()
##Password(str) 旧16位
##MD5(str) 32未 两者加密均不可逆
select PASSWORD('abcd')  ##对abcd加密
ENCODE(“被加密字符串”,“加密字符串”)函数加密

加密的结果是一个二进制数,必须使用 blob 类型的字段来保护它

例子:

INSERT INTO lobTab VALUES(4,'jerry',encode('this is a file','key'));");
// Execute sql
String sql = "select * from lobTab where id = 4

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c5NDXxZv-1607938015483)(C:\Users\NoobCo3\AppData\Roaming\Typora\typora-user-images\1607309376151.png)]

关于视图

视图的特点:

1、视图通常也被称为子查询,是从一个或多个表导出的虚拟的表,其内容由查询定义。具有普通表的结构,但是不实现数据存储;

2、对视图的修改:单表视图一般用于查询和修改,会改变基本表的数据;

3、多表视图一般用于查询,不会改变基本表的数据;

4、 视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的,有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。

创建
CREATE [OR REPLACE] VIEW 视图名(列1,列2...)

AS SELECT (列1,列2...)	

FROM ...;

[WITH [CASCADED|LOCAL] CHECK OPTION]
删除
DROP VIEW viewname;
查看视图
DESC viewname;
查询所有视图
SHOW TABLE STATUS WHERE COMMENT='view'

关于触发器

INSERT 触发器在 INSERT 语句执行之前或之后执行。需要知道以下几点:

  • 在 INSERT 触发器代码内,可引用一个名为 NEW 的虚拟表,访问被插入的行;
  • 在 BEFORE INSERT 触发器中, NEW 中的值也可以被更新(允许更改被插入的值);
  • 对于 AUTO_INCREMENT 列,NEW 在 INSERT 执行之前包含0,在 INSERT 执行之后包含新的自动生成值。

查看所有触发器:

show triggers;

删除触发器:

drop trigger xxxx_trigger; ##DML

例子

​ 插入数据后将信息"Employee added"插入result 查询@result即可得出"Employee added"

CREATE TRIGGER newemployee AFTER INSERT ON employee FOR EACH ROW SELECT 'Employee added' INTO @result;

关于存储过程

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的 SQL 语句集经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程的优点:

  • 存储过程可封装,并隐藏复杂的商业逻辑;
  • 存储过程可以回传值,并可以接受参数;
  • 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同;
  • 存储过程可以用在数据检验,强制实行商业逻辑等。

存储过程个人理解为一个private的方法,只提供返回值.

无参例子

CREATE PROCEDURE avgAge()
BEGIN
SELECT AVG(age) AS avgAge
FROM employee;
END;

有参例子

	CREATE PROCEDURE getName(
    IN ino INT,
   	OUT oname VARCHAR(32)
    )
    BEGIN
    SELECT ename FROM employee WHERE empno = ino INTO oname;
    END;
使用
CALL <PROCEDURE_NAME>;
删除
DROP PROCEDURE <PROCEDURE_NAME>;

关于函数

函数存储着一系列 SQL 语句,调用函数就是一次性执行这些语句。所以函数可以降低语句重复。

例子:

创建函数

CREATE FUNCTION createTable(name VARCHAR(20)) RETURNS VARCHAR(50)
    BEGIN
    DECLARE str VARCHAR(50) DEFAULT '';
    SET @tableName=name;
    SET str=CONCAT('CREATE TABLE ',@tableName,'(id INT,name VARCHAR(20));');
    RETURN str;
    END

删除函数

drop function if exists <function_name>;

关于锁和事务(重点)

事务:

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,删除一个人员,既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务。

使用 Connection 对象来管理事务。java.sql.Connection 接口是一个数据库连接对象。

  • 开启事务

    setAutoCommit(boolean autoCommit) 调用该方法设置参数为false,即开启事务

  • 提交事务

    commit() 当所有sql斗执行完提交事务

  • 回滚事务

    rollback() 在catch中回滚事务

事务ACID四特性;
  • 事务内的每个内容不可分割,是一个统一的整体,或同时进行或同时消亡。
  • 事务前后数据在内保持一致
  • 事务的隔离性指的是几个事务同时执行,事务 a 不应该干扰到事务 b 内的操作(在并发过程中很有可能会发生事务间的影响,例如脏读、不可重复读等。需要在编程的时候选择适当的方式进行选择)
  • 在事务完成以后,该事务所du对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。由于一项操作通常会包含许多子操作,而这些子操作可能会因为硬件的损坏或其他因素产生问题,要正确实现ACID并不容易。
悲观锁

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

MySQL select…for update的Row Lock与Table Lock

上面我们提到,使用select…for update会把数据给锁住,不过我们需要注意一些锁的级别,MySQL InnoDB默认Row-Level Lock,所以只有「明确」地指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。

RL和TL的触发条件(重点)
  1. 明确指定主键,并且有此数据,row lock

  2. 明确指定主键,若查无此数据,无lock

  3. 无主键,table lock

  4. 主键不明确,table lock,例子

    select * from t_goods where id>0 for update; 
    select * from t_goods where id<>1 for update;
    

关于数据库主键对MySQL锁级别的影响实例,需要注意的是,除了主键外,使用索引也会影响数据库的锁定级别

  1. 明确指定索引,并且有此数据,row lock
  2. 明确指定索引,若查无此数据,无lock
乐观锁

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何实现乐观锁呢,一般来说有以下2种方式:

1、使用版本号实现乐观锁

版本号的实现方式有两种,一个是数据版本机制,一个是时间戳机制。具体如下。

a.使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。用下面的一张图来说明:

img

如上图所示,如果更新操作顺序执行,则数据的版本(version)依次递增,不会产生冲突。但是如果发生有不同的业务操作对同一版本的数据进行修改,那么,先提交的操作(图中B)会把数据version更新为2,当A在B之后提交更新时发现数据的version已经被修改了,那么A的更新操作会失败。

b.时间戳机制,同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

2、使用条件限制实现乐观锁

这个适用于只更新是做数据安全校验,适合库存模型,扣份额和回滚份额,性能更高。这种模式也是目前我用来锁产品库存的方法,十分方便实用。

JSON实例开发(12.08)

关于集合空间和集合

在巨杉数据库中,存在“集合空间”和“集合”的概念,可以简单理解为二者分别对应着传统数据库中的“库”和“表”。

名称释义
集合空间对应 Java 类为 com.sequoiadb.base.CollectionSpace。 集合空间是数据库中存放集合的物理对象。任何一个集合必须属于一个且仅一个集合空间。集合空间名最大长度 127 字节,为 UTF-8 编码。一个集合空间中可以包含不超过 4096 个集合;每个数据节点可以包含不超过 16384 个集合空间。
集合对应 Java 类为 com.sequoiadb.base.DBCollection。 集合是数据库中存放文档的逻辑对象。任何一条文档必须属于一个且仅一个集合。集合由“<集合空间名>.<集合名>”构成。集合名最大长度 127 字节,为 UTF-8 编码。一个集合中可以包含零个至任意多个文档(上限为集合空间大小上限)。

关于BSON对对象id的使用

Java BSON 使用 org.bson.types.ObjectId 来生成每条记录的“_id”字段内容。目前,Java ObjectId 的 12字节内容由三部分组成:4字节精确到秒的时间戳,4字节系统(物理机)标示,4字节由随机数起始的序列号。默认情况下,数据库为每条记录生成一个字段名为“_id”的唯一对象 ID。

日期和时间戳

Java BSON 使用 java.util.Date 来构造日期类型,Date类是经常会使用到的一个用来处理日期、时间的一个类。 Date类的构造器有: Date():分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。 Date(long date):分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。 除此之外,最直观且常见的操作方式为通过 SimpleDateFormat 指定格式,然后对字符串进行格式化后返回一个 Date 对象。

Java BSON 使用 org.bson.types.BSONTimestamp 来构造时间戳类型。

时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数。通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。 它的设立主要是为用户提供一份电子证据, 以证明用户某些数据的具体产生时间。

LOB对象的使用

Java BSON 使用 com.sequoiadb.base.DBLob 来构造 LOB 大对象数据类型。

LOB 常用于存储文件类型数据,它具有着传统关系型数据库所不具备的优势。

大对象(LOB)的功能旨在突破 SequoiaDB 的单条记录最大长度为 16MB 的限制,为用户写入和读取更大型记录提供便利。

LOB 记录的大小目前不受限制。

每一个 LOB 记录拥有一个 OID,通过指定集合及 OID 可以访问一条 LOB 记录。在非分区集合及哈希分区集合中均可使用 LOB 功能。集合间不共享 LOB 记录。当一个集合被删除时,其拥有的 LOB 记录自动删除。

例子:

此代码样例将会向数据库中插入一条 LOB 记录,准备插入的 LOB 数据内容来源于字符串的二进制流。这里演示如何向集合中插入 LOB 数据,以及如何通过 OID 获取这条 LOB 数据。在 Java 开发中,会使用 com.sequoiadb.base.DBLob 来构造 LOB 对象。

需要注意的是,LOB 的存取是以流的形式,所以操作完毕要执行 close 方法。

操作语句

例子

BSONObject record = new BasicBSONObject();
// Create a file stream with text content.
String word = "Hello there! This is the specific content of the Text file.";
// Create the Lob.
DBLob lob = cl.createLob();
// Add the file stream to Lob.
lob.write(word.getBytes());
// Get the unique ID after successful lob creation.
ObjectId id = lob.getID();
// Print ID.
String s = id.toString();
System.out.println("The ID generated after creating the lob object is:" + s);
// Close the file stream.
lob.close();
// Get the inserted lob object.
DBLob lobCopy = cl.openLob(id);
byte[] bytes = new byte[word.length()];
// Read the file stream of the lob object into memory.
lobCopy.read(bytes);
String get = new String(bytes);
System.out.println("The content of the obtained lob object file stream is:" + get);
lobCopy.close();
单条插入
// Insert a piece of data into the collection, and the data is a BsonObject object.
BSONObject record = new BasicBSONObject();
record.put("empno", 10002);
record.put("ename", "Bezalel");
record.put("age", 31);
cl.insert(record);
多条插入
// Insert multiple pieces of data into a collection.
List<BSONObject> records = new ArrayList<>();
BasicBSONObject r1 = new BasicBSONObject();
r1.put("empno", 10003);
r1.put("ename", "Parto");
r1.put("age", 33);
records.add(r1);
BasicBSONObject r2 = new BasicBSONObject();
r2.put("empno", 10004);
r2.put("ename", "Chirstian");
r2.put("age", 18);
records.add(r2);
cl.insert(records);
指定查询
BSONObject matcher = new BasicBSONObject();
// $ et means equal.
BSONObject et = new BasicBSONObject();
et.put("$et", 19);
// Age equals to 19.
matcher.put("age", et);
cursor = cl.query(matcher, null, null, null);
更新指定向
// Set the matching rule, and $et equals to the value.
BSONObject matcher = new BasicBSONObject();
BSONObject et = new BasicBSONObject();
et.put("$et", 19);
matcher.put("age", et);
// Set the modified value.
BSONObject modifier = new BasicBSONObject();
BSONObject value = new BasicBSONObject();
value.put("age", 20);
modifier.put("$set", value);
// Execute update operation.
cl.update(matcher, modifier, null);
删除数据
// Set the matching rule, and $et equals to the value.
BSONObject matcher = new BasicBSONObject();
BSONObject et = new BasicBSONObject();
et.put("$et", 19);
matcher.put("age", et);
// Execute delete operation.
cl.delete(matcher);
创建索引
cl.createIndex("idx_empno", column, false, false);
属性释义
ShardingKey分区键
ShardingType默认为 hash 分区。其可选取值如下: “hash”:hash 分区; “range”:范围分区;
Partition分区数。仅当选择 hash 分区时填写,代表了 hash 分区的个数。 其值必须是2的幂。范围在[23,220]。默认为4096
AutoSplit标示新集合是否开启自动切分功能,默认为 false
Compressed标示新集合是否开启数据压缩功能,默认为 true
CompressionType压缩算法类型。默认为 lzw 算法。其可选取值如下: “snappy”:使用 snappy 算法压缩; “lzw”:使用 lzw 算法压缩;
参数名参数类型描述是否必填
namestring索引名,同一个集合中的索引名必须唯一。
keyJson 对象索引键,包含一个或多个指定索引字段与类型的对象。类型值 1 表示字段升序,-1 表示字段降序,“text” 则表示创建全文索引
isUniqueBoolean索引是否唯一,默认 false。设置为 true 时代表该索引为唯一索引。
enforcedBoolean索引是否强制唯一,可选参数,在 isUnique 为 true 时生效,默认 false。设置为 true 时代表该索引在 isUnique 为 true 的前提下,不可存在一个以上全空的索引键。
联合索引

如果经常要用到多个字段的多条件查询,可以考虑建立联合索引。一般来说,就如有除第一个字段外的其它字段不经常用于条件筛选的情况,比如说 a、b 两个字段,如果经常用 a 条件或者 a + b 条件去查询,而很少单独用 b 条件查询,那么可以建立 a、b 的联合索引。如果 a 和 b 都要分别经常独立的被用作查询条件,那还是要建立多个单列索引。

BasicBSONObject column = new BasicBSONObject();
// Index contains fields
column.put("empno", 1);
column.put("deptno", 1);
// Create a joint index.
cl.createIndex("idx_empno", column, false, false);
事务

例子

db.beginTransaction();
// Insert 2 pieces of data into the collection, and the data is in Json format.
cl.insert("{ \"empno\": 10007, \"ename\": \"Trancer\", \"age\": " +
          "11}}");
// Transaction rollbacks.
db.rollback();
db.beginTransaction();
cl.insert("{ \"empno\": 10008, \"ename\": \"Actioner\", \"age\": " +
          "12}}");
db.commit();
db.rollback();
关于SDB连接池

Java SDK 驱动包中已经提供了封装好的连接池对象。但使用连接池之前,需要用户根据实际情况,对连接池进行一些参数配置。在 Java 中,巨杉数据库连接池对象为 com.sequoiadb.datasource.SequoiadbDatasource,构造此对象时,需要指定数据库地址列表(List形式)、用户名、密码,以及要传入 com.sequoiadb.base.ConfigOptions 和 com.sequoiadb.datasource.DatasourceOptions 对象作为参数。ConfigOptions 和 DatasourceOptions 自身所带的方法,可以设置一些连接池配置参数,具体参数释义如下:

参数入口所属对象释义
setConnectTimeoutConfigOptions建连超时时间,单位毫秒
setMaxAutoConnectRetryTimeConfigOptions建连失败后重试时间,单位毫秒
setMaxCountDatasourceOptions连接池最多能提供500个连接
setDeltaIncCountDatasourceOptions每次增加20个连接
setMaxIdleCountDatasourceOptions连接池空闲时,保留20个连接
setKeepAliveTimeoutDatasourceOptions池中空闲连接存活时间,单位:毫秒,0表示不关心连接隔多长时间没有收发消息
setCheckIntervalDatasourceOptions每隔60秒将连接池中多于 MaxIdleCount限定的空闲连接关闭,并将存活时间过长(连接已停止收发超过keepAliveTimeout时间)的连接关闭
setSyncCoordIntervalDatasourceOptions向catalog同步coord地址的周期,单位:毫秒,0表示不同步
setValidateConnectionDatasourceOptions连接出池时,是否检测连接的可用性,默认不检测
setConnectStrategyDatasourceOptions默认使用coord地址负载均衡的策略获取连接

模板

ArrayList<String> addrs = new ArrayList<>();
ConfigOptions nwOpt = new ConfigOptions();
DatasourceOptions dsOpt = new DatasourceOptions();

// Provide the coord node addresses, and multiple can be added.
addrs.add("sdbserver1" + ":" + 11810);

// Set the network parameters.
nwOpt.setConnectTimeout(500); // The connection establishment timeout period is 500ms
nwOpt.setMaxAutoConnectRetryTime(0); // The retry time after connection establishment fails is 0ms

// Set the connection pool parameters.
dsOpt.setMaxCount(500); // The connection pool can provide up to 500 connections.
dsOpt.setDeltaIncCount(20); // Add 20 connections at a time.
dsOpt.setMaxIdleCount(20); // When the connection pool is idle, 20 connections are reserved.
dsOpt.setKeepAliveTimeout(0); // The survival time of idle connections in the pool. Unit: ms.
// 0 means that it is indifferent to how long the connection has not been sent or received.
dsOpt.setCheckInterval(60 * 1000); 
// Close the idle connections in the connection pool that are more than MaxIdleCount limit every 60 seconds.
// Close the connection with a long survival time (the connection has stopped sending and receiving beyond the keepAliveTimeout time). 
// Synchronize the period of the coord address to the catalog. Unit: milliseconds.
// 0 means out of sync.
dsOpt.setSyncCoordInterval(0);
// When the connection is out of the pool, the availability of the connection is checked. The default is non-detection.
dsOpt.setValidateConnection(false);
// Use coord address load balancing strategy to obtain connection by default.
dsOpt.setConnectStrategy(ConnectStrategy.BALANCE);

// Establish a connection pool.
ds = new SequoiadbDatasource(addrs, "sdbadmin", "sdbadmin",
                             nwOpt, dsOpt);
分区
// Create an employee collection.
BSONObject options = new BasicBSONObject();
BasicBSONObject shardingKey = new BasicBSONObject();
// Use the age field as the partition key.
shardingKey.put("age", 1);
options.put("ShardingKey", shardingKey);
// Set the consistency of the collection.
options.put("ReplSize", 1);
// Set partition type.
options.put("ShardingType", "hash");
// The number of partitions. It is only filled in when the hash partition is selected, and represents the number of hash partitions.
// Its value must be a power of 2, and the range is [2 ^ 3, 2 ^ 20]. The default is 4096.
options.put("Partition", 4096);
// Indicate whether the new collection is enabled for automatic segmentation, and the default is false.
options.put("AutoSplit", true);
// Indicates whether the new collection is enabled for data compression, and the default is true.
options.put("Compressed", true);
// Type of compression algorithm. The default is the lzw algorithm. The selectable values are as follows:
// "snappy": Use the snappy algorithm to compress.
// "lzw": Use the lzw algorithm for compression.
options.put("CompressionType", "lzw");
cs.createCollection("employee", options);
属性释义
ShardingKey分区键
ShardingType默认为 hash 分区。其可选取值如下: “hash”:hash 分区; “range”:范围分区;
Partition分区数。仅当选择 hash 分区时填写,代表了 hash 分区的个数。 其值必须是2的幂。范围在[23,220]。默认为4096
AutoSplit标示新集合是否开启自动切分功能,默认为 false
Compressed标示新集合是否开启数据压缩功能,默认为 true
CompressionType压缩算法类型。默认为 lzw 算法。其可选取值如下: “snappy”:使用 snappy 算法压缩; “lzw”:使用 lzw 算法压缩;

S3对象储存应用(12.09)

介绍

Amazon Simple Storage Service更好地称为Amazon S3 。 它是存储即服务解决方案,并提供了用于在云上存储和检索数据的简单界面。

换句话说,它为任何应用程序存储需求提供了基础架构。 您的应用程序可以存储和检索高达5TB的较大文件,这是快速,高效和可靠的。 并且它提供了不错的访问接口,例如用于通过编程方式从Web浏览器访问的Web管理控制台以及REST API和SOAP接口。

水桶

桶是存储数据的基本容器。 每个对象都存储在存储桶中。 每个存储桶可以没有任何编号。 存储在其中的数据对象。 桶名称在整个Amazon S3中是唯一的。 因此,一旦创建存储桶,请仔细命名存储桶。 它不能重命名。

可以使用以下两种格式访问存储区,以下是存储区url的格式-存储区名称作为子域http:// <存储区名称> .s3.amazonaws.com / <对象名称>或存储区名称作为路径http: //s3.amazonaws.com/ <存储桶名称> / <对象名称>

其中, bucket-name存储桶的名称 object-name是存储在存储桶中的对象名称,例如。 我们将照片文件存储在mypics存储桶中,然后https://mypics.s3.amazonaws.com/photo.png

存储桶提供了更高级别的名称空间以及组织存储在s3内部的数据对象的方式。 此外,您可以通过在存储桶周围创建策略来将访问控制应用于存储桶以限制访问。

对象

对象是存储在Amazon S3中的基本实体。 对象存储在存储桶中。

对象由数据和元数据组成。 数据部分可以是任何东西,但是元数据通常是描述对象的一组键值对。 此元数据可以是常见的内容,例如提供的日期创建,日期修改,mime类型或自定义元数据

因此,作为用户,您可以使用提供的简单Web服务界面来读取,写入,删除存储桶中的数据对象,该界面非常易于使用,任何人都可以立即开始使用它。

对象标签(tag)

使用存储对象打标签对存储进行分类。每个标签都是一个键-值对。
您可以将标签添加到新对象 (当您上传新对象时),也可以将标签添加到现有对象。请注意以下几点:

  • 您最多可以将 10 个标签与对象关联。与对象关联的标签必须具有唯一的标签键。
  • 标签键的长度最大可以为 128 个 Unicode 字符,标签值的长度最大可以为 256 个 Unicode 字符。
  • 键和值区分大小写
Sdb对S3的支持

AWS S3 提供的有对集群中存储桶的创建接口 createBucket(String str),该接口在SequoiaS3 中同样适用,可以通过 S3 对象直接调用该接口,创建指定的存储桶。

配置SequoiaDB

  1. SequoiaS3 对接的 SequoiaDB 需开启 RC 级别事务,且配置为等锁模式

    > var db = new Sdb( "localhost", 11810 )
    > db.updateConf( { transactionon:true, transisolation:1, translockwait:true} )
    
  2. 配置SS3

    vi /opt/sequoiadb/tools/sequoias3/config/application.properties
    
    server.port=8002
    
    sdbs3.sequoiadb.url=sequoiadb://xxx:11810,xxx:11810
    sdbs3.sequoiadb.meta.domain=domain1
    sdbs3.sequoiadb.data.domain=domain2
    
  3. 启动SS3服务

    ./sequoias3.sh start
    
更多配置

http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1576827433-edition_id-500

SS3的兼容性例子

创建区域

创建一个名为 region-example 的区域,该区域设置为每年创建一个集合空间,在该集合空间中每月创建一个新的集合,用于存放对象数据

CreateRegionRequest request = new CreateRegionRequest(regionName)
            .withDataCLShardingType(DataShardingType.MONTH)
            .withDataCSShardingType(DataShardingType.YEAR);
sequoiaS3.createRegion(request);

JAVA对接SS3的配置

对存储桶,对象,存储区域操作.
  1. 生成一个 AmazonS3 连接和一个 SequoiaS3 连接时,需要修改 endPoint 的地址和端口,使其指向 SequoiaS3 的地址和端口。

    AWSCredentials credentials = new BasicAWSCredentials("ABCDEFGHIJKLMNOPQRST", "abcdefghijklmnopqrstuvwxyz0123456789ABCD");//构造函数参数(accessKey,secretkey)
            String endPoint = "http://127.0.0.1:8002";
            AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endPoint, null);
            AmazonS3 s3 = AmazonS3ClientBuilder.standard()
                    .withEndpointConfiguration(endpointConfiguration)
                    .withCredentials(new AWSStaticCredentialsProvider(credentials))
                    .build();
    
            return s3;
    
  2. 建立一个创建桶的方法

    public static void putBucket(String bucket) {
            try {
                s3.createBucket(bucket);
            } catch (AmazonServiceException e) {
                System.err.println(e.getStatusCode());
                System.err.println(e.getErrorCode());
                System.err.println(e.getErrorMessage());
            }
        }
    
关于元数据的操作

对象由对象数据和元数据组成,对象数据是存储的具体内容,而元数据则是包含了对该内容的描述。对象元数据是一组名称值对,可以在上传对象元数据时对其进行设置。上传对象后将无法修改对象元数据。

例子

//Get the S3 connection
AmazonS3 s3 = this.getS3();
//Create a bucket to use
s3.createBucket(bucketName);
//Create file input stream
File file = new File("/opt/sequoiadb/version.conf");
InputStream inputStream = new FileInputStream(file);
//Get metadata object
ObjectMetadata objectMetadata = new ObjectMetadata();
//Set metadata properties
objectMetadata.setContentLength(file.length());
objectMetadata.setContentLanguage("CH");
objectMetadata.setContentEncoding("utf8");
objectMetadata.setContentType("text/plain");
//Save the uploaded file as an object and set the object metadata
s3.putObject(bucketName,objectName,inputStream,objectMetadata);
inpuStream.close();
创建LOB对象存储及数据操作

获取sdb对象

Sequoiadb sequoiadb=null;
// addr, port, username, password
sequoiadb = new Sequoiadb("sdbserver1", 11810, "", "");

将lob对象上传到sdb

img



//Get the collection space object
CollectionSpace cs = sequoiadb1.createCollectionSpace(csName);
//Get collection object
DBCollection cl = cs.createCollection(clName);

//Create the Lob
DBLob lob = cl.createLob();
ObjectId id = lob.getID();
//Print oid, and a unique oid will be generated when the Lob object is created
String s = id.toString();
fileInputStream = new FileInputStream(file);
//Write data to the Lob
lob.write(fileInputStream);
//Close the Lob
lob.close();

查询sdb的cl

//Get the collection space object
CollectionSpace cs = sequoiadb1.getCollectionSpace(csName);
//Get collection object
DBCollection cl = cs.getCollection(clName);
//Get the list of Lob in the collection
DBCursor cursor = cl.listLobs();
try {
//Traverse the Lob list and output Lob information
while (cursor.hasNext()) {
BSONObject record = cursor.getNext();
System.out.println(record.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
cursor.close();
}

通过FileIO流下载lob

//Get the specified Lob object by oid
DBLob dbLob = cl.openLob(new ObjectId(""));
FileOutputStream fileOutputStream = null;
try {
//Get the file output stream, and set the file path and file name
fileOutputStream = new FileOutputStream(new File("/home/shiyanlou/Desktop/sequoiadb.txt"));
//Read the Lob and write to the local
dbLob.read(fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
dbLob.close();
}

删除LOB

//Get the collection space object
CollectionSpace cs = sequoiadb1.getCollectionSpace(csName);
//Get the collection object
DBCollection cl = cs.getCollection(clName);
//Delete the specified Lob
cl.removeLob(new ObjectId(""));
LOB对象存储分区

LOB 对象,在水平分区类型中只适合于 Hash 分区。在下面的例子中,使用 Hash 分区方式,分区个数为 4096,分区键为 sid。然而对于 LOB 对象,它的分区键是OID 加分片序号,通过 Hash 分散存储在相应的分区组中。

Hash 方式下根据记录中分区键生成的 Hash 值选择所要插入的分区。ShardingType 如果不填则默认为 Hash 分区。

在 Hash 方式分区中,用户不指定每个分区的范围,而是指定集合切分的分区个数(Partition),其值必须是 2 的幂,范围在[ 23 , 220 ],默认为 4096 个,代表我们将整个范围平均划分为 4096 个分区。设计 Hash 分区的目的是让数据分布更灵活,可以根据需要自由设置每个数据分区承担 Hash 分区的范围

Sequoiadb sequoiadb = this.getSdbConnect();
CollectionSpace cs = sequoiadb.createCollectionSpace(csName);
BasicBSONObject cl_options = new BasicBSONObject();
//set collection params
cl_options.put("ShardingType","hash");
cl_options.put("ShardingKey",new BasicBSONObject("sid",1));
cl_options.put("Partition",4096);
cl_options.put("AutoSplit",true);
//create collection
cs.createCollection(clName,cl_options);

垂直分区分为主集合和子集合,主集合必须用 Range 切分,子集合用Hash切分,也可用 Hash,ShardingKey 也不必和主集合的一致。

创建垂直分区集合步骤

垂直分区的创建分为以下几个步骤

  1. 创建主集合,主集合必须是 Range 分区类型;
  2. 创建子集合,子集合使用 Hash 分区;
  3. 将子集合 1、子集合 2 关联到主集合中。

每个子集合都有一个范围,对于用途为存放 LOB 的集合,该范围为时间范围。插入 LOB 对象时插入主集合,这时会通过 LOB 对象的 LOBID 判断该 LOB 上传的时间,进而判断该插入到哪一个子集合中。

通过IO流实现SDBFS写读文件

InputStream put = new FileInputStream("/home/sdbadmin/sequoiadb.txt");
OutputStream out  = new FileOutputStream("/opt/sequoiafs/mountpoint/sequoiadb.txt");
byte[] cbuf = new byte[1024];
int len = 1024;
//How many bytes of file are read at a time
while((len = put.read(cbuf))!= -1){
    out.write(cbuf,0,len);
    out.flush();
}
put.close();

//Get the file input stream
InputStreamReader put = new InputStreamReader(new FileInputStream("/opt/sequoiafs/mountpoint/sequoiadb.txt"), "utf-8");
char[] cbuf = new char[1024];
int len = 1024;
//Read the file content and output to console
while((len = put.read(cbuf))!= -1){
    System.out.println(new String(cbuf, 0, len));
}
put.close();

Spark 实例应用开发环境

关于spark

  1. Spark包含了大数据领域常见的各种计算框架:比如Spark Core用于离线计算,Spark SQL用于交互式查询,Spark Streaming用于实时流式计算,Spark MLib用于机器学习,Spark GraphX用于图计算
  2. Spark主要用于大数据的计算,而Hadoop以后主要用于大数据的存储(比如HDFS、Hive、HBase)等,,以及资源调度(Yarn)
  3. Spark+hadoop的组合是大数据领域最热门的组合,也是最有前景的组合
  4. Spark与MapReduce计算过程,Spark基于内存进行计算,所以速度更快
Spark基本概念

在具体讲解Spark运行架构之前,需要先了解几个重要的概念:

  • RDD:是弹性分布式数据集(Resilient Distributed Dataset)的简称,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型
  • DAG:是Directed Acyclic Graph(有向无环图)的简称,反映RDD之间的依赖关系
  • Executor:是运行在工作节点(Worker Node)上的一个进程负责运行任务,并为应用程序存储数据;
  • 应用:用户编写的Spark应用程序;
  • 任务:运行在Executor上的工作单元
  • 作业:一个作业包含多个RDD及作用于相应RDD上的各种操作
  • 阶段:是作业的基本调度单位,一个作业会分为多组任务,每组任务被称为“阶段”,或者也被称为“任务集”。

Spark运行架构包括集群资源管理器(Cluster Manager)、运行作业任务的工作节点(Worker Node)、每个应用的任务控制节点(Driver)和每个工作节点上负责具体任务的执行进程(Executor)。其中,集群资源管理器可以是Spark自带的资源管理器,也可以是YARN或Mesos等资源管理框架。

这里写图片描述

由于 Spark SQL 使用的 Thrift JDBC server 和 Hive 的 HiveServer2 是一致的,因此可以通过 Hive JDBC 访问 Spark SQL。Spark SQL 和 SequoiaDB 交互主要是通过在 Spark SQL 中创建 SequoiaDB 集合的映射表实现的,通过 Hive JDBC 提交读写映射表的 SQL 语句,即可达到操作 SequoiaDB 存储集群中的数据的目的。

创建连接

// Call the predefined SdbUtil class to create a collection space and collection
SdbUtil.initCollectionSpace("sample");
SdbUtil.initCollection("sample", "jdbc_sample");
// Load Hive JDBC driver
Class.forName("org.apache.hive.jdbc.HiveDriver");
// Create a Hive JDBC connection
Connection connection = DriverManager.getConnection(
        "jdbc:hive2://sdbserver1:10000/default",// Hive JDBC connection url
        "sdbadmin",// Hive JDBC connection user name
        ""// Hive JDBC connection password (authentication is not enabled by default)
);
// Create Statement
Statement statement = connection.createStatement();
// Drop the existing table
String dropTable = "DROP TABLE IF EXISTS jdbc_sample";
// Execute the SQL statement of drop table
statement.execute(dropTable);
// Create a mapping table
String mapping =
        "CREATE TABLE jdbc_sample ( id INT, val VARCHAR ( 10 ) )" +
                "USING com.sequoiadb.spark " +
                "OPTIONS(" +
                "host 'sdbserver1:11810'," +
                "collectionspace 'sample'," +
                "collection 'jdbc_sample'" +
                ")";
// Execute the SQL statement of create a mapping table
statement.execute(mapping);
// Insert record
String insert = "INSERT INTO jdbc_sample VALUES ( 1, 'SequoiaDB' )";
// Execute the SQL statement of insert record
statement.executeUpdate(insert);
// Query record
String query = "SELECT * FROM jdbc_sample";
// Execute the SQL statement of query record to get result set
ResultSet resultSet = statement.executeQuery(query);
// Call the predefined result set to beautify the utility class and print the result set
ResultFormat.printResultSet(resultSet);
// Release JDBC sources
resultSet.close();
statement.close();
connection.close();

ntpoint/sequoiadb.txt"), “utf-8”);
char[] cbuf = new char[1024];
int len = 1024;
//Read the file content and output to console
while((len = put.read(cbuf))!= -1){
System.out.println(new String(cbuf, 0, len));
}
put.close();


## Spark 实例应用开发环境

### 关于spark

1. Spark包含了大数据领域常见的各种计算框架:比如Spark Core用于离线计算,Spark SQL用于交互式查询,Spark Streaming用于实时流式计算,Spark MLib用于机器学习,Spark GraphX用于图计算
2. Spark主要用于大数据的计算,而Hadoop以后主要用于大数据的存储(比如HDFS、Hive、HBase)等,,以及资源调度(Yarn)
3. Spark+hadoop的组合是大数据领域最热门的组合,也是最有前景的组合
4. Spark与MapReduce计算过程,**Spark基于内存进行计算**,所以速度更快

#### Spark基本概念

在具体讲解Spark运行架构之前,需要先了解几个重要的概念:

- RDD:是弹性分布式数据集(Resilient Distributed Dataset)的简称,是**分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型**;
- DAG:是Directed Acyclic Graph(有向无环图)的简称,反映**RDD之间的依赖关系**;
- Executor:是运行在**工作节点(Worker Node)上的一个进程**,**负责运行任务**,并为应用程序存储数据;
- 应用:**用户编写**的Spark应用程序;
- 任务:运行在Executor上的**工作单元**;
- 作业:**一个作业包含多个RDD及作用于相应RDD上的各种操作**;
- 阶段:是**作业的基本调度单位**,一个作业会分为多组任务,每组任务被称为“阶段”,或者也被称为“任务集”。

Spark运行架构包括**集群资源管理器**(Cluster Manager)、**运行作业任务的工作节点**(Worker Node)、每个应用的**任务控制节点**(Driver)和**每个工作节点上负责具体任务的执行进程**(Executor)。其中,集群资源管理器可以是Spark自带的资源管理器,也可以是YARN或Mesos等资源管理框架。

![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/9651fff7b167557c527028d6800437b9.png)

由于 Spark SQL 使用的 Thrift JDBC server 和 Hive 的 HiveServer2 是一致的,因此可以通过 Hive JDBC 访问 Spark SQL。Spark SQL 和 SequoiaDB 交互主要是通过在 Spark SQL 中创建 SequoiaDB 集合的映射表实现的,通过 Hive JDBC 提交读写映射表的 SQL 语句,即可达到操作 SequoiaDB 存储集群中的数据的目的。

### 创建连接

```java
// Call the predefined SdbUtil class to create a collection space and collection
SdbUtil.initCollectionSpace("sample");
SdbUtil.initCollection("sample", "jdbc_sample");
// Load Hive JDBC driver
Class.forName("org.apache.hive.jdbc.HiveDriver");
// Create a Hive JDBC connection
Connection connection = DriverManager.getConnection(
        "jdbc:hive2://sdbserver1:10000/default",// Hive JDBC connection url
        "sdbadmin",// Hive JDBC connection user name
        ""// Hive JDBC connection password (authentication is not enabled by default)
);
// Create Statement
Statement statement = connection.createStatement();
// Drop the existing table
String dropTable = "DROP TABLE IF EXISTS jdbc_sample";
// Execute the SQL statement of drop table
statement.execute(dropTable);
// Create a mapping table
String mapping =
        "CREATE TABLE jdbc_sample ( id INT, val VARCHAR ( 10 ) )" +
                "USING com.sequoiadb.spark " +
                "OPTIONS(" +
                "host 'sdbserver1:11810'," +
                "collectionspace 'sample'," +
                "collection 'jdbc_sample'" +
                ")";
// Execute the SQL statement of create a mapping table
statement.execute(mapping);
// Insert record
String insert = "INSERT INTO jdbc_sample VALUES ( 1, 'SequoiaDB' )";
// Execute the SQL statement of insert record
statement.executeUpdate(insert);
// Query record
String query = "SELECT * FROM jdbc_sample";
// Execute the SQL statement of query record to get result set
ResultSet resultSet = statement.executeQuery(query);
// Call the predefined result set to beautify the utility class and print the result set
ResultFormat.printResultSet(resultSet);
// Release JDBC sources
resultSet.close();
statement.close();
connection.close();
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值