魏 洋
(西南交通大学 信息科学与技术学院,成都 610031)
实时数据库系统是组态软件的核心组成部分,实时数据库及时准确地获取现场数据是整个控制系统正常工作的前提,同时实时数据库系统是实时数据库联系图形系统、历史数据库系统、报表系统、报警系统的桥梁和纽带[1]。传统的关系数据库系统追求的目标是实现大容量数据存储以及数据的准确性,其存放的数据不会主动的随着时间的变化而改变即并没有“实时性”概念,因此开发具有“实时性”概念的实时数据库系统,是基于组态软件设计的重点与难点。
传统的数据库采用常驻磁盘的存储策略,CPU访问存储在磁盘中的数据需要通过I/O操作,由于通过I/O操作读取数据相比内存读取数据速度要慢很多,当系统中对实时事务处理的性能要求很高,频繁的I/O操作很难满足事务定时限制的要求。随着高性能实时事务处理应用的增加以及存储器容量的增加与价格的下降,以“内存数据库”(MMDB,main memory database)技术来实现实时数据库的底层数据存储管理,更有效地支持实时事务,已成为人们的共识[2]。因此我们采用内存存储器、磁盘存储器和档案式存储器等多种存储介质共同构造实时数据库系统存储体系,其体系结构图如图1所示。
图1 实时数据库存储结构
图1中,M1为内存存储器,它存放活跃事务的工作数据,包括采集点、输出控制点、计算中间变量点等。M2为磁盘存储器,本系统采样MySQL关系数据库存放现场设备的历史数据。M3为档案式存储器,用来存放系统组态参数以及系统日志等需要长期保存的非共享数据,组态软件的组态参数用来描述设备、变量、图形等信息。由于XML语言具有极强的信息描述能力,选择XML语言描述组态软件的组态参数,利用Qt中提供的QtXml模块可对XML文档中的组态参数分层读取,获取组态软件所需的初始化节点参数。
传统数据库的数据是“单值”的、静态的,即只要不“显式地”调用UPDATE命令更改数据库中的值,数据库中的数据不会随着现实时间的改变而改变。而实时数据库必须表示数据与时间的关系,即具有“实时性”。
实时数据库中的数据对象用位号表示,位号为一个三元组d:<value,time,valid>。其中,d为位号的标识符,分量dvalue为d的当前状态值,dtime为时标,即实时数据的采样时间或生成时间,dvalid为有效期,对于采样数据是采样周期,对于控制输出数据是控制输出截止时间。
实时数据库系统利用面向对象的模块化设计方法,将实时数据库中的功能分为多个模块单元进行封装,降低系统内部的耦合程度,系统功能模块之间通过封装的接口函数进行联系。实时数据库系统功能模块如图2所示。
图2 实时数据库系统功能模块结构
实时数据库系统的功能模块主要分为以下几个模块单元:
(1)用户触发模块:用户触发实时数据库系统程序,系统程序根据存储在档案式存储器中的XML文件读取组态参数,组态参数提供了系统初始化运行的必要信息。
(2)应用程序接口模块:该模块的接口函数提供了系统内部各个功能模块进行联系的内部通道,也给外部用户程序提供了直接访问实时数据库的通道,外部用户程序通过调用该模块提供的接口函数可对实时库数据进行查询、删除等基本操作,无需利用SQL语句进行操作,节省了解析SQL语句的步骤,提高了系统执行效率。同时该模块还提供了与外存数据库,组态软件等的外部接口函数。
(3)网络通信模块:本系统网络通信模块采用Modbus TCP/IP协议进行远程数据传输,是实时数据库与现场设备之间的网络通道。
(4)采集模块:数据采集模块按照事先设定好的固定周期,对现场设备的状态值进行采集,并写入到实时数据库中,采集模块保证了实时数据库中的采集数据与现场设备状态值保持一致,是实时数据库实时性的保障之一。
(5)回送模块:回送模块将组态软件发出的控制指令数据传输到现场设备,实现组态软件对现场设备的远程控制。
(6)读写操作模块:该模块包含数据输入、输出处理模块,实现对实时数据对象读写操作的功能。
(7)历史数据库模块:历史数据由系统定时从实时数据库中采样保存到历史数据库中,历史数据库通过应用程序接口将数据保存到外部磁盘MySQL数据库中。
(8)报警模块:读取用户事先设定好的位号报警阈值,一旦位号当前值越限发出报警信息,并保存报警记录。
(9)事故处理模块:该模块当现场控制设备发生故障时,发出事故报警,防止事故进一步恶化,并保存事故记录。
一个完整的实时数据库数据模型包括数据结构、数据操作、数据约束3个部分,即有:
RTDM : : = <RTDO, RTC, RTDP>[3]
其中,RTDM为数据模型,RTDO为实时数据对象及其结构,RTDP为施加于RTDO的操作,RTC为施加于RTDO与RTDP的限制,即数据约束。
2.1.1 数据结构
有轨电车弱电集成系统现场有采集数据、计算数据、控制数据等。现场采集数据代表有轨电车弱电集成系统中被监控设备状态,计算数据是由采集数据或者其它数据经过逻辑运算得到的数据,控制数据代表组态软件输出控制命令到现场被控设备。在实时数据库系统中,将以上数据概括、抽象为模拟量输入数据(AI)点、模拟量输出数据(AO)点、数字量输入数据(DI)点、数字量输出数据(DO)点,统称为位号[4]。一个位号有若干位号参数,每个位号参数都有一个数据值,将其抽象归纳为类似于关系数据库中的表的模型,位号标识类比表的主键,若干位号参数类比表的若干字段属性,即一个位号数据表示表的一行记录。位号数据以<key,value>的形式存储在内存中,表示结构如表1所示。
表1 数据结构
2.1.2 数据操作
在传统数据库中定义关系代数有5种基本操作:选择、投影、并、差和笛卡尔积。在本实时数据库系统中数据以<key,value>形式存储,一组key/value类比于关系数据库中的一行记录,对于实时数据库而言,一组数据是二维(值和时间)的,故传统的关系代数操作不能适用于实时数据库,要在传统关系代数操作基础上引入对时间的操作,以选择操作为例:
为了说明方便,表2为简略的有轨电车弱电集成系统现场数字量记录表,将表2命名为table_DI。
表2 table_DI
查询表table_DI中Value值为1,LastUpdate值大于等于30 000 ms的记录:
其操作结果如表3所示。
表3 操作结果
2.1.3 数据约束
实时数据库中的数据是相应现实世界的映像,因此现实世界状态的任何变化都应及时反应到实时数据库中。实时数据库中的数据应保持外部(或绝对)一致性以及相互(或相对)一致性约束[5]。所谓外部一致性约束即要求数据对象时标必须足够接近其真实产生时间,相互一致性约束即要求一组指定参与决策的数据集合相互之间的时间差距在一定的阈值范围内。
以有轨电车弱电集成系统中的采集数据为例,采集数据有两个位号参数分别为LastUpdate(数据最新更新时间,单位为:ms)和CollecTime(采样周期,单位为:ms),为了保持实时数据库中实时数据外部一致性约束,规定采集数据中的LastUpdate与系统时间差值必须小于等于采样周期,即有Data满足:
为了保持实时数据库中的实时数据相互一致性约束,规定参与决策的一组数据之间的时标差值必须小于等于采样周期,即有一组数据Data1,Data2,…Data(n)满足:
以DI点为例,介绍其模型实例,在有轨电车弱电集成系统中DI点主要为全线列车、机电设备、供电设备等的采集数据以及计算数据。DI点为被控设备的开关量数据,由0和1表示开关的闭合。采用C++语言编程,根据有轨电车弱电集成系统中实际数据抽象概括了统一的数据结构模型,如下:
typedef struct tagDIGITAL
{
string PointCode; //位号标识
string PointDesc; //位号描述
string GroupCode; //组名称,本系统中表示车站名称
string DeviceCode; //车站中被控设备名称
int PointType; //位号类型
int Value; //位号当前值
long CollectTime; //采样周期,单位为:ms
long LastUpdate; //数据最新更新时间,单位为:ms
uchar DataCat; //位号当前值数据类型
short AlarmPriority; //报警优先级
short RtuNo; //采集通道号,0表示通道1,1表示通道2
short PointNo; //采集序号,小于0表示计算点,大于等于0表示从被控设备相应内存地址中读取采集数据
short Complement; //取反标志,0不取反,1取反
short AlarmMode; //报警方式
short IncidentLim; //事故跳闸次数限
short SaveStyle; //存盘方式,0不存盘,1周期存盘,2变化存盘
short SaveInterval; //存盘间隔,单位为:min
short ValDefault; //缺省值,默认为0
} digital;
以上位号的数据模型已经确立,系统初始化生成数据库表或者生成数据库表后查询数据都需要知道表的结构和表中字段的属性结构,因此又抽象归纳了数据库表和表中字段属性的结构模型,如下:
char code[MDB_COLUMN_DESCSIZE]; //位号标识,即字段名称
char desc[MDB_COLUMN_DESCSIZE]; //位号描述,即字段描述
int offset; //字段相对偏移值
mce::ushort unitlen; //字段长度
mce::uchar datatype; //字段类型
mce::uchar iskey; //是否是主键,1为主键,0为非主键
} BASECOLUMN;
实时数据库系统中所有的事务都对各种系统资源存在着共享与竞争,包括存储空间、CPU时间、数据库数据等,资源竞争式共享导致了各种冲突问题,而实时事务并发控制就是解决事务处理过程中所发生的各种冲突问题。目前,实时数据库事务并发控制技术包括锁式协议、乐观协议和时标协议等,以上3种控制技术各有优缺点[6]。针对实时数据库系统中硬实时事务只有周期采集事务和偶发的故障处理事务,其余大部分为软实时事务,并且计算机系统内存资源有限等特点,所以实时数据库系统选择了锁式控制协议。
锁式并发控制协议机制都是进行悲观的冲突探测,即凡是进行并发控制的两个或多个事务都是冲突的,解决方法是让冲突之一的事务阻塞或夭折。典型的锁式并发控制算法是2PL(Two-Phase Lock Protocol)算法,该算法规定事务的执行分为两个阶段:(1)事务对任何数据进行读写操作之前,要先获得该数据的封锁;(2)在释放封锁后,事务不再申请和获得其它任何封锁[7]。传统的2PL算法采用AB(always block)协议,以TH和TR分别代表占有和请求事务,凡是发生冲突就阻塞TR事务,让其等待。传统的2PL算法存在以下问题:(1)可能会发生死锁,这对于实时性很不利;(2)忽略了事务优先级,默认为所有事务具有相同的优先级次序,可能引发系统事务优先级次序倒置,这违背了优先级驱动事务的处理原则。
针对传统的2PL算法存在的缺点,本实时数据库系统使用优先级2PL算法的锁式并发控制协议。优先级2PL算法将基于优先级的冲突解决方式集成到传统的2PL算法中,将每个事务指派一个优先级,当发生冲突时并不总是阻塞TR,而是选择让优先级较低的事务阻塞或夭折,这有利于高优先级的事务被优先处理。典型的优先级2PL算法是2PL-HP算法即高优先级2PL算法,该算法规定发生冲突时,若TR的优先级比所有TH的优先级高(可能有多个共享锁的占有事务),则夭折所有的TH而让TR执行,否则TR等待。采用C++语言编程,2PL-HP的冲突处理算法为:
令P(T)表示事务T的优先级,HC表示所有共享锁占有者TH的集合,WC表示被阻塞的请求事务的集合,2PL-HP冲突处理算法用流程图表示如图3所示。2PL-HP算法在事务冲突解决方式上相比传统的2PL算法,它考虑了事务的优先级次序,将较低优先级的事务推迟执行,有效地解决了优先级倒置问题。
图3 2PL-HP冲突算法流程图
在避免死锁问题上,如果使用2PL-HP算法是静态分配事务优先级次序,可以避免死锁发生。
实时数据库接口为用户程序提供了直接访问实时数据库中数据的有效通道,它是供用户程序调用的一组函数集合,并且规定了调用这些函数集合的规范。直接调用接口函数提供的函数集合,极大地提高了研发人员开发用户程序的效率。由于Windows中动态链接库(DLL)文件被多个程序同时调用时,该DLL页面只需放入内存一次即可实现资源共享,有效节省了内存资源,所以本系统的接口函数都是以动态链接库的形式供用户程序调用。表4列出了实时数据库中部分接口函数。口函数执行出现错误,接口函数返回值会返回错误信息,用户调用程序通过检查接口函数返回值判断函数是否成功执行。
表4 接口函数说明
接口函数中大部分都含有一个或多个参数,并且具有返回值类型。接口函数内部会检查参数的正确性,返回值表示接口函数执行正确与否,如果接
目前,国内轨道交通运营的线路多采用适度集成模式,行车调度系统与综合监控系统等有特殊要求和影响行车安全的系统仍独立设置。这种结构的最大缺点是不能实现系统间高效的联动,一旦行车过程中出现故障,各系统间响应速度不够,限制了轨道交通的运营管理[8]。
有轨电车弱电集成系统应用于深圳龙华线有轨电车项目,将传统的行车调度系统与综合监控系统集成在一套系统上统称为有轨电车弱电集成系统。主要包括信号系统(ATS)、电力监控系统(PSCADA)、火灾自动报警系统(FAS)、自动售检票系统(AFC)、旅客信息系统(PIS)、闭路电视系统(CCTV)、广播系统(PA)、时钟系统(CLK)等。在统一的系统平台上实现对全线列车、机电设备、电力设备的监控功能,需要一个纽带将有轨电车弱电集成系统现场的硬件设备、用户监控界面连接起来。由于组态软件能够以灵活多样的组态方式提供良好的用户开发界面同时支持各种工业控制设备和常见的通信协议,与高可靠的网络系统和工业计算机结合,可以实现向控制层和管理层提供软、硬件的全部接口的功能,因此利用组态软件开发有轨电车弱电集成系统的最佳选择。实时数据库系统是组态软件的核心组成部分,它为组态软件用户界面提供现场监控设备的实时数据同时实时地将控制数据传达到被控设备中。以下简述实时数据库系统应用于有轨电车弱电集成系统中的PSCADA。
电力监控子系统(PSCADA)对有轨电车全线的供电设备的状态进行监控,PSCADA所监控的设备包括变电所10 kV、1 500 V、400 V开关量(包含断路器位置、隔离开关位置、设备工况等),变电所10 kV、1 500 V、400 V电气模拟量等(包含电流、电压、频率、有功功率、无功功率、有功电度、无功电度等)。其中变电所10 kV、1 500 V、400 V开关量在实时数据库系统中的数据模型在2.1中已经给出。PSCADA系统的用户界面通过实时数据库系统提供的接口读取现场被控设备的状态值,将现场设备的实时状态反应在用户界面中,如图4所示。
图4 PSCADA用户界面
图4中,绿色矩形表示断路器处于分闸状态,红色表示断路器处于合闸状态,鼠标右击断路器可以实现对断路器远程控制以及查看断路器实时状态值,包括数字开关量以及模拟量的值,如图5所示。
图5 右击断路器弹出窗口
以查看断路器的实时状态值为例,点击实时信息查看编号为6G01断路器的数字量与模拟量实时值,如图6所示。
图6 断路器数字量、模拟量实时值
图6中,断路器相关的数字量、模拟量数据均是通过实时数据库系统提供的接口函数读取的供电设备现场实时的状态值。
使用组态软件开发有轨电车弱电集成系统,系统需要实时监测控制全线列车、机电设备、电力设备的状态值,实时数据库是对这些设备状态的实时映射,所以实时数据库系是决定整个系统能否正常工作的关键。结合有轨电车弱电集成系统实际控制场景,抽象归纳出了实时数据库系统数据模型。分析了实时数据库系统的功能模块结构,利用面向对象的模块化设计方法以及动态链接库技术,提供了实时数据库系统的接口函数。针对实时数据库系统中多事务同时对计算机系统共享资源竞争所引发的冲突问题,使用锁式并发控制技术解决事务冲突问题。通过对传统的2PL算法与优先级2PL算法比较,最终确立了使用2PL-HP算法实现锁式并发控制协议,相比使用2PL算法,解决了事务优先级倒置问题,避免了死锁发生等问题。但同时该算法也存在一些缺陷,如使用2PL-HP算法相比传统的2PL算法浪费了计算机系统资源,也有可能导致活锁的发生。无论是基于乐观还是悲观的实时事务并发控制协议算法都存在一定的缺陷,本文是在计算机系统资源有限,实时数据库系统软实时事务较多的情况下,探索使用了基于2PL-HP算法实现实时数据系统事务锁式并发控制协议,并成功运用在有轨电车弱电集成系统中。最后举例说明实时数据库系统在有轨电车弱电集成子系统PSCADA中的应用。
[1]王 荃,垒 壹,李福中.工控组态软件实时数据库系统的设计与实现[J]. 化工自动化及仪表,2000,27(3):40-43.
[2]张 维.实时事务处理的研究与设计[D].武汉:华中科技大学,2008:4-5.
[3]刘云生,易 岚.一个实时数据模型[J].小型微型计算机系统,2000,21(5):550-551.
[4]雷 建,王润孝,沈 昕.流程工业生产调度与控制集成系统数据库设计[J].工业仪表与自动化装置,2008(3):74-74.
[5]P.A.Thopmpson. A temporal data model based on accounting principles.[D]PhD thesis,Dept. of Computer Science. Univ. of Calgary,Calgary,Alta.,Canada,Mar.1991.
[6]程昌秀,申排伟,陆 锋.面向拓扑空间实体的扩展锁技术[J].计算机辅助设计与图形学学报,2005,17(2):209-210.
[7]姚晓玲,吴哲辉. 2PL协议的Petri网模型[J].计算机工程与应用,2004,40(24):160-161.
[8]金久强,王 浩.北京地铁6号线行车综合自动化系统设计与实现[J].铁路计算机应用,2015,24(8):56-57.