前面写了两篇关于国产数据库的文章,没想到引起了很多网友的热议,其中大部分网友是表示认可、肯定;在此我表示感谢。当然其中也有个别网友朋友提出了质疑和疑问,甚至抵制,这类朋友大致的观点总结一下就是:
1、你们MogDB是基于openGauss数据库的二次开发增强,既然openGauss我用起来感觉不好用,自然MogDB也不好用。
2、openGauss是基于开源PostgreSQL9.2,还是停留在9这个版本,太老了。
3、直接干脆从PostgreSQL不香吗?
针对这几个疑问,我正式回复一下:
1、开源openGauss迭代速度比较快,同时确实存在不少Bug,另外在针对Oracle、MySQL、PostgreSQL方面的兼容性相对要差很多,目前各家DBV厂商都做了很多兼容性增强,包括一些Bug修复,因此稳定性是可以得到保障的。至于说好不好用,我想大家试试就知道了吧!
2、openGauss是基于PostgreSQL 9.2.4版本没错,但是已经被魔改的很厉害了,架构都完全不同了,而且实事求是的说,现在最新版PostgreSQL17 还有一些没解决的痛点,openGauss 1.0 都解决了,那么,您能说openGauss还停留在PostgreSQL9.2 时代么?
3、我其实在公众号留言也回复过了,如果用户运维能力跟得上,用开源PG也完全没有问题,毕竟确实有很多互联网公司都在用PG,比如去哪儿网、探探、中国平安、苏宁等等。但是如果用户是要进行数据库国产化改造,那么我想用PostgreSQL来替代Oracle或者DB2又或者是MySQL,应该就不太适合了吧。我想原因就不需要过多解释了。
我们再回到这个主题上来,为什么企业用户选择MogDB来做国产化改造,而不是用开源的openGauss或者PostgreSQL呢?我想大概有如下几个原因:
数据库稳定性、性能、安全等都是经得起考验的,毕竟现在每一个客户投产之前都要经过很长的测试;其次那就是MogDB对于其他数据库的兼容性真的做的还不错,至少是达到用户的预期了吧。
因此我打算用3~5篇系列文章来给大家分享分享MogDB在针对Oracle、MySQL、PostgreSQL等数据库方面的兼容性增强和改进。
实际上兼容性我们做的非常多了,一些场景的数据库类型,SQL写法就不说了,大家可以参考MogDB官网 www.mogdb.io。这里我简单提几个兼容性的大类。
MogDB 兼容Oracle的函数有哪些?
#字符函数
regexp_substr
regexp_instr
regexp_replace
regexp_count
replace
instrb
soundex
asciistr
unistr
convert
......
# 时间函数
months_between
trunc
round
numtoyminterval
systimestamp
sys_extract_utc
new_time
......
# 数字函数
nanvl
bitor
bitxor
bin_to_num
sinh
cosh
tanh
remainder
round_ties_to_even
.....
# 聚合函数
wm_concat
listagg
bit_and_agg
bit_or_agg
bit_xor_agg
any_value
kurtosis_pop
kurtosis_samp
skewness_pop
skewness_samp
......
# NULL值相关函数
nullif
nvl2
lnnvl
# 其他函数
sys_guid
ora_hash
dump
vsize
to_blob
empty_clob()
nls_charset_name
nls_charset_id
sys_context
userenv
instrb
nls_charset_id
nls_charset_name
nls_lower
nls_upper
ora_hash
remainder
replace
show
show_parameter
to_timestamp,
to_yminterval
tz_offset,
nullif
ratio_to_report
pivot
unpivot
实际上兼容的函数还有很多,我这里就写这么多。比如Oracle listagg、pivot、unpivot这些都是Oracle 11g 版本新增加的函数;甚至Oracle 21c新增的分析函数也支持了。
MogDB 兼容Oracle的DBMS包?
实际上很多toB客户都是Oracle的重度使用者,大量使用Oracle内置dbms package、存储过程等等,因此如果我们要进行快速替换、低成本替换,就必须要去兼容一些Oracle dbms内置包,比如如下就是我们已经兼容并支持的部分:
dbms_random
dbms_output
dbms_lock
dbms_lob
dbms_application_info
dbms_metadata
dbms_job
dbms_utility
dbms_stat
dbms_obfuscation_toolkit
dbms_utility
dbms_snapshot
utl_url
utl_raw
utl_match
utl_encode
utl_recomp
.....
MogDB 兼容Oracle DBA_XXX视图和数据字典有哪些?
DBA_CATALOG
DBA_CONS_COLUMNS
DBA_CONSTRAINTS
DBA_DATA_FILES
DBA_DEPENDENCIES
DBA_IND_COLUMNS
DBA_IND_EXPRESSIONS
DBA_IND_PARTITIONS
DBA_IND_STATISTICS
DBA_INDEX_USAGE
DBA_INDEXES
DBA_OBJECTS
DBA_PART_INDEXES
DBA_PART_TABLES
DBA_PROCEDURES
DBA_SEGMENTS
DBA_SEQUENCES
DBA_SOURCE
DBA_SYNONYMS
DBA_TAB_COL_STATISTICS
DBA_TAB_COLS
DBA_TAB_COLUMNS
DBA_TAB_COMMENTS
DBA_COL_COMMENTS
DBA_TAB_MODIFICATIONS
DBA_TAB_PARTITIONS
DBA_TAB_SUBPARTITIONS
DBA_PART_KEY_COLUMNS
DBA_SUBPART_KEY_COLUMNS
DBA_TAB_STATISTICS
DBA_TABLES
DBA_TABLESPACES
DBA_TRIGGER_COLS
DBA_TRIGGERS
DBA_TYPES
DBA_VIEWS
DBA_JOBS
DBA_JOBS_RUNNING
DBA_MVIEWS
DBA_MVIEW_LOGS
DBA_MVIEW_COMMENTS
DBA_USERS
DBA_DETAIL_PRIVILEGES
DBA_ALL_PRIVILEGES
DBA_ALL_PRIVILEGES_SQL
ALL_CATALOG
ALL_CONS_COLUMNS
ALL_CONSTRAINTS
ALL_DATA_FILES
ALL_DEPENDENCIES
ALL_IND_COLUMNS
ALL_IND_EXPRESSIONS
ALL_IND_PARTITIONS
ALL_IND_STATISTICS
ALL_INDEX_USAGE
ALL_INDEXES
ALL_OBJECTS
ALL_PART_INDEXES
ALL_PART_TABLES
ALL_PROCEDURES
ALL_SEGMENTS
ALL_SEQUENCES
ALL_SOURCE
ALL_SYNONYMS
ALL_TAB_COL_STATISTICS
ALL_TAB_COLS
ALL_TAB_COLUMNS
ALL_TAB_COMMENTS
ALL_COL_COMMENTS
ALL_TAB_MODIFICATIONS
ALL_TAB_PARTITIONS
ALL_TAB_SUBPARTITIONS
ALL_PART_KEY_COLUMNS
ALL_SUBPART_KEY_COLUMNS
ALL_TAB_STATISTICS
ALL_TABLES
ALL_TABLESPACES
ALL_TRIGGER_COLS
ALL_TRIGGERS
ALL_TYPES
ALL_VIEWS
ALL_JOBS
ALL_JOBS_RUNNING
ALL_MVIEWS
ALL_MVIEW_LOGS
ALL_MVIEW_COMMENTS
ALL_USERS
USER_CATALOG
USER_CONS_COLUMNS
USER_CONSTRAINTS
USER_DATA_FILES
USER_DEPENDENCIES
USER_IND_COLUMNS
USER_IND_EXPRESSIONS
USER_IND_PARTITIONS
USER_IND_STATISTICS
USER_INDEX_USAGE
USER_INDEXES
USER_OBJECTS
USER_PART_INDEXES
USER_PART_TABLES
USER_PROCEDURES
USER_SEGMENTS
USER_SEQUENCES
USER_SOURCE
USER_SYNONYMS
USER_TAB_COL_STATISTICS
USER_TAB_COLS
USER_TAB_COLUMNS
USER_TAB_COMMENTS
USER_COL_COMMENTS
USER_TAB_MODIFICATIONS
USER_TAB_PARTITIONS
USER_TAB_SUBPARTITIONS
USER_PART_KEY_COLUMNS
USER_SUBPART_KEY_COLUMNS
USER_TAB_STATISTICS
USER_TABLES
USER_TABLESPACES
USER_TRIGGER_COLS
USER_TRIGGERS
USER_TYPES
USER_VIEWS
USER_JOBS
USER_JOBS_RUNNING
USER_MVIEWS
USER_MVIEW_LOGS
USER_MVIEW_COMMENTS
USER_USERS
DBA_DIRECTORIES
ALL_DIRECTORIES
DBA_ROLES
DBA_ROLE_PRIVS
USER_ROLE_PRIVS
PRODUCT_COMPONENT_VERSION
PLAN_TABLE
DBA_SOURCE_ALL
NLS_DATABASE_PARAMETERS
NLS_INSTANCE_PARAMETERS
NLS_SESSION_PARAMETERS
DICTIONARY
DICT
COLS
IND
OBJ
TAB
DUAL
我想大家比较意外的是,我们居然支持了dict。其实之前做Oracle DBA的时候,就给同事分享过一个小技巧。很多小伙伴之前记不住Oracle这么多的视图名称,要去翻文档,实际上完全可以模糊查询dict 就行了。简直不要太方便。这里我给大家举个例子:
[omm@mogdb1 compat-tools-master]$ gsql -r -d test
gsql ((MogDB 5.0.5 build b77f1a82) compiled at 2023-12-08 03:11:47 commit 0 last mr 1804 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
test=# \dt
List of relations
Schema | Name | Type | Owner | Storage
--------+--------------------+-------+-------+------------------------------------------------------
public | mogdb_sql_bypass_1 | table | omm | {orientation=row,compression=no}
public | t1 | table | omm | {orientation=row,compression=no,storage_type=USTORE}
public | t2 | table | omm | {orientation=row,compression=no}
public | test_incresort_1 | table | omm | {orientation=row,compression=no}
public | tt | table | omm | {orientation=row,compression=no}
(5 rows)
test=# select table_name from dict where table_name like '%PRIVILEGE%';
table_name
-------------------------------
GS_AUDITING_PRIVILEGE
GS_DB_PRIVILEGES
COLUMN_PRIVILEGES
ROUTINE_PRIVILEGES
TABLE_PRIVILEGES
UDT_PRIVILEGES
USAGE_PRIVILEGES
DATA_TYPE_PRIVILEGES
GS_DB_PRIVILEGE
GS_AUDITING_POLICY_PRIVILEGES
(10 rows)
test=#
test=# select* from compat_tools.dba_segments where segment_name=upper('tt');
owner | segment_name | partition_name | segment_type | tablespace_name | bytes | blocks
--------+--------------+----------------+--------------+-----------------+-----------+--------
PUBLIC | TT | | TABLE | DEFAULT | 352329728 | 43009
(1 row)
test=# select file_name,tablespace_name,file_id,relative_fno,blocks,status,online_status from compat_tools.dba_data_files limit 10;
file_name | tablespace_name | file_id | relative_fno | blocks | status | online_status
-----------------------------------+-----------------+---------+--------------+--------+-----------+---------------
/opt/mogdb/data/base/273133/15354 | PG_DEFAULT | 1247 | 1247 | 27 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15468 | PG_DEFAULT | 1259 | 1259 | 52 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15448 | PG_DEFAULT | 1249 | 1249 | 185 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15452 | PG_DEFAULT | 1255 | 1255 | 196 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15461 | PG_DEFAULT | 7815 | 7815 | 0 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15356 | PG_DEFAULT | 2703 | 2703 | 6 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15357 | PG_DEFAULT | 2704 | 2704 | 10 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15450 | PG_DEFAULT | 2658 | 2658 | 55 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15451 | PG_DEFAULT | 2659 | 2659 | 36 | AVAILABLE | ONLINE
/opt/mogdb/data/base/273133/15454 | PG_DEFAULT | 2836 | 2836 | 8 | AVAILABLE | ONLINE
(10 rows)
test=#
这样大家用起来,是不是感觉就比较符合Oracle DBA的日常习惯了?
MogDB 兼容Oracle gv
的动态性能视图有哪些?
Oracle动态性能视图对我们分析故障、优化数据库性能无疑是利器,就我个人目前所了解的近10种数据库来讲,Oracle在这方面的强大,仍然是无出其右。
本质像Oracle学习的态度,我们也兼容了部分性能视图,希望能够让DBA们能快速去定位和发现问题。
GV$DATABASE
GV$INSTANCE
GV$DATAFILE
GV$LOCK
GV$PARAMETER
GV$PARAMETER_VALID_VALUES
GV$SESSION
GV$SESSTAT
GV$SPPARAMETER
GV$SYSSTAT
GV$TABLESPACE
GV$VERSION
GV$NLS_PARAMETERS
GV$NLS_VALID_VALUES
GV$SYSTEM_WAIT_CLASS
GV$SQL
GV$OPTION
GV$LICENSE
GV$STATNAME
GV$MYSTAT
V$DATABASE
V$INSTANCE
V$DATAFILE
V$LOCK
V$PARAMETER
V$PARAMETER_VALID_VALUES
V$SESSION
V$SESSTAT
V$SPPARAMETER
V$SYSSTAT
V$TABLESPACE
V$VERSION
V$NLS_PARAMETERS
V$NLS_VALID_VALUES
V$SYSTEM_WAIT_CLASS
V$SQL
V$OPTION
V$LICENSE
V$STATNAME
V$MYSTAT
当然,目前我们兼容还在不断增强,如果大家在使用过程中发现一些问题或者有新的需求想法,都可以告诉我们。实际上上述的一些视图中,我认为可能最常用的就是v
Lock,v$sql等几个视图了。
test=# select sid,serial#,username,status,machine,program,logon_time,blocking_session_status,event from compat_tools.v$session limit 10;
sid | serial# | username | status | machine | program | logon_time | blocking_session_status | event
-----------------+---------+----------+--------+---------+------------------------+-------------------------------+-------------------------+-------
139629065926400 | 0 | omm | active | | gsql | 2024-06-11 18:25:12.472399+08 | NOT IN WAIT | none
139633275959040 | 0 | omm | idle | | WLMArbiter | 2024-06-05 22:05:22.69227+08 | NOT IN WAIT | none
139633304270592 | 0 | omm | idle | | WorkloadMonitor | 2024-06-05 22:05:22.686512+08 | NOT IN WAIT | none
139633329436416 | 0 | omm | active | | workload | 2024-06-05 22:05:22.685468+08 | NOT IN WAIT | none
139633633523456 | 0 | omm | active | | PercentileJob | 2024-06-05 22:05:22.620672+08 | NOT IN WAIT | none
139633590531840 | 0 | omm | active | | Asp | 2024-06-05 22:05:22.61905+08 | NOT IN WAIT | none
139633729992448 | 0 | omm | idle | | TxnSnapCapturer | 2024-06-05 22:05:22.577808+08 | NOT IN WAIT | none
139633567397632 | 0 | omm | idle | | statement flush thread | 2024-06-05 22:05:22.617195+08 | NOT IN WAIT | none
139633656067840 | 0 | omm | idle | | WDRSnapshot | 2024-06-05 22:05:22.625884+08 | NOT IN WAIT | none
139633702205184 | 0 | omm | idle | | CfsShrinker | 2024-06-05 22:05:22.576739+08 | NOT IN WAIT | none
(10 rows)
test=#
test=# select sql_id,parsing_schema_name,cpu_time,db_time,executions,buffer_gets,disk_reads,rows_processed from compat_tools.v$sql limit 10;
sql_id | parsing_schema_name | cpu_time | db_time | executions | buffer_gets | disk_reads | rows_processed
------------+---------------------+-----------+-----------+------------+-------------+------------+----------------
2550485021 | omm | 43771320 | 48290679 | 846 | 1726791 | 33 | 176671
3733824374 | omm | 2303 | 2339 | 24 | 24 | 0 | 0
1281210063 | omm | 7339 | 1007397 | 1 | 0 | 0 | 0
3078959359 | omm | 322706803 | 322999653 | 1 | 81185207 | 537114 | 0
547100316 | omm | 0 | 0 | 0 | 0 | 0 | 0
521895001 | omm | 18059 | 19092 | 2 | 0 | 0 | 0
2576472348 | omm | 2176 | 2564 | 3 | 162 | 1 | 3
1219338790 | omm | 921 | 1279 | 1 | 28 | 4 | 0
2118969015 | omm | 40492 | 41153 | 55 | 159 | 6 | 1320
332229841 | omm | 9649810 | 13303484 | 846 | 402132 | 1804 | 0
(10 rows)
MogDB 兼容Oracle的SQL语法有哪些?
MogDB对于Oracle 的兼容,我认为最为主要的就是这部分内容,实际上也是做的比较多的部分,内容太多,但是又不太好分类,这里我就简单罗列一下:
MogDB 支持 Oracle 的 insert all语法.
MogDB 支持 Oracle游标 CURRENT OF cursor语法
MogDB 支持 INSERT ON CONFLICT DO UPDATE/DO NOTHING语法及其功能
MogDB 支持 Oracle PL/SQL中的subtype 语法
MogDB 支持 对存储过程中扩展数组的extend语法的参数传入数组的count属性
MogDB 支持 聚合函数+KEEP子句
MogDB 支持 创建自定义type数组
MogDB 兼容Oracle ORDER BY +DISTINCT
MogDB 兼容Oracle ORDER BY +使用数字代替投影列
MogDB 兼容Oracle ORDER BY +使用常量字符串
MogDB 兼容Oracle ORDER BY + 多列、表达式、聚集函数
MogDB 兼容Oracle GROUP BY 中含空字符串
MogDB 兼容Oracle GROUP BY中使用整数常量
MogDB 兼容Oracle GROUP BY字符串和表达式
.....
实际上还有很多兼容性功能,就不再一一列举了,更多详细情况可以参考官方文档。
企业客户异构迁移实战分享
最后给大家分享前段时间部门同事所做的一个Oracle to MogDB异构迁移改造实战的案例吧。总的来讲我认为这个难度不大。
如果单纯的去看兼容度,老实说,从这个例子来看,应该99%了。说自家数据库兼容性很高,很多人一定会跳出来质疑,你这个系统是不是也太简单了点?因此我又找同事分享了一个例子,xxx金融行业的,这里我就打码了。
这个可能是今年见过最为复杂的系统了,Oracle存储过程和包居多,真的是Oracle超级重度使用用户。有人可能会说,你这里看上去兼容性大概也就80%不到呀。开始看这个数据我也有疑惑,问同事才反馈说之前迁移数据时漏掉了一个schema,因此很多依赖失效,导致不少失败了。最终版本报告没有拿到,但同事反馈存储过程和package的兼容度能达到 90%左右,最终客户需要测试的部分关键业务,全部通过实际测试。
其次我要说明一下的是,兼容性实际上跟系统复杂度有关,我们需要建立这个一个认知。
当然上面提到的一些迁移工具比如MTK、MDB等大家都可以去www.mogdb.io上面下载使用。
软件好不好用,兼容性究竟如何,我想让用户自己来评价更好,我们可能做的不是最好的,但 MogDB 仍然在不断努力和完善,欢迎大家多多测试并提供宝贵意见!