近些年來,數(shù)據(jù)庫國產(chǎn)化成為大的趨勢,涌現(xiàn)出一批數(shù)據(jù)庫廠商。這些產(chǎn)品或基于開源構(gòu)建、或全新自研,通過較短時間的發(fā)展取得了不俗的成績。近期受邀對國產(chǎn)數(shù)據(jù)庫-YashanDB的最新版本進(jìn)行了評測,進(jìn)而對這一新興國產(chǎn)數(shù)據(jù)庫有了較完整的認(rèn)識,也為我們國產(chǎn)數(shù)據(jù)庫取得進(jìn)步感到欣喜。后續(xù)的測試內(nèi)容,是基于 YashanDB 最新版本-v23.1版本進(jìn)行的測試。感興趣的同學(xué),也可以通過如下鏈接獲取免費(fèi)版本進(jìn)行測試。
下載鏈接:http://download.yashandb.com。
一、YashanDB 簡要介紹
崖山數(shù)據(jù)庫管理系統(tǒng)(YashanDB)是深圳計算科學(xué)研究院在經(jīng)典數(shù)據(jù)庫理論基礎(chǔ)上,融入新的原創(chuàng)理論,自主設(shè)計、研發(fā)的新型數(shù)據(jù)庫管理系統(tǒng)。第一次看到Y(jié)ashanDB的架構(gòu)及能力,還是挺驚訝的,感覺是一個集“Oracle單機(jī)+DataGuard+RAC+分布式MPP(Shared-Nothing)”于一身的全面手。為了更好的理解,我簡單列個表格說明下。
1、多部署架構(gòu)
(1)主備架構(gòu)
(2)共享集群架構(gòu)
(3)分布式架構(gòu)
2、多存儲引擎
存儲引擎是數(shù)據(jù)庫核心部件之一,YashanDB通過不同的存儲引擎適應(yīng)不同的應(yīng)用場景,以獲得面向在線交易場景的高效事務(wù)處理能力,面向?qū)崟r分析場景的事務(wù)與分析均衡能力,和面向海量穩(wěn)態(tài)數(shù)據(jù)分析場景的高性能?;诓煌拇鎯σ?,YashanDB支持的表類型有HEAP表,TAC表和LSC表。
- HEAP Table:行存表,主打OLTP場景。
- TAC Table (Transaction Analytics Columnar Table) :列存表,主打?qū)崟r分析場景。
- LSC Table (Large-scale Storage Columnar Table):列存表,主打海量穩(wěn)態(tài)數(shù)據(jù)的交互式分析場景。
3、多計算引擎
作為SQL引擎的核心組件,YashanDB的優(yōu)化器采用CBO(Cost Based Optimizer)優(yōu)化模式,基于統(tǒng)計信息,計算數(shù)據(jù)訪問和處理所需要的代價,選擇代價最低的方案生成執(zhí)行計劃。另外YashanDB 支持多種計算引擎,包括基于火山模型的執(zhí)行引擎、向量化執(zhí)行引擎及PL/SQL 引擎。針對大數(shù)據(jù)量下的列計算,YashanDB采用向量化執(zhí)行模型,利用SIMD原理對某一列數(shù)據(jù)進(jìn)行批量處理和計算,提高CPU利用率,大批量地減少程序循環(huán)。PL/SQL為數(shù)據(jù)庫內(nèi)部引擎,能夠靈活高效地訪問數(shù)據(jù)庫對象,其語法基于SQL語言擴(kuò)展,可編程性強(qiáng),支持用戶將業(yè)務(wù)邏輯下沉到數(shù)據(jù)層,更接近數(shù)據(jù)更高效,并可通過多級封裝實(shí)現(xiàn)安全、隔離、簡潔的接口供多應(yīng)用系統(tǒng)調(diào)用。
4、多發(fā)行版本
YashanDB 也支持多種發(fā)行版本,滿足不同需求。
- 個人版:YashanDB面向個人用戶推出的免費(fèi)試用版本,除不支持多模數(shù)據(jù) 類型、高級安全能力、數(shù)據(jù)庫集群等企業(yè)級功能,該版本包含YashanDB數(shù)據(jù)庫所有基礎(chǔ)核心能力,支持單機(jī)主備部署形態(tài),配套開發(fā)者工具;同時對最大連接數(shù)、表空間限額、列存、運(yùn)維和數(shù)據(jù)遷移工具等做了限制。供個人用戶或開發(fā)者用于學(xué)習(xí)、測試、開發(fā)用途。
- 標(biāo)準(zhǔn)版:YashanDB面向小規(guī)模用戶推出的商業(yè)版本,該版本價格適中,除不支持多模數(shù)據(jù)類型、高級安全能力等企業(yè)級功能,該版本包含YashanDB數(shù)據(jù)庫所有基礎(chǔ)核心能力,支持單機(jī)主備、分布式、集群部署形態(tài),配套完整數(shù)據(jù)遷移和監(jiān)控運(yùn)維工具,可以為政府或中小企業(yè)提供支持其操作所需的基本能力。
- 企業(yè)版:YashanDB面向大規(guī)模用戶推出的商業(yè)版本,該版本包含YashanDB數(shù)據(jù)庫完整核心能力,支持PB級海量數(shù)據(jù)存儲和大量的并發(fā)用戶,支持模數(shù)據(jù)類型、高級安全能力,支持單機(jī)主備、分布式、集群部署形態(tài),配套完整數(shù)據(jù)遷移和監(jiān)控運(yùn)維工具,可以滿足支撐各類企業(yè)應(yīng)用。
二、 YashanDB 新版本評測
YashanDB 功能很多,覆蓋多種架構(gòu)及形態(tài),可滿足多種場景。受個人精力所限,此次評測僅針對發(fā)布版本的亮點(diǎn)功能-Oracle兼容性,進(jìn)行了簡單測試。從 Oracle DBA 角度來看,YashanDB 與 Oracle 的兼容度頗高,產(chǎn)品無論從設(shè)計理念、到核心功能、再到生態(tài)工具,都兼顧了 Oracle 的能力及操作習(xí)慣,甚至在部分能力上還有所增強(qiáng)。因此無論是使用者、開發(fā)者、管理者等角度看,相對上手的難度都不大。當(dāng)然 Oracle 兼容性本身功能也是很復(fù)雜,可參考我之前寫的文章,想做到完全兼容是不太現(xiàn)實(shí)的。下面挑選了部分對比項進(jìn)行評測,其中部分內(nèi)容通過官網(wǎng)文檔內(nèi)容說明,未做進(jìn)一步測試。特別聲明:以下測試結(jié)果僅代表個人意見,不作為產(chǎn)品選型評估依據(jù)。
1、數(shù)據(jù)類型
數(shù)據(jù)類型部分,情況則相對復(fù)雜。Oracle 支持的數(shù)據(jù)類型范圍較廣,YashanDB 支持了大部分?jǐn)?shù)據(jù)類型,但在處理精度、存儲空間等方面與Oracle還是有所區(qū)別。下面針對主要的數(shù)據(jù)類型進(jìn)行了測試。
-- 測試字符類型
SQL> create table test_char(
country_id char,
city_id nchar(2),
address varchar2(4000),
name nvarchar2(40)
);
Succeed.
SQL> insert into test_char values ('1', '11', '北京市海淀區(qū)', '張三');
1 row affected.
SQL> select * from test_char;
COUNTRY_ID CITY_ID ADDRESS NAME
---------- --------- ------------------------ -------------------------------------
1 11 北京市海淀區(qū) 張三
-- 測試數(shù)字類型
SQL> create table test_num(
n1 number,
n2 number(38),
n3 number(9,2),
n4 int,
n5 smallint,
n6 decimal(5,2),
n7 float,
n8 float(2),
n9 real,
n10 binary_float,
n11 binary_double
);
Succeed.
SQL> insert into test_num values (1.23, 123, 7456123.89, 573, 34, 673.43, 34.1264, 56.2, 23.231, 12.34, 34.56);
1 row affected.
SQL> select * from test_num;
N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11
----------- ----------- ----------- ------------ -------- ----------- ----------- ----------- ----------- ----------- -----------
1.23 123 7456123.89 573 34 673.43 3.413E+001 5.62E+001 2.323E+001 1.234E+001 3.456E+001
1 row fetched.
SQL> insert into test_num values (1.23, 123, 7456123.89, 573, 34, 673.43, 34.1264, 56.2, 23.231, 12.34f, 34.56d);
select * from test_num;
[1:98]YAS-04105 invalid number character f
// 在Oracle中可以使用f或F表示前面是個浮點(diǎn)數(shù),目前YashanDB還不支持這種寫法。
-- 擴(kuò)展類型
SQL> create table test_long_varchar(a varchar2(8000));
Succeed.
// YashanDB還針對部分?jǐn)?shù)據(jù)類型,支持了更大的值域范圍,如示例中的VARCHAR2類型。
-- 測試日期/時間類型
SQL> create table test_date(
t1 date,
t2 timestamp(6),
t3 interval year(3) to month,
t4 interval day(3) to second(6)
);
Succeed.
SQL> insert into test_date values(sysdate,sysdate,INTERVAL '1' YEAR,INTERVAL '1' DAY);
1 row affected.
SQL> select * from test_date;
T1 T2 T3 T4
------------- ---------------------------------- --------------- -----------------------
2023-10-27 2023-10-27 16:52:49.000000 +01-00 +01 00:00:00.000000
SQL> create table test_date_timezone(
t1 timestamp(9) with time zone,
t2 timestamp with local time zone
);
[2:17]YAS-04209 unexpected word with
// 目前YashanDB還不支持帶有時區(qū)的類型
-- 測試布爾型
SQL> create table test_bool ( a boolean);
Succeed.
SQL> insert into test_bool values(true);
1 row affected.
SQL> insert into test_bool values(false);
1 row affected.
SQL> select * from test_bool;
A
--------------------
true
false
// YashanDB 增加了 Oracle 不支持的布爾類型。
-- 測試大對象類型
SQL> create table test_bigfile(
f1 long,f2 blob,f3 clob,f4 nclob,f5 bfile);
[2:1]YAS-04229 invalid datatype
SQL> create table test_bigfile(
f1 blob,f2 clob);
Succeed.
SQL> insert into test_bigfile (f1, f2) values ('1', '2');
1 row affected.
SQL> select * from test_bigfile;
F1 F2
---------------------------------------------------------------- ----------------------------------------------------------------
01 2
1 row fetched.
2、字符集及排序
字符集方面,常見的中文字符集(gbk、gb18030)及utf8系列字符集是支持重點(diǎn)。從官網(wǎng)上查看YashanDB支持的字符集,具體如下。針對字符集排序方面,YashanDB 支持部分Oracle排序能力,還有部分尚不支持。
-- 查看當(dāng)前字符集
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------------------
UTF8
-- 測試排序
SQL> create table test_sort(name varchar2(20));
Succeed.
SQL> insert into test_sort values('張三');
SQL> insert into test_sort values('李四');
SQL> select * from test_sort;
NAME
---------------------
張三
李四
SQL> SELECT name FROM test_sort ORDER BY NLSSORT(name,'NLS_SORT=SCHINESE_PINYIN_M');
NAME
---------------------
李四
張三
-- 按偏旁部首排序(不支持)
SQL> SELECT name FROM test_sort ORDER BY NLSSORT(name,'NLS_SORT=SCHINESE_RADICAL_M');
[3:23]YAS-04352 invalid NLS parameter string used in SQL function
-- 按筆畫排序(不支持)
SQL> SELECT name FROM test_sort ORDER BY NLSSORT(name,'NLS_SORT=SCHINESE_STROKE_M');
[3:23]YAS-04352 invalid NLS parameter string used in SQL function
3、數(shù)據(jù)庫對象
在數(shù)據(jù)庫對象方面,Oracle 支持非常豐富的對象類型,包括但不限于表、索引、分區(qū)、視圖、序列、同義詞、觸發(fā)器、DB Link等等。YashanDB 支持了大部分?jǐn)?shù)據(jù)類型,支持部分的對象尚有部分能力與Oracle還是有所區(qū)別。
-- 【測試表】
---- 堆表
SQL> create table test_heap ( id int,name varchar2(10));
Succeed.
-- 索引組織表(不支持)
SQL> create table test_iot(id varchar2 (10),name varchar2(20),
constraint pk_id primary key(id)
) organization index;
[6:14]YAS-04247 invalid table type
-- 簇表(不支持)
SQL> create cluster test_cluster(id number);
[1:16]YAS-04115 "DATABASE" expected but missing
-- 臨時表
SQL> create global temporary table test_temp_tran (
tid number(3), tname varchar2(30)
) on commit delete rows;
Succeed.
SQL> create global temporary table test_temp_sess(
tid number(3), tname varchar2(30)
) on commit preserve rows;
Succeed.
SQL> create private temporary table yas$ptt_privatetemtable(c1 int,c2 int);
Succeed.
// YashanDB還支持一種新的臨時表類型-private temporary。
// 該語句只作用于單機(jī)HEAP/TAC表,用于指定創(chuàng)建的表為私有臨時表。
// 在某個會話中創(chuàng)建的私有臨時表,其表結(jié)構(gòu)及數(shù)據(jù)只對本會話可見。
// 私有臨時表的名稱必須為YAS$PTT_開頭。
--壓縮表
SQL> create table test_compress(id number,name varchar2(20)) compress;
Succeed.
-- 分區(qū)
SQL> create table test_partition(product_id varchar2(5), sales_count number(10,2))
partition by range(sales_count)
(
partition p1 values less than(1000),
partition p2 values less than(2000),
partition p3 values less than(3000)
);
SQL> SELECT PARTITION_NAME,HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='TEST_PARTITION';
PARTITION_NAME HIGH_VALUE
------------------- ----------------
P1 1000
P2 2000
P3 3000
SQL> insert into test_partition values('1',600);
1 row affected.
SQL> insert into test_partition values('2',1000);
1 row affected.
SQL> insert into test_partition values('3',2300);
1 row affected.
SQL> insert into test_partition values('4',6000);
YAS-02115 partition key does not map to any partition
SQL> commit;
SQL> select * from test_partition partition(p1);
PRODUCT_ID SALES_COUNT
---------- -----------
1 600
-- 增加一個分區(qū)
SQL> alter table test_partition add partition p4 values less than(maxvalue);
SQL> insert into test_partition values('4',6000);
1 row affected.
SQL> SELECT PARTITION_NAME,HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='TEST_PARTITION';
PARTITION_NAME HIGH_VALUE
------------------- ----------------
P1 1000
P2 2000
P3 3000
P4 maxvalue
-- 復(fù)合分區(qū)(List+Hash)
CREATE TABLE TEST_LIST_HASH (vl1 varchar2(20),vl2 number(12))
PARTITION BY LIST (vl1)
SUBPARTITION BY HASH (vl2)
SUBPARTITION TEMPLATE
(
SUBPARTITION SP1,
SUBPARTITION SP2,
SUBPARTITION SP3,
SUBPARTITION SP4
)
(
PARTITION P1 VALUES ('MIN', 'HOUR','SECOND'),
PARTITION P2 VALUES ('DAY', 'MONTH','YEAR'),
PARTITION P3 VALUES (DEFAULT)
);
-- 【索引】
---- BTree索引
SQL> create table test_index( a int,b int,c int,d int);
Succeed.
SQL> create index idx_test_a on test_index(a);
Succeed.
SQL> create index idx_test_ab on test_index(a,b);
Succeed.
SQL> create index idx_test_c on test_index(c desc);
Succeed.
-- Bitmap索引(不支持)
SQL> create table test_bitmap_index(a int,b int);
Succeed.
SQL> create bitmap index on test_bitmap_index(a);
[1:8]YAS-04225 invalid word bitmap
-- 基于函數(shù)的索引
SQL> create table test_fbi(a int,b int);
Succeed.
SQL> create index idx_fbi on test_fbi(abs(a));
Succeed.
SQL> explain plan for select * from test_fbi where abs(a)=1;
+----+--------------------------------+----------------------+------------+----------+
| Id | Operation type | Name | Owner | Rows |
+----+--------------------------------+----------------------+------------+----------+
| 0 | SELECT STATEMENT | | | |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_FBI | HFUSER1 | |
|* 2 | INDEX RANGE SCAN | IDX_FBI | HFUSER1 | 100|
+----+--------------------------------+----------------------+------------+----------+-- 視圖SQL> create table test_view( a int,b int);
Succeed.
SQL> insert into test_view values(1,1);
SQL> insert into test_view values(1,1);
SQL> insert into test_view values(2,2);
SQL> create view v1_simple as select * from test_view where a=1;
Succeed.
SQL> create view v2_complex as select a,count(*) cnt from test_view group by a;
Succeed.
SQL> select * from v1_simple;
A B
------------ ------------
1 1
1 1
SQL> select * from v2_complex;
A CNT
------------ ---------------------
1 2
2 1
SQL> update v1_simple set b=3;
[1:8]YAS-02012 table or view does not exist
// 視圖更新還不支持
-- 序列
SQL> create sequence test_seq1 increment by 2 start with 100;
Succeed.
SQL> select test_seq1.currval,test_seq1.nextval from dual;
TEST_SEQ1.CURRVAL TEST_SEQ1.NEXTVAL
----------------- -----------------
100 100
SQL> /
TEST_SEQ1.CURRVAL TEST_SEQ1.NEXTVAL
----------------- -----------------
102 102
-- 同義詞
SQL> create or replace synonym test_syn for user_tables;
Succeed.
-- 觸發(fā)器
SQL> create table test_trigger(a int,b int);
Succeed.
SQL> create or replace trigger test_trigger1
before insert on test_trigger
for each row
begin
:new.b:=:new.a+100;
end;
/
SQL> insert into test_trigger(a) values(1);
SQL> select * from test_trigger;
A B
------------ ------------
1 101
-- 存儲過程
SQL> create or replace procedure test_procas
begin
dbms_output.put_line('hello word');
end;
/
Succeed.
SQL> set serveroutput on
SQL> call test_proc();hello word
-- DB Link
SQL> create user hfuser2 identified by 123456;
SQL> grant dba to hfuser2;
SQL> conn hfuser2/123456
SQL> create database link test_lnk connect to hfuser1 identified by 123456 using '172.16.31.8:1688';
Succeed.
SQL> select * from test_partition@test_lnk;
PRODUCT_ID SALES_COUNT
---------- -----------
1 600
2 1000
3 2300
4 6000
SQL> insert into test_partition@test_lnk values(5,700);
1 row affected.
SQL> select * from test_partition@test_lnk;
PRODUCT_ID SALES_COUNT
---------- -----------
1 600
5 700
2 1000
3 2300
4 6000
-- 【測試表】
4、內(nèi)置函數(shù)
函數(shù)部分,Oracle支持?jǐn)?shù)百種函數(shù),可以說極大豐富了數(shù)據(jù)庫處理數(shù)據(jù)的能力。YashanDB 兼容支持了大部分函數(shù),這樣可以大幅降低代碼改造的工作量。
-- 數(shù)學(xué)函數(shù)
SQL> SELECT ABS(-5) AS abs_test FROM DUAL;
ABS_TEST
---------------------
5
SQL> select cos(0) from dual;
COS(0)
-----------
1.0E+000
SQL> select acos(-1) from dual;
ACOS(-1)
-----------
3.142E+000
SQL> SELECT MOD(15, 4) AS mod_test FROM DUAL;
MOD_TEST
---------------------
3
-- 日期函數(shù)
SQL> SELECT SYSDATE AS sysdate_test FROM DUAL;
SYSDATE_TEST
--------------------------------
2023-10-16
SQL> SELECT DATE('2022-08-01') AS date_test FROM DUAL;
DATE_TEST
--------------------------------
2022-08-01
SQL> SELECT EXTRACT(MONTH FROM SYSDATE) AS extract_test FROM DUAL;
EXTRACT_TEST
------------
10
SQL> SELECT TRUNC(SYSDATE, 'MONTH') AS trunc_test FROM DUAL;
TRUNC_TEST
--------------------------------
2023-10-01
-- 字符函數(shù)
SQL> SELECT LENGTH('Hello, World!') AS length_test FROM DUAL;
LENGTH_TEST
---------------------
13
SQL> SELECT SUBSTR('Hello, World!', -4) AS substr_test FROM DUAL;
SUBSTR_TEST
-----------
rld!
SQL> SELECT INSTR('Hello, World!', 'o') AS instr_test FROM DUAL;
INSTR_TEST
---------------------
5
SQL> SELECT UPPER('Hello, World!') AS upper_test FROM DUAL;
UPPER_TEST
-----------------
HELLO, WORLD!
SQL> SELECT TRIM(' Hello, World! ') AS trim_test FROM DUAL;
TRIM_TEST
-----------------
Hello, World!
-- 其他函數(shù)
SQL> SELECT NVL('true', 'false') AS nvl_test FROM DUAL;
NVL_TEST
--------
true
SQL> SELECT USERENV('CLIENT_INFO') res FROM DUAL;
RES
----------------------------------------------------------------
user: HFUSER1
program path: /data1/yashan/yasdb_home/yashandb/23.1.0.309/bin/yasql
SQL> SELECT DECODE('',1,1,2) res1,
DECODE(1,1,1,'1',2,3) res2,
DECODE(1,'',1,'1',2,3) res3,
DECODE('','',1,3) res4
FROM DUAL;
RES1 RES2 RES3 RES4
------------ ------------ ------------ ------------
2 1 2 1
SQL> SELECT SYS_CONTEXT('USERENV', 'IP_ADDRESS') res FROM DUAL;
RES
----------------------------------------------------------------
172.16.31.8
5、SQL語法
SQL 語法部分,是 Oracle 頗為復(fù)雜的部分,也是很多后續(xù)改造遷移工作的重點(diǎn)難點(diǎn)。這部分涉及的情況比較多,僅做了部分簡單的測試。
SQL> select * from test1;
A B
------------ ------------
1 1
2 2
3 3
SQL> select * from test2;
A B
------------ ------------
1 1
2 2
4 4
-- 表連接(ANSI寫法)
SQL> select * from test1 full outer join test2 on test1.a=test2.a;
A B A B
------------ ------------ ------------ ------------
1 1 1 1
2 2 2 2
4 4
3 3
-- 表連接(Oracle方言)
SQL> select * from test1,test2 where test1.a(+)=test2.a;
A B A B
------------ ------------ ------------ ------------
1 1 1 1
2 2 2 2
4 4
-- 子查詢
SQL> select * from test1 where test1.a in (select test2.a from test2);
A B
------------ ------------
1 1
2 2
-- 窗口函數(shù)
SQL> select test1.*, rank() over(order by test1.a desc) as ranks
from test1;
A B RANKS
------------ ------------ ---------------------
3 3 1
2 2 2
1 1 3
-- 聚合函數(shù)
SQL> select a from test1 group by a having count(*)<2;
A
------------
1
2
3
-- 集合查詢
SQL> select * from test1 minus select * from test2;
A B
------------ ------------
3 3
-- 使用偽列
SQL> select * from test1 where rownum<2;
A B
------------ ------------
1 1
SQL> select rowid,* from test1;
ROWID A B
---------------------- ------------ ------------
2281:4:0:212:0 1 1
2281:4:0:212:1 2 2
2281:4:0:212:2 3 3
6、過程化語言
過程化語言,是指在數(shù)據(jù)庫端處理數(shù)據(jù)的一種語言,也是很多國產(chǎn)數(shù)據(jù)庫的痛點(diǎn)。從用戶角度來看,過程化語言確實(shí)大大豐富了數(shù)據(jù)處理能力,是一種不可或缺的能力。YashanDB 這方面做了很大程度的兼容,常用的過程化語言用法都支持。
-- 包與存儲過程
SQL> create package my_package as
procedure my_procedure (
p_input_param in integer,
p_output_param out integer
);
end my_package;
/
Succeed.
SQL> create package body my_package as
procedure my_procedure (
p_input_param in integer,
p_output_param out integer
) as
begin
p_output_param := p_input_param * 2;
end my_procedure;
end my_package;
/
Succeed.
SQL> set serveroutput on
SQL> declare
v_output_param integer;
begin
my_package.my_procedure(10, v_output_param);
dbms_output.put_line('output parameter value: ' || v_output_param);
end;
/
output parameter value: 20
PL/SQL Succeed.
-- Java UDF
SQL> create or replace library ya_lib is '/home/yashan/example/UDFexample.class';
Succeed.
$ cat UDFexample.java
package example;
public class UDFexample {
public static String execJdbcexample(int ctrls) {
switch (ctrls) {
case 1:return "Hello";
case 2:return "World";
default:return "!";
}
}
public static void main(String[] args) {
String a = execJdbcexample(1);
}
}
$ javac UDFexample.java
$ ls -lrt
-rw-rw-r--. 1 yashan yashan 322 Oct 31 11:44 UDFexample.java
-rw-rw-r--. 1 yashan yashan 477 Oct 31 11:45 UDFexample.class
SQL> CREATE OR REPLACE FUNCTION udf_func_java(argu INT) RETURN VARCHAR IS
LANGUAGE java
NAME 'example.UDFexample.execJdbcexample(int) return string'
LIBRARY ya_lib;
/
Succeed.
SQL> SELECT udf_func_java(1) FROM dual;
UDF_FUNC_JAVA(1)
----------------------------------------------------------------
Hello
SQL> SELECT udf_func_java(2) FROM dual;
UDF_FUNC_JAVA(2)
----------------------------------------------------------------
World
7、數(shù)據(jù)字典/系統(tǒng)視圖
數(shù)據(jù)字典,是元數(shù)據(jù)的存儲。系統(tǒng)視圖,則是反映系統(tǒng)運(yùn)行狀態(tài)的一個窗口。YashanDB 提供了動態(tài)視圖和系統(tǒng)視圖支持。其中,動態(tài)視圖為系統(tǒng)提供的以V$、GV$或DV$開頭的視圖,用于實(shí)時展現(xiàn)正處于數(shù)據(jù)庫運(yùn)行中的各項數(shù)據(jù),尤其與性能相關(guān)數(shù)據(jù),用戶通過查詢這些視圖,對系統(tǒng)進(jìn)行管理和優(yōu)化。
- V$視圖:本地動態(tài)視圖,查詢當(dāng)前所在實(shí)例節(jié)點(diǎn)的數(shù)據(jù),在單機(jī)、分布式、共享集群部署中的表現(xiàn)一致。
- GV$視圖:全局動態(tài)視圖,在共享集群部署中,GV$視圖查詢的是所有實(shí)例數(shù)據(jù)進(jìn)行匯聚的結(jié)果,在單機(jī)/分布式部署中,GV$視圖等同于V$視圖,查詢的是本地數(shù)據(jù)。
- DV$視圖:分布式動態(tài)視圖,DV$視圖只在分布式部署中存在,查詢的是所有節(jié)點(diǎn)數(shù)據(jù)進(jìn)行匯聚的結(jié)果。
-- 動態(tài)視圖
SQL> select database_name,log_mode,open_mode,status,current_scn from v$database;
DATABASE_NAME LOG_MODE OPEN_MODE STATUS CURRENT_SCN
------------------ ----------------- ----------------- ----------- ---------------------
yashandb ARCHIVELOG READ_WRITE NORMAL 489941942425038848
SQL> select startup_time,host_name,data_home,instance_name from v$instance;
STARTUP_TIME HOST_NAME DATA_HOME INSTANCE_NAME
---------------------------- ------------- ----------------------------------- -------------------
2023-10-12 17:31:41.069135 host-23-8 /data1/yashan/yasdb_data/db-1-1 yasdb
SQL> select name, thread_id,status from v$process;
NAME THREAD_ID STATUS
--------------------------------- --------------------- ---------------------------------
TIMER 96616 Working
BUFFER_POOL 96617 Working
PRELOADER 96618 Working
PRELOADER 96619 Working
SMON 96620 Working
CKPT 96621 Working
DBWR 96622 Working
DBWR 96623 Working
SCHD_TIMER 96624 Working
TCP_LSNR 96625 Working
LISTENER_LOG 96627 Working
TCP_LSNR 96628 Working
TCP_LSNR 96629 Working
MMON 96630 Working
JOB_QUEUE 96631 Working
RD_ARCH 96636 Working
ARCH_DATA 96637 Working
HEALTH_MONITOR 96639 Working
PARAL_WORKER_0 96641 Working
PARAL_WORKER_1 96642 Working
LOGW 96643 Working
XFMR 96644 Working
-- DBA/ALL/USER視圖
SQL> select username,account_status,profile from dba_users;
USERNAME ACCOUNT_STATUS PROFILE
--------- ------------------- -----------
SYS OPEN DEFAULT
HFUSER2 OPEN DEFAULT
HFUSER1 OPEN DEFAULT
MDSYS LOCKED DEFAULT
SQL> select owner,object_type,count(*) from dba_objects group by owner,object_type order by 1,3 desc;
OWNER OBJECT_TYPE COUNT(*)
----------- --------------------- ---------
HFUSER1 TABLE 16
HFUSER1 INDEX 6
HFUSER1 TABLE PARTITION 4
HFUSER1 VIEW 2
HFUSER1 LOB 2
HFUSER1 SYNONYM 1
HFUSER1 TRIGGER 1
HFUSER1 SEQUENCE 1
HFUSER1 PROCEDURE 1
HFUSER2 UNDEFINED 1
8、SQL/PLSQL引擎
SQL 引擎部分,是 Oracle 內(nèi)核最為強(qiáng)大的組件,提供如查詢改寫、預(yù)編譯、CBO、執(zhí)行計劃(展示、緩存、綁定、管理)、自適應(yīng)游標(biāo)、提示等非常豐富的能力,可對 SQL 語句及執(zhí)行做到全方位的管理。YashanDB的優(yōu)化器采用CBO(Cost Based Optimizer)優(yōu)化模式。優(yōu)化器的目標(biāo)是為SQL語句生成最有效的執(zhí)行計劃傳遞給執(zhí)行器,執(zhí)行計劃包含數(shù)據(jù)訪問路徑、表連接順序等執(zhí)行算子信息。YashanDB的CBO優(yōu)化器基于統(tǒng)計信息,計算數(shù)據(jù)訪問和處理所需要的代價,選擇代價最低的方案生成執(zhí)行計劃。其統(tǒng)計信息主要包括表、列、索引的統(tǒng)計信息,例如表的行數(shù)、列的平均長度、索引包含的列數(shù)等。統(tǒng)計信息有動態(tài)收集、實(shí)時收集、在線收集、定時任務(wù)及手動觸發(fā)等多種收集方式,同時,可通過并行統(tǒng)計、抽樣統(tǒng)計等技術(shù)加快統(tǒng)計效率,為優(yōu)化器提供及時更新的信息。在執(zhí)行算子上,支持了掃描、表連接、查詢、排序、輔助、PX并行執(zhí)行等多種算子。同時支持利用Hint,對優(yōu)化器對算子的選擇和執(zhí)行方式提出干預(yù),例如指定表掃描的方式、指定執(zhí)行順序、指定并行度等,優(yōu)化器將根據(jù)這些提示,結(jié)合統(tǒng)計信息,生成最優(yōu)的執(zhí)行計劃。Oracle特有的PL/SQL能力,能夠靈活高效地訪問數(shù)據(jù)庫對象,其語法基于SQL語言擴(kuò)展,可編程性強(qiáng),支持用戶將業(yè)務(wù)邏輯下沉到數(shù)據(jù)層,更接近數(shù)據(jù)更高效,并可通過多級封裝實(shí)現(xiàn)安全、隔離、簡潔的接口供多應(yīng)用系統(tǒng)調(diào)用。YashanDB也支持了包括存儲過程、匿名塊、函數(shù)、JOB、觸發(fā)器和高級包功能。這部分未做詳細(xì)測試。
-- 統(tǒng)計信息
SQL> exec dbms_stats.gather_schema_stats('hfuser1');
PL/SQL Succeed.
SQL> select table_name,num_rows,blocks,last_analyzed,partitioned,temporary from user_tables;
TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED PARTITIONED TEMPORARY
---------------------- ----------- ---------- ----------------- ----------- ---------
TEST_TEMP_SESS N Y
TEST_TEMP_TRAN N Y
T_PROC 0 1 2023-10-18 N N
TEST2 3 1 2023-10-18 N N
TEST1 3 1 2023-10-18 N N
TEST_TRIGGER 1 1 2023-10-18 N N
TEST_VIEW 3 1 2023-10-18 N N
TEST_FBI 0 0 2023-10-18 N N
TEST_BITMAP_INDEX 0 0 2023-10-18 N N
TEST_INDEX 3 1 2023-10-18 N N
TEST_COMPRESS 0 0 2023-10-18 N N
TEST_PARTITION 4 4 2023-10-18 Y N
TEST_HEAP 0 0 2023-10-18 N N
TEST_BIGFILE 1 1 2023-10-18 N N
TEST_DATE 1 1 2023-10-18 N N
TEST_NUM 1 1 2023-10-18 N N
TEST_CHAR 1 1 2023-10-18 N N
TEST_TBS 1 1 2023-10-18 N N SQL> select index_name,table_name,blevel,distinct_keys,status from user_indexes;INDEX_NAME TABLE_NAME BLEVEL DISTINCT_KEYS STATUS
--------------------- ---------------- ------------ ----------------- ---------
SYS_IL2248C00001$$ TEST_BIGFILE VALID
SYS_IL2248C00000$$ TEST_BIGFILE VALID
IDX_FBI TEST_FBI 0 0 VALID
IDX_TEST_C TEST_INDEX 0 0 VALID
IDX_TEST_AB TEST_INDEX 0 0 VALID
IDX_TEST_A TEST_INDEX 0 0 VALID
-- 優(yōu)化器
SQL> show parameter optimizer_mode;
NAME VALUE
---------------- ----------------
0 rows fetched.
//YashanDB 目前尚不支持修改優(yōu)化器行為。
9、系統(tǒng)調(diào)優(yōu)
系統(tǒng)調(diào)優(yōu)是 DBA 常規(guī)需要完成的工作,包括實(shí)例調(diào)優(yōu)、語句調(diào)優(yōu)等。實(shí)例調(diào)優(yōu)通常通過診斷報告進(jìn)行分析后調(diào)整,語句調(diào)優(yōu)通常包括查看執(zhí)行計劃、語句調(diào)優(yōu)、結(jié)構(gòu)優(yōu)化等。對于不易調(diào)整的計劃,也可以采用如Hint、Outline的方式進(jìn)行改寫。下圖是 YashanDB 生成的 AWR 報告,形式上與 Oracle AWR 十分類似。通過這一報告可以快速了解快照間系統(tǒng)整體運(yùn)行狀況,當(dāng)然目前 YashanDB 支持的指標(biāo)還沒有那么多,相信未來會不斷完善。
下面是針對語句調(diào)優(yōu),可完成的一些工作。
-- 查看執(zhí)行計劃(EXPLAIN)
SQL> explain plan for select * from test_partition where product_id=2;
PLAN_DESCRIPTION
----------------------------------------------------------------
SQL hash value: 3275967159
Optimizer: ADOPT_C
+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+
| Id | Operation type | Name | Owner | Rows | Cost(%CPU) | Partition info |
+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+
| 0 | SELECT STATEMENT | | | | | |
| 1 | PART SCAN ALL | | | 1| 34( 0)| [0,3] |
|* 2 | TABLE ACCESS FULL | TEST_PARTITION | HFUSER1 | 1| 34( 0)| |
+----+--------------------------------+----------------------+------------+----------+-------------+--------------------------------+
Operation Information (identified by operation id):
---------------------------------------------------
2 - Predicate : filter("TEST_PARTITION"."PRODUCT_ID" = 2)
SQL> set autotrace on
SQL> select * from test_partition where product_id=2;
Execution Plan
----------------------------------------------------------------
SQL hash value: 3275967159
Optimizer: ADOPT_C
+----+--------------------------------+----------------------+------------+----------+----------+-------------+----------+----------+----------+----------+--------------------------------+
| Id | Operation type | Name | Owner | E - Rows | A - Rows | Cost(%CPU) | A - Time | Loops | Memory | Disk | Partition info |
+----+--------------------------------+----------------------+------------+----------+----------+-------------+----------+----------+----------+----------+--------------------------------+
| 0 | SELECT STATEMENT | | | | | | | | | | |
| 1 | PART SCAN ALL | | | 1| | 34( 0)| | | | | [0,3] |
|* 2 | TABLE ACCESS FULL | TEST_PARTITION | HFUSER1 | 1| | 34( 0)| | | | | |
+----+--------------------------------+----------------------+------------+----------+----------+-------------+----------+----------+----------+----------+--------------------------------+
Operation Information (identified by operation id):
---------------------------------------------------
2 - Predicate : filter("TEST_PARTITION"."PRODUCT_ID" = 2)
-- 查看執(zhí)行計劃(AutoTrace)
SQL> set autotrace on
SQL> select count(*) from test1;
COUNT(*)
---------------------
3
Execution Plan
----------------------------------------------------------------
SQL hash value: 860157296
Optimizer: ADOPT_C
+----+----------------------+--------+---------+----------+----------+-------------+----------+----------+----------+----------+----------------+
| Id | Operation type | Name | Owner | E - Rows | A - Rows | Cost(%CPU) | A - Time | Loops | Memory | Disk | Partition info |
+----+----------------------+--------+---------+----------+----------+-------------+----------+----------+----------+----------+----------------+
| 0 | SELECT STATEMENT | | | | | | | | | | |
| 1 | AGGREGATE | | | 1| | 13( 0)| | | | | |
| 2 | TABLE ACCESS FULL | TEST1 | HFUSER1 | 3| | 13( 0)| | | | | |
+----+----------------------+--------+---------+----------+----------+-------------+----------+----------+----------+----------+----------------+
Statistics
----------------------------------------------------------------------------------------------------
11 rows fetched.
-- Hint
SQL> select * from test_index where a=2;
+----+--------------------------------+----------------------+------------+
| Id | Operation type | Name | Owner |
+----+--------------------------------+----------------------+------------+
| 0 | SELECT STATEMENT | | |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_INDEX | HFUSER1 |
|* 2 | INDEX RANGE SCAN | IDX_TEST_A | HFUSER1 |
+----+--------------------------------+----------------------+------------+
SQL> select /*+ full(test_index) */ * from test_index where a=2;
+----+--------------------------------+----------------------+------------+
| Id | Operation type | Name | Owner |
+----+--------------------------------+----------------------+------------+
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS FULL | TEST_INDEX | HFUSER1 |
+----+--------------------------------+----------------------+------------+
10、安全特性
YashanDB實(shí)現(xiàn)了用戶、角色、權(quán)限管理,支持包括三權(quán)分離等能力。特別是針對DBA關(guān)注的安全需求,如審計、防火墻、數(shù)據(jù)加密等能力也有實(shí)現(xiàn)。雖然相較于Oracle還有著不小的差距,如數(shù)據(jù)加密僅支持表空間,但初步安全能力都已具備,可滿足日常安全需求。以用戶及角色為例,簡單測試了一下。
SQL> CREATE USER hfuser1 IDENTIFIED BY 123456;
Succeed.
SQL> GRANT CONNECT TO hfuser1;
Succeed.
SQL> GRANT RESOURCE TO hfuser1;
Succeed.
SQL> GRANT CONNECT,RESOURCE TO hfuser1;
YAS-02216 invalid privilege or role specified
//這點(diǎn)與Oracle有差異,無法單次授予多個角色權(quán)限
SQL> CONN hfuser1/123456
Connected to:
YashanDB Server Enterprise Edition Release 23.1.0.309 x86_64 - X86 64bit Linux
SQL> select username,user_id,account_status,default_tablespace from user_users;
USERNAME USER_ID ACCOUNT_STATUS DEFAULT_TABLESPACE
-------------- ------------ ------------------- -------------------------
HFUSER1 3 OPEN USERS
11、實(shí)例管理
實(shí)例管理,是DBA日常對數(shù)據(jù)庫實(shí)例的運(yùn)維類操作,包括對實(shí)例狀態(tài)、參數(shù)、日志、控制文件等的管理。
-- 實(shí)例啟停
SQL> select status from v$instance;
STATUS
-------------
OPEN
SQL> shutdown;
Succeed.
[mys@host-23-8 ~]$ nohup yasdb open &
[1] 110817
[mys@host-23-8 ~]$ yasql sys/xxx@<ip>:<port>
YashanDB SQL Enterprise Edition Release 23.1.0.309 x86_64
Connected to:
YashanDB Server Enterprise Edition Release 23.1.0.309 x86_64 - X86 64bit Linux
SQL> select status from v$instance;
STATUS
-------------
OPEN
--在線與歸檔日志
SQL> SELECT database_name,log_mode,open_mode FROM v$DATABASE;
DATABASE_NAME LOG_MODE OPEN_MODE
------------------- ----------------- -----------------
yashandb ARCHIVELOG READ_WRITE
SQL> SELECT * FROM v$archived_log;
NAME SEQUENCE# THREAD# RESETLOGS_ID FIRST_CHANGE#
---------------------------- ------------ ------- ------------ ---------------------
/data1/yashan/arch_0_1.ARC 1 1 0 0
/data1/yashan/arch_0_2.ARC 2 1 0 488514779900493824
/data1/yashan/arch_0_3.ARC 3 1 0 488993590743019520
/data1/yashan/arch_0_4.ARC 4 1 0 489347488660754432
/data1/yashan/arch_0_5.ARC 5 1 0 490055274011684864
/data1/yashan/arch_0_6.ARC 6 1 0 490314622336798720
/data1/yashan/arch_0_7.ARC 7 1 0 490409186952015872
/data1/yashan/arch_0_8.ARC 8 1 0 490528754307604480
SQL> select * from v$logfile;
THREAD# ID NAME BLOCK_SIZE BLOCK_COUNT USED_BLOCKS SEQUENCE# STATUS
------- ----- ----------------- ------------ ------------ ------------ ------------ ---------
1 0 /data1/redo1 4096 32768 192 9 CURRENT
1 1 /data1/redo2 4096 32768 32768 6 INACTIVE
1 2 /data1/redo3 4096 32768 2749 7 INACTIVE
1 3 /data1/redo4 4096 32768 174 8 INACTIVE
-- 參數(shù)
SQL> show parameter;
NAME VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
MAX_SESSIONS 1024
MAX_WORKERS 0
MAX_PARALLEL_WORKERS 32
MAX_REACTOR_CHANNELS 0
WORK_AREA_STACK_SIZE 1024K
...
ENABLE_ARCH_DATA_IGNORE_BACKUP FALSE
176 rows fetched.
//YashanDB 包含了176個參數(shù)
SQL> alter system set MAX_SESSIONS=1000 scope=spfile;
Succeed.
--控制文件
SQL> select * from v$controlfile;
ID NAME BLOCK_SIZE FILE_SIZE_BLKS BYTES
----- ---------------------------------------------------------------- ------------ -------------- ---------------------
0 /data1/yashan/yasdb_data/db-1-1/dbfiles/ctrl1 8192 3097 25370624
1 /data1/yashan/yasdb_data/db-1-1/dbfiles/ctrl2 8192 3097 25370624
2 /data1/yashan/yasdb_data/db-1-1/dbfiles/ctrl3 8192 3097 25370624
12、存儲管理
YashanDB 使用與Oracle類似的層次存儲,包含Tablespace-Datafile-Segment-Extent-Block多個級別。
-- 表空間管理
[mys@host-23-8 ~]$ yasql sys/xxx@<ip>:<port>
YashanDB SQL Enterprise Edition Release 23.1.0.309 x86_64
Connected to:
YashanDB Server Enterprise Edition Release 23.1.0.309 x86_64 - X86 64bit Linux
SQL> select tablespace_name from dba_tablespaces;
TABLESPACE_NAME
----------------------------------------------------------------
SYSTEM
SYSAUX
TEMP
SWAP
USERS
UNDO
SQL> create tablespace tbs_test datafile '.../dbfiles/tbs_test.dbf' size 10m autoextend on;
Succeed.
mys@host-23-8 ~]$ yasql hfuser1/<ip>:<port>
SQL> create table test_tbs ( a int) tablespace tbs_test;
Succeed.
SQL> insert into test_tbs values(1);
1 row affected.
13、備份恢復(fù)
備份恢復(fù)能力是數(shù)據(jù)庫的基礎(chǔ),也是保護(hù)數(shù)據(jù)的最重要手段。YashanDB提供了多種備份及恢復(fù)方式,有基于SQL(BACKUP、RESTORE語句)、基于工具YasRMAN(類似RMAN)或者通過圖形化終端發(fā)起備份。備份支持全量及多級增量備份,同時可支持備份壓縮與加密。恢復(fù)方面,支持全量及基于時點(diǎn)的還原,后者僅支持單機(jī)版本。下面針對備份做個簡單測試
SQL> BACKUP DATABASE FULL FORMAT '/tmp/backup_full_20231017';
Succeed.
[mys@host-23-8 ~]$ ls -al /tmp/backup_full_20231017/*
-rw-r----- 1 mys mys 124387328 Oct 17 20:07 /tmp/backup_full_20231017/arch0_0_5_0.bak
-rw-r----- 1 mys mys 5632 Oct 17 20:07 /tmp/backup_full_20231017/backup_filelist
-rw-r----- 1 mys mys 16777216 Oct 17 20:07 /tmp/backup_full_20231017/backup_profile
-rw-r----- 1 mys mys 25370624 Oct 17 20:07 /tmp/backup_full_20231017/ctrl_0_0_0.bak
-rw-r----- 1 mys mys 67108864 Oct 17 20:07 /tmp/backup_full_20231017/data_0_0_0.bak
-rw-r----- 1 mys mys 67108864 Oct 17 20:07 /tmp/backup_full_20231017/data_1_0_0.bak
-rw-r----- 1 mys mys 8192 Oct 17 20:07 /tmp/backup_full_20231017/data_2_0_0.bak
-rw-r----- 1 mys mys 8192 Oct 17 20:07 /tmp/backup_full_20231017/data_3_0_0.bak
-rw-r----- 1 mys mys 67108864 Oct 17 20:07 /tmp/backup_full_20231017/data_4_0_0.bak
-rw-r----- 1 mys mys 134217728 Oct 17 20:07 /tmp/backup_full_20231017/data_5_0_0.bak
-rw-r----- 1 mys mys 134217728 Oct 17 20:07 /tmp/backup_full_20231017/data_5_0_1.bak
-rw-r----- 1 mys mys 67108864 Oct 17 20:07 /tmp/backup_full_20231017/data_5_0_2.bak
14、高可用
在高可用方面,YashanDB支持多種高可用架構(gòu),包括主備模式(類似Oracle DataGuard)、共享模式(類似Oracle RAC)、分布式模式。其中主備模式支持一主多備和級聯(lián)備模式(不限層級),當(dāng)主機(jī)發(fā)生故障的時候,業(yè)務(wù)可以轉(zhuǎn)移到備機(jī)上繼續(xù)執(zhí)行,降低故障對業(yè)務(wù)的影響,提高數(shù)據(jù)庫的可用性。共享模式則是在共享存儲與共享內(nèi)存技術(shù)實(shí)現(xiàn)一個單庫多實(shí)例的多活數(shù)據(jù)庫系統(tǒng)。支持在線故障自動切換和故障自動恢復(fù),集群任一實(shí)例異常都不影響正常實(shí)例對外提供的服務(wù)。分布式則是采用Shared-Nothing 架構(gòu),由管理節(jié)點(diǎn)組、協(xié)調(diào)節(jié)點(diǎn)組與數(shù)據(jù)節(jié)點(diǎn)組組成。這些節(jié)點(diǎn)部署在不同主機(jī)上,有不同的安裝目錄、數(shù)據(jù)目錄,并且通過一些網(wǎng)絡(luò)端口進(jìn)行內(nèi)部通訊或?qū)ν馓峁┓?wù)。此外,針對對象級的誤操作等,也提供了閃回功能。受限于測試環(huán)境,未做高可用測試。
15、生態(tài)接口與工具
YashanDB 可通過很多的數(shù)據(jù)訪問接口,如常見的JDBC、ODBC、C、Python、ADO.NET 等,幾乎面對不同訪問語言都有對應(yīng)的訪問接口可用。同時支持持久化框架-Mybatis、SQL開發(fā)工具(如DataGrip、DBeaver)、BI工具(如FineBI)及大數(shù)據(jù)分析工具(如Spark、Kafka等)。為了方便運(yùn)維,其也支持很多獨(dú)立小工具,很多如 Oracle 的工具集,如yasql(命令行管理工具)、imp/exp(導(dǎo)入導(dǎo)出工具)、yasboot(安裝部署與運(yùn)維工具)、yasrman(備份工具)、yasldr(文本加載工具)等。