-
用户自定义锁也叫咨询锁(advisory lock),用户可以通过调用GaussDB(DWS) 提供的函数来自定义锁,自定义锁按照作用范围分为两类: 1) 事务级自定义锁 pg_advisory_xact_lock(key bigint) pg_advisory_xact_lock(key1 int, key2 int) pg_advisory_xact_lock_shared(key bigint) pg_advisory_xact_lock_shared(key1 int, key2 int) pg_try_advisory_xact_lock(key bigint) pg_try_advisory_xact_lock(key1 int, key2 int) pg_try_advisory_xact_lock_shared(key bigint) pg_try_advisory_xact_lock_shared(key1 int, key2 int) 2) session级自定义锁 pg_advisory_lock(key bigint) pg_advisory_lock(key1 int, key2 int) pg_advisory_lock_shared(key bigint) pg_advisory_lock_shared(key1 int, key2 int) pg_try_advisory_lock(key bigint) pg_try_advisory_lock(key1 int, key2 int) pg_try_advisory_lock_shared(key bigint) pg_try_advisory_lock_shared(key1 int, key2 int) 带shared后缀的相关函数会申请5级锁ShareLock,不带 shared后缀的会申请7级锁ExclusiveLock; 带try 标识的相关函数表示尝试申请锁,如果申请不到,直接返回,不需锁等待。
-
1) 事务锁 写事务会获取一个事务号,并且会以这个事务号申请一个事务锁,锁级别是7级锁ExclusiveLock。 事务锁用于控制记录的并发修改,比如,两个事务先后修改同一条记录,在前一个事务未结束之前,后一个事务会等待在前一个事务的事务锁上。 2) 记录锁 当出现并发更新冲突时,冲突的事务会申请记录锁,锁级别是 7 级锁ExclusiveLock。 记录锁主要是提高等待事务的优先级,在更新事务结束后,让持有记录锁的事务第一个被唤醒。 3) 扩展锁 文件扩展时,会申请扩展锁,扩展锁的锁级别是7级锁ExclusiveLock。 表、索引、fsm、vm等文件扩展时都会申请扩展锁。 4) 分区锁 分区锁是专门针对分区表的,分区锁的意义与表锁差不多,锁级别从 1-8 都有。
-
GaussDB(DWS)支持的表锁级别很多,原生PG支持从最低的1级到最高的8级,另外GaussDB(DWS)在8.2.1(及以上)版本中还增加了9级锁,各锁级别含义如下: 1级锁,AccessShareLock SELECT语句申请AccessShareLock,只与8级锁冲突,只会阻塞DDL等语句; 2级锁,RowShareLock SELECT FOR SHARE/UPDATE语句申请RowShareLock,与7/8级锁冲突; 3级锁,RowExclusiveLockINSERT/UPDATE/DELET语句申请RowExclusiveLock,与 6-8级锁冲突; 4级锁,ShareUpdateExclusiveLockVACUUM/ANALYZE语句申请ShareUpdateExclusiveLock,与 5-8级锁冲突; 5级锁,ShareLock CREATE INDEX语句申请ShareLock,与4/6/7/8级锁冲突,与5级锁不冲突,同一个表的多个CREATE INDEX可以同时执行不阻塞; 6级锁,ShareRowExclusiveLock 在 GaussDB(DWS) 中,ShareRowExclusiveLock 目前只在 ALTER SEQUENCE 中用到,阻塞表的增删改以及更高级别操作,该锁与3-8级锁冲突; 7级锁,ExclusiveLock VACUUM FULL,MERGE PARTITION等语句申请ExclusiveLock级锁,ExclusiveLock 只与SELECT兼容,与2-8级锁冲突; 除了表锁外,事务锁,扩展锁、记录锁都是使用的ExclusiveLock,后面会进行详细介绍; 8级锁,AccessExclusiveLock DDL 等语句会申请AccessExclusiveLock,包括 ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,VACUUM FULL等,8级锁与所有锁都冲突; 9级锁,UpdateExclusiveLock 仅autovacuum中使用,为了支持与autoanalyze操作并行。
-
LWLock 称为轻量级锁,只存在两种锁类型(LWLockMode):共享锁(Shared)和排它锁(Exclusive),当无法获取到锁时,会进行阻塞等待状态; 原生PG不提供死锁检测,DWS自己支持了死锁检测; 加锁解锁对外部用户透明,使用完一般应该立即主动释放,不等事务结束。 SpinLock 称为自旋锁,一般依赖于硬件支持,需要CPU支持TAS(test-and-set)指令集; 由于没有cpu上下文切换,性能高,主要用于临界区很短的场景,能快速释放锁,如几个指令内的内存状态修改和计算; 最多只有一个持有者,如未能获取到锁,则cpu busy做轮询检查直到拿到(超时后会PANIC退出); 没有等待队列和死锁检测。 RegularLock 称为常规锁,底层使用hash 表,持锁时间可以较长,有死锁检测和等待队列,事务结束时会自动释放; 可细分为表锁,事务锁,文件扩展锁,咨询锁等。
-
当前HStore并发更新同一行仍然是不支持的,其中同一行上并发update/delete操作会先等锁然后报错,同一行上的并发upsert操作会先等锁然后继续执行。由于等待开销也是会影响业务的入库性能,甚至可能产生死锁,所以需要在入库时保证不会并发更新到同一行或者同一个key。索引相关 索引会占用额外的空间,同时带来的点查性能提升有限,所以HStore表只建议在需要做 Upsert 或者有点查(这里指唯一性与接近唯一的点查) 的诉求下创建一个主键或者btree 索引。 MERGE相关 由于HStore表依赖后台autovacuum来将操作MERGE到主表,所以入库速度不能超过MERGE速度,否则会导致Delta表的膨胀,可以通过控制入库的并发来控制入库速度。同时由于Delta表本身的空间复用受oldestXmin的影响,如果有老事务存在可能会导致Delta空间复用不及时而产生膨胀。 UPSERT性能 HStore 表虽然相比普通列存,并发upsert入库性能得到了很大提升,但相比行存还是有差距,大概只有行存的1/3。所以在不追求压缩率以及批量查询性能、只追求单点查询性能的场景下,还是推荐行存表入库。
-
虽然列存老Delta表解决了小批量入库产生的小CU问题,但是没有解决同一个 CU 上的并发更新产生的锁冲突问题。而实时入库的场景下,需要将insert+upsert+update 操作实时并发入库,数据来源于上游的其他数据库或者应用,同时要求入库后的数据要能及时查询,且对于查询的效率要求很高。 目前的列存表由于锁冲突的原因无法支持并发upsert/update入库,导致这些有需要的局点只能使用行存表,但是行存表因为格式的天然劣势,在AP查询场景下一方面性能较慢,另一方面由于压缩差导致占用了大量的磁盘空间,对用户产生额外成本。 GaussDB(DWS)中的HStore表, 在使用列存储格式尽量降低磁盘占用的同时,支持高并发的更新操作入库以及高性能的查询效率。面向对于实时入库和实时查询有较强诉求的场景,同时拥有处理传统TP场景的事务能力。HStore 表的实现主要依靠一张新设计的Delta表以及内存并发控制机制,这里简单讲一下Delta表的实现以及简单的观察Delta表。 HStore 的 Delta 表主要用于存放入库产生的 Insert/Delete/Update 操作,小批量Insert 的数据会先进入Delta形成一条类型是I(Insert)的记录;删除会往Delta表插入一条类型是D(Delete)的记录;更新操作(Upsert与Update)会拆分成 Delete + Insert会插入一条类型 X(表示由更新产生的删除)的记录以及一条类型 I 的记录;(类型是U(Update)的记录由轻量化Update产生,不过当前轻量化更新默认关闭,所以不用管。) 可以看到,入库时的 Upsert/Update/Delete 都会转换成相应类型的记录插入的HStore 的 Delta 表中,再结合内存并发控制机制,就能保证同一个CU上更新于删除操作不会阻塞。同时,由于小批量的插入只会在Delta表上形成一条记录,相比与列存老Delta的直接存储数据,能减少IO占用,提高MERGE效率。
-
最基础的表类型,顾名思义,数据按行存储,在实际的物理块中,数据的所示的方式存储: 优势很明显,点查场景下,直接就能索引到行存某行元组的位置,点查性能好。数据库中的系统表就是行存表,对于用户的一些对点查性能要求高或者频繁更新的小表,都推荐用行存表。 AP场景下,常常需要对某列进行批量查询来做分析业务,这时候采用行存的话就会把所有列都读出来产生冗余IO, 同时AP场景下的表数据量往往很大,行存表压缩暂未商用,使用行存表也会导致占用空间过大。GaussDB(DWS)中的列存表就是针对这种场景实现的。列存表将每列的数据批量存储成一个 CU(Compress Unit), 能带来了很好的空间压缩与批量查询性能提升,对于一些涉及多表关联的分析类复杂查询、数据不经常更新的表,推荐使用列存表。对于列存表,如果业务是频繁的小批量插入,那么将产生大量的小CU(单个CU里只有几百条甚至几条数据), 每个列的CU都是有压缩代价的,小CU过多将严重影响列存表的查询性能。列存的 Delta 表就是针对这种场景实现的,让小批量插入的数据先存储到行存Delta 表,满6w后由后台autovacuum异步merge到主表CU。如图3所示,需要注意的是列存带Delta表只解决小批量入库产生的小CU问题,不解决同一个CU上的并发更新问题。
-
在对HStore进行点查时,会首先通过CU的min/max来进行粗过滤,我们希望通过min/max 过滤掉大部分数据,这就要求每个 CU 的数据尽可能的接近,而不能过于分散。目前GaussDB(DWS)已经实现了局部聚簇 (Partial Cluster Key, 简称PCK),在数据批插过程中就会进行排序。但还是会有如下几种情况导致CU的聚簇性无法达到要求: 1) 写入数据时,如果不是批量导入,则不会把数据写入排序器,而是直接插入Delta表,当 Delta 表 MERGE 的时候,也不会先走排序逻辑,而是直接将数据写入CU; 2) 当CU中的数据被删除的足够多时,就变成了小CU,聚簇性本身就会变差,就算进行了小 CU 合并,也依然不会走排序逻辑,而是将数据直接写入 Delta 表,merge流程与1)一致; 3) 实际上就是增加数据+删除数据。通过将HStore中多个CU的数据根据partial cluster key进行排序,生成新的CU再重新写入,新CU的数据会有更高的聚集性,即CU的min,max会在一个较小的区间内。异步排序时的并发处理与小CU合并类似。经过测试,排序后的CU聚簇性极大提升,粗过滤效率的提升与原本的数据特征有关。但是排序过程中会对所有参与排序的CU加CU级锁,此过程会阻塞部分DML操作,因此不建议在业务高峰期使用此功能。
-
小CU合并不是直接产生新的CU,而是将小CU数据重新插入到delta表后标记删除,然后依赖Delta表的自动MERGE攒够后再产生完整的新CU; 和正常的Delta merge不同在于,小CU被标记删除后新插入Delta表的记录会申请新的ctid,因为 ctid是变化的,所以该操作和DML操作存在冲突。当DML操作时遇到小CU合并,使用等待重试的方式处理;当compact操作时遇到DML冲突时直接跳过即可,原因就是删除和更新操作还是会将数据标记删除,因此可以直接放弃合并此条数据。小CU合并的事务可见性基于现有的csn机制,compaction inprogress或者回滚对外不可见,还是看到老记录,compaction提交老记录就不再可见看到新记录。 具体一个 CU 中剩余多少条数据才算是小 CU,应该是与业务强相关。因此,小CU阈值应该可以使用GUC参数调节。0CU的处理比小CU的处理简单的多,我们直接从CUDESC表中将0CU记录删除即可。这里指的删除天然支持MVCC,因此老的快照查询依然可以访问被删除的记录。 小CU合并的过程就是不断的尝试把小于一定阈值的CU标记删除,转移数据到Delta 中,直到这个CU全部被标记删除后变成0 CU,就可以当做0 CU彻底清理。成功解决小CU问题,并且在小CU合并期间对实时入库性能几乎没有影响(推荐小CU行数阈值下upsert性能劣化1%),但是因为小CU问题的解决,可以很好的解决查询性能劣化,空间膨胀等问题,并且小CU合并完成后,最终实时入库性能还是会有显著提升。
-
问题诱因 1) 有些实时表入库量并不大,不定期会有入库,因为 MERGE 的判断标准有两个:行数或者时间,超过时间没有入库后也会强制MERGE,这种情况下MERGE产生的CU的行数不可控,可能产生小CU; 2) 对于缓慢变化维表来说,可能很长时间才改变一次,每次都可能产生一个小 CU,虽然不会有太多这种小CU,但长期运行后,这种维度表数量还很多的情况下,小CU的数量就会到达影响系统性能的级别; 3) 频繁upsert、update、delete等更新后,CU中大部分数据被标记删除,这样的CU虽然会被列存VACUUM通过填充NULL进行回收,但是依然会导致小IO和cudesc表的膨胀,进而影响性能。 问题影响 1) CUDesc 并不会因为 CU 变小而变小,因此当小 CU 过多会导致存储利用率过低。比如一个1000列的大宽表产生的CU只包含1行数据,但是因为每一列都会在CUDESC表中记录,CUDesc也会增加一千多行数据; 2) 只剩下几十行甚至几行的小CU会引发大量的小IO; 3) 粗过滤效率降低,因为CUDESC表中会存储CU的最值,当进行查询时可以先通过最值进行粗过滤,但是如果CU中数据太少导致数据范围小,则会降低粗过滤效率; 4) 降低压缩率。因为数据压缩是以CU为单位的,但是CU过小会导致压缩表现达不到预期。
-
列存储优势明显,但是劣势也比较明显,传统列存表基本无法支持并发更新入库。随着业务复杂程度的提升,出现了对于实时入库和实时查询有较强诉求的场景,这要求数据库同时拥有处理传统TP 场景的事务能力和强大的数据分析能力。这时就可以使用HStore 来处理这些场景了。 HStore 利用Delta表存储update/delete/insert等操作信息。之后依赖后台常驻autovacuum 来做MERGE操作将数据写入主表。 利用特有的 Delta 表,HStore 解决了传统列存表 CU 锁的问题,支持上游upsert/update 等操作实时并发入库。同时还能保证和普通列存表相近的数据分析与数据压缩能力。 HStore 表技术特点如下:完整的事务一致性:支持全面的事务能力,数据插入或者更新提交后即可见不存在时延,保证数据ACID一致性。 全面的功能支持:提供和当前列存一样全面的功能和语法支持。 查询性能好:适用多表关联等复杂AP查询场景,相对于传统行存表,拥有更完善的分布式查询计划与更先进的分布式执行器,性能优势明显。支持复杂的子查询和存储过程,支持主键等传统索引能力去重和加速点查,也支持分区、全局字典、局部排序等方式进一步加速AP查询。 入库快:彻底解决列存CU锁冲突问题,支持高并发的更新入库操作,典型场景下,并发更新性能是之前的百倍以上。 高压缩:数据在MERGE进入列存主表后,按列存储具有天然的压缩优势,能极大地节省磁盘空间与IO资源。
-
行存储 传统OLTP(OnLine Transaction Processsing 联机事务处理)场景与功能、业务强相关,数据需要进行频繁的增删改查,这时比较适合使用行存储式。行存储的优势主要有两个方面:首先是点查性能好,在点查场景下可以直接索引到某行数据的元组位置;其次就是更新效率高,行存储在实时并发入库,并发更新方面依然有着比较大的优势。 列存储 传统行存储形式的数据库主要为业务服务,但是如果涉及到分析查询场景,特别是在数据量大且复杂的查询时,就会遇到性能瓶颈了,性能瓶颈是数据存储方式决定的。因此OLTP(OnLine Transaction Processsing 联机事务处理)场景一般会交给列存储引擎去做。列存储的优势主要有两方面:首先是批量查询性能好,当分析查询只涉及某列或者某几列,不需要访问无关列,特别是在表的宽度比较大时(如一千列),优势更加明显;其次就是列存储的压缩性能更高,原因就是因为数据按列存储,单列类型相同。 列存储引擎的最小存储单位是CU(Compression Unit, 压缩单元):一个CU是由表中某一列的一部分数据组成的压缩数据块, 通过(cu_id,col_id)标识一个CU。另外,列存引擎通过Delta表,避免了小CU的产生,显著提升列存表单条导入的性能,同时解决由于小CU导致的数据膨胀问题。当单条或小批量数据导入到列存表时,需先存入Delta表,当Delta表中数据积攒到指定行数时再存入新产生的CU中。
-
时序表的建表语法,在很大程度上继承了行存和列存的语法,降低了用户的学习成本,能够更容易理解和使用。我们将时序表的列分为三种kv_type类型(tag、field、time),那么如何将对应的列指定为合适的类型,帮助我们更好的提高导入、查询等场景的性能,让业务场景运行的更加高效呢?对于不随时间的变化而变化,描述发电机的属性信息的列(发电机信息、生产厂商、型号、位置、ID)被设置为tag列,在建表时需要将对应的列后面指定为TSTag; 对于采样数据的维度(电压、功率、频率、电流相角)这些对应的采样数值随时间的变化而变,我们将这些维度设置为 field 列,建表语句数据类型后面指定为TSField; 最后一列我们指定为时间列time,存储field列数据对应的时间信息,建表时将指定为TSTime。 在写建表语句时,对于tag列的顺序,我们可以适当优化一下,将唯一性(distinct值)较高的列尽量写在前面,这样对于时序场景的性能有一些提升。如果用户没有手动优化,GaussDB(DWS) IoT数仓也可以自适应的帮助用户提高时序场景的性能。另外,创建时序表时一定要指定表级参数orientation属性设置为timeseries。时序表不需要手动指定DISTRIBUTE BY和PARTITION BY, 默认按照所有tag列分布,且分区健默认为tstim指定的时间列。 对于create table like 语法,该语法需要自动从源表中继承列名和对应的kv_type类型。因此如果源表是非时序表,新表是时序表,对应的列的kv_type类型无法确定,则无法创建成功。
-
案例介绍本案例使用Vanna配合本地Ollama/华为mass服务,并借助开发者空间云开发环境提供的免费GaussDB数据库和HCE2.0开发环境进行本地部署,来构建一个先进的AI自然语言分析系统。 案例内容一、概述1.1 案例介绍使用Vanna配合本地Ollama/华为mass服务,并借助开发者空间云开发环境提供的免费GaussDB数据库开发环境进构建一个先进的AI自然语言分析系统。GaussDB:华为自主创新研发的分布式关系型数据库。该产品支持分布式事务,同城跨AZ部署,数据0丢失,支持1000+的扩展能力,PB级海量存储。同时拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。Vanna:作为数据处理和自然语言处理(NLP)的关键组件,Vanna负责数据的预处理、清洗、转换以及NLP任务的执行,如文本分类、情感分析、实体识别等。Ollama:作为AI模型和算法的核心,Ollama提供了丰富的机器学习模型和深度学习算法,用于训练和优化自然语言处理任务。它与Vanna紧密集成,共同实现高效的数据分析和知识提取。ModelArts Studio(MaaS)平台:是华为云推出的一款大模型即服务平台,可以一站式的对业界主流开源大模型进行部署托管,同时开放大模型API服务,可以结合业界主流Agent开发框架,轻松构建AI Agent应用。华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云开发环境、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。1.2 适用对象企业个人开发者高校学生1.3 案例时间本案例总时长预计60分钟。1.4 案例流程说明:在开发者空间中安装Ollama与Vanna申请华为云开发者空间的GaussDB数据库;启动vanna链接GaussDB数据库进行自然语言数据库分析。申请ModelArts Studio(MaaS)免费服务1.5 资源总览本案例预计花费0.8元。资源名称规格单价(元)时长(分钟)华为开发者空间 - 云开发环境鲲鹏通用计算增强型 kc1 | 2vCPUs | 4G | HCE2.0免费60华为开发者空间 - 生态版GaussDB单副本集中式版 | 4 vCPUs | 16G | HCE OS 64bit (200GB)免费60弹性公网IP按流量计费 5Mbit/s0.8元/GB60二、案例准备工作2.1 配置云开发环境根据案例《开发者空间 - 云开发环境使用指导》,请查看下面链接,配置云开发环境,并通过xshell、crt等链接工具登录云开发环境。开发者空间 - 云开发环境使用指导参考如上案例链接进行配置并连接:创建本地PC和远程云开发环境的隧道链接通过xshell、crt等链接工具登录云开发环境,进行测试2.2 领取GaussDB数据库2.2.1 免费领取GaussDB在线试用版(2025年 06月 21日 - 2025年 12月 31日)。华为开发者空间-GaussDB云数据库领取与使用指导注:部署的Django项目需要对接GaussDB,因此GaussDB需要绑定EIP,参考上述指导中领取部分第(5)步因为默认vanna的postgrs驱动连接gaussdb认证方式有问题,实例创建完成后修改password_encryption_type参数为0,然后在基本信息里修改一下root密码 2.2.2 进行数据初始化领取Gaussdb实例后连接数据库点击登录 输入用户名密码进行登录 点击新建数据库,创建数据库school,兼容选择mysql点击确定 点击去school数据库,创建schema名字school,点击确认 初始化表和数据点击sql窗口,数据库选择school,schema也选择上面创建的school,拷贝表和数据脚本到窗口栏,点击执行sql样例数据: CREATE TABLE students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件'); INSERT INTO students (name, age, major, email) VALUES('张三', 20, '计算机科学', 'zhangsan@example.com'),('李四', 21, '电子工程', 'lisi@example.com'),('王五', 19, '数学', 'wangwu@example.com'),('赵六', 22, '物理', 'zhaoliu@example.com'),('钱七', 20, '化学', 'qianqi@example.com'),('孙八', 21, '生物', 'sunba@example.com'),('周九', 19, '历史', 'zhoujiu@example.com'),('吴十', 22, '哲学', 'wushi@example.com'),('郑十一', 20, '艺术', 'zhengshiyi@example.com'),('王十二', 21, '音乐', 'wangshier@example.com'),('陈十三', 19, '体育', 'chenshisan@example.com'),('冯十四', 22, '英语', 'fengshisi@example.com'),('董十五', 20, '法语', 'dongshiwu@example.com'),('萧十六', 21, '德语', 'xiaoshiliu@example.com'),('曹十七', 19, '日语', 'caoshiqi@example.com'),('许十八', 22, '韩语', 'xushiba@example.com'),('蒋十九', 20, '西班牙语', 'jiangshijiu@example.com'),('沈二十', 21, '意大利语', 'shenshier@example.com'),('韩二十一', 19, '心理学', 'hanershiyi@example.com'),('杨二十二', 22, '社会学', 'yangershi@example.com'); CREATE TABLE courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID'); INSERT INTO courses (course_name, credits, teacher_id) VALUES('数据结构', 4, 1),('微积分', 3, 2),('编程基础', 3, 3),('物理实验', 2, 4),('化学原理', 3, 5),('生物技术', 4, 6),('历史概论', 2, 7),('哲学思考', 3, 8); CREATE TABLE enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩'); INSERT INTO enrollments (student_id, course_id, grade) VALUES(1, 1, 85.5),(2, 2, 90.0),(3, 3, 78.5),(4, 4, 82.0),(5, 5, 88.5),(6, 6, 75.0),(7, 7, 80.5),(8, 8, 87.0),(9, 1, 81.0),(10, 2, 85.5),(11, 3, 79.0),(12, 4, 83.0),(13, 5, 86.5),(14, 6, 77.0),(15, 7, 82.5),(16, 8, 88.0),(17, 1, 84.0),(18, 2, 87.5),(19, 3, 80.0),(20, 4, 85.0),(21, 5, 83.5),(22, 6, 78.0),(23, 7, 81.5),(24, 8, 86.0),(25, 1, 82.0),(26, 2, 84.5),(27, 3, 79.5),(28, 4, 83.0),(29, 5, 86.5),(30, 6, 77.5); 2.3 验证云开发环境与GaussDB互通通过xshell或windows命令终端登录云开发环境,测试GaussDB能否连接,如下是通的 如不通去修改安全组的入方向规则,增加需要的端口如图(默认应该没通的)三、 安装Ollama首先我们要先配置pycharm远程开发环境可参考如下用例基于华为开发者空间-云开发环境,PyCharm SSH远程开发环境搭建:cid:link_2后续所有操作都基于pycharm的远程命令行进行操作 3.1 安装OllamaOllama 是一个强大的开源工具,旨在帮助用户轻松地在本地运行、部署和管理大型语言模型(LLMs)。它提供了一个简单的命令行界面,使用户能够快速下载、运行和与各种预训练的语言模型进行交互执行安装命令如下:方式一(推荐,安装速度快):curl -fsSL https://dtse-mirrors.obs.cn-north-4.myhuaweicloud.com/case/0035/install.sh | sudo bash 3.2 模型部署接下来可以借助 Ollama 工具来部署 Deepseek 大模型,部署 deepseek-r1:1.5b 版本,因为资源有限我们部署一个小一点的模型,执行命令:ollama pull deepseek-r1:1.5b 部署的时间长短依赖于网络的情况,部署完成后,我们就可以与 Deepseek 大模型进行对话了:ollama run deepseek-r1:1.5b 四、 安装配置Vanna4.1 更新python配置虚拟环境vanna使用python 安装建议3.10以上,开发者空间中的python版本为3.9.9,需要先升级python4.1.1 安装所需包sudo yum groupinstall "Development Tools" -ysudo yum install openssl-devel -ysudo yum install gcc -y sudo yum install gcc-c++ -y sudo yum install bzip2-devel -y sudo yum install libffi-devel -y sudo yum install zlib-devel -y sudo yum install wget -y sudo yum install make -y sudo yum install glibc-devel -y sudo yum install libgcc -y sudo yum install tar -y sudo yum install bzip2 -y sudo yum install zlib -y sudo yum install xz -y sudo yum install readline-devel -y sudo yum install sqlite-devel -y sudo yum install sqlite-libs -y 4.1.2 升级pythonsudo wget https://mirrors.huaweicloud.com/python/3.10.14/Python-3.10.14.tgzsudo tar xzf Python-3.10.14.tgzcd Python-3.10.14OPENSSL_PREFIX=/usrsudo ./configure --enable-optimizations --with-ensurepip=install \ --with-openssl=$OPENSSL_PREFIXsudo make -j$(nproc)sudo make altinstallpython3.10 -m sslpython3.10 --version4.1.3 配置python虚拟环境因为业务场景的Python开发,多数都是构建一个大型应用程序,并且不希望各种组件的各种版本之间相互冲突,所以需要设置一个虚拟环境。先需要更新下载源。执行如下命令sudo yum -y updatesudo yum -y upgradepip3 install virtualenv -i cid:link_8 #安装virtualenvpython3.10 -m venv myenv #创建虚拟环境source myenv/bin/activate #激活环境 4.2 python下安装Vannapython 安装建议3.10以上安装前更新下pip,然后执行安装python3.10 -m pip install --upgrade pip -i cid:link_8pip3 install 'vanna[chromadb,ollama,postgres]' -i cid:link_8 4.3 Vanna官网生成示例代码Vanna是一款基于开源Python框架的SQL生成工具,可以用日常用语提问,Vanna自动将其转换为SQL语句,简化数据库查询过程。生成实例代码官网:https://vanna.ai/文档:https://vanna.ai/docs/Vanna的例子,链接如下,按照如下图选择生成示例代码:https://vanna.ai/docs/postgres-ollama-chromadb/依次选择Ollama-ChromaDB-postgres 会生成示例代码, 选择使用的模型商选择使用向量数据库的类型 选择要连接的数据库 样例代码:from vanna.ollama import Ollamafrom vanna.chromadb import ChromaDB_VectorStoreclass MyVanna(ChromaDB_VectorStore, Ollama): def __init__(self, config=None): ChromaDB_VectorStore.__init__(self, config=config) Ollama.__init__(self, config=config)vn = MyVanna(config={'model': 'deepseek-r1:1.5b', 'ollama_host': 'http://localhost:11434'})vn.connect_to_postgres(host='xxxxxxx', dbname='school', user='xxxx', password='xxxx', port='8000')vn.train(ddl="""CREATE TABLE school.students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件');CREATE TABLE school.courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID');CREATE TABLE school.enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩');""")from vanna.flask import VannaFlaskAppVannaFlaskApp(vn, allow_llm_to_see_data=True).run() 五、 启动应用并使用4.1 代码配置打开pycham把样例代码粘贴进main.py,并修改模型和数据库配置vn = MyVanna(config={'model': 'deepseek-r1:1.5b', 'ollama_host': 'http://localhost:11434'})vn.connect_to_postgres(host='xxxx', dbname='school', user='xxxx', password='xxxx', port='8000')上传代码到远程开发环境 5.2 启动应用进入自己配置的ssh远程目录启动应用nohup python3.10 main.py & 查看输出日志,日志最后有系统的登录地址tail nohup.out 创建应用启动的对应端口(8084)的隧道协议,可参考开发者空间 - 云开发环境使用指导-第4章2小节hdspace devenv start-tunnel --instance-id=0edfc31f922c4b54b74ba8819 --remote-port=8084 --local-port=8084 5.3 使用自然语言分析数据库在浏览器输入http://127.0.0.1:8084,进行登录,第一次比较慢等待一下 然后我们可以用自然语言操作数据库了,因为已开发环境内存有限,deepseek-r1:1.5b回答的不太好,如果资源充足可以换别的模型,生成的sql问题可以点击修复;使用自然语言提问:每门课程的做高分是多少 sql结果会自动生成表格和图表 六、 使用华为maas部署使用ollama本地模型比较安全但相对复杂,我们还可以使用华为ModelArts Studio(MaaS)服务来作为系统的智能模型6.1 申请ModelArts免费服务参考下面的步骤,免费体验ModelArts Studio(MaaS)预置服务cid:link_5按下面的步骤获取相关信息:区域切换到“西南-贵阳一”,依次点击:ModelArts Studio->模型推理->在线推理->预置服务->免费服务->领取 领取后点击->调用说明->OpenAI SDKAPI Key管理-> 创建API Key把api key,api地址,model参数保留好备用 6.2 生成vanna代码整体可参考<<四、安装配置vanna>>https://vanna.ai/docs/postgres-ollama-chromadb/依次选择OpenAI-ChromaDB-postgres 成示例代码 生成的示例代码6.3 安装python包注意: 要重新安装使用的包与ollama部署时的不一样pip3 install 'vanna[chromadb,openai,postgres]' -i cid:link_8pip3 install openai #安装openai本地客户端 6.4 修改代码并运行整体可参考步骤<<五、启动应用并使用>>在6.2生成的模板代码下我们进行修改,添加进去华为maas的参数及OpanAI客户端的代码运行前修改如下模型和数据库配置my_llm_api_key = 'key' #上面步骤我们创建的apikeymy_llm_base_url = 'https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/271c9332-4aa6-4ff5-95b3-0cf8bd94c394/v1' # 上面步骤调用说明里的apiurlmy_llm_name = 'DeepSeek-V3' #上面步骤的modelnamevn.connect_to_postgres(host='xxx', dbname='school', user='root', password='xxx', port='8000')代码:from vanna.ollama import Ollamafrom vanna.chromadb import ChromaDB_VectorStorefrom vanna.openai import OpenAI_Chatfrom openai import OpenAImy_llm_api_key = 'key' #上面步骤我们创建的apikeymy_llm_base_url = 'https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/271c9332-4aa6-4ff5-95b3-0cf8bd94c394/v1' # 上面步骤调用说明里的apiurlmy_llm_name = 'DeepSeek-V3' #上面步骤的modelnameclient = OpenAI( api_key=my_llm_api_key, base_url=my_llm_base_url)class MyVanna(ChromaDB_VectorStore, OpenAI_Chat): def __init__(self, client=None, config=None): ChromaDB_VectorStore.__init__(self, config=config) OpenAI_Chat.__init__(self, client=client, config=config)vn = MyVanna(client=client, config={"model": my_llm_name})vn.connect_to_postgres(host='xxx', dbname='school', user='root', password='xxx', port='8000')vn.train(ddl="""CREATE TABLE school.students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件');CREATE TABLE school.courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID');CREATE TABLE school.enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩');""")from vanna.flask import VannaFlaskAppVannaFlaskApp(vn, allow_llm_to_see_data=True).run() 上传代码并运行整体可参考步骤<<五、启动应用并使用>>nohup python3.10 main.py & 在浏览器输入http://127.0.0.1:8084,进行登录使用,我们可以看到使用准确的模型一次就回答对了,如果生产部署选对模型很重要 至此本案例关于在开发者空间–远程开发环境中使用Vanna配合ollama/maas基于GaussDB的自然语言分析系统实践操作完毕。 我正在参加【案例共创】第6期 开发者空间-基于云开发环境和GaussDB构建应用 cid:link_7
-
GaussDB P模式下自增主键是通过序列自增主键,但是如果在M模式下使用序列好像是不行的,一直报游标cursor错误,2种方式兼容不了,M模式下使用AUTO_INCREMENT进行自增主键
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第三期2026/08/21 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;念擎-华为云AI开发者运营案例开发专家
本期直播内容:AI六层能力首次详细解读 + 新一代华为云开发者空间亮相 + 校园案例直播带练
回顾中
热门标签