运行时控制
初始化
在 C 应用程序中初始化运行时环境的启动过程是 mco_runtime_start()
。在执行任何数据库操作之前,必须调用它。然而,在调用 mco_runtime_start()
之前,通常的做法是通过调用 mco_error_set_handler()
来注册一个致命错误处理程序,在某些特殊情况下,可能需要通过调用 mco_runtime_setoption()
来设置运行时选项。函数 mco_get_runtime_info()
可以在初始化后的任何时间调用,以获取当前运行时的具体配置细节。然后,当完成数据库活动(从所有数据库断开连接并关闭之后),C 应用程序必须调用 mco_runtime_stop()
来清理信号量并对运行时进行有序关闭。
API调用示例:
static void errhandler(MCO_RET n)
{
printf("\nSmartEDB runtime fatal error: %d", n);
getchar();
exit( 0 );
}
int main(int argc, char* argv[])
{
MCO_RET rc;
mco_db_h db;
mco_error_set_handler(&errhandler);
mco_runtime_start();
// 执行数据库处理
mco_runtime_stop();
}
运行时选项
少数单进程全局数据库运行时选项可用于管理共享内存操作系统参数和其他特殊功能。这些选项是在运行时初始化之前通过调用 mco_runtime_setoption()
进行设置的,并且可以在运行时关闭之前的任何时间通过调用 mco_runtime_getoption()
进行检索。有关实际运行时选项的列表,请参考参考指南页面 mco_runtime_setoption()
。
例如,在 Unix 系统上的多进程共享内存应用程序可能需要将共享内存访问模式从默认值 0666
进行设置。为此,应用程序将使用如下代码设置此运行时选项。
mco_runtime_setoption( MCO_RT_OPTION_UNIX_SHM_MASK, 0600 );
...
mco_runtime_start();
...
持久化数据库
持久化数据库应用程序的运行时选项与内存数据库应用程序相同,
但是对于持久化数据库,必须指定内存设备定义和数据库打开参数。
运行库
内存中数据库应用程序必须与以下基本库进行链接:
- mcolib - 基本的核心运行时函数。
- mcovtmem - “虚拟表”内存管理器函数。
- mcotmursiw、mcotmvcc 或 mcotexcl - 事务管理器函数
- mcomconv、mcomipc、mcompsx 或 mcomw32 - 内存设备函数。
- 同步库:对数据库对象以及内部运行时结构的访问进行同步的函数。
- mcouwrt 或 mcowrt:实用函数。
持久化数据库
内存数据库应用程序使用“虚拟表”库 mcovtmem,持久数据库应用程序则使用库 mcovtdsk 以及文件系统库:
- mcofuni:Unix-Linux 文件系统
- mcofw32:Windows 文件系统
使用 mco_db_save()
或 mco_db_load()
函数在持久介质中存储和检索数据库映像文件的应用程序,需要 mcoseri 库中提供的序列化和文件系统功能。
同步库
数据库存储库和数据库运行时元数据是共享资源。它们会被多个任务同时进行读写操作。为确保内部结构和存储库数据的正确性,运行时必须确保这些读写操作按正确的顺序执行。换句话说,对它们的访问必须“同步”。对于大多数受支持的平台,提供了两种同步方法。一种完全基于操作系统的同步内核原语,例如信号量。另一种方法将原子指令与操作系统同步原语相结合。
一种锁定算法可以通过首先尝试使用原子指令锁定资源来创建用户空间“快速路径”。如果尝试失败,并且线程需要阻塞,则会执行系统调用。但如果没有竞争(通常是这种情况),则无需通知内核。内核调用相对昂贵,因为它们会导致 CPU 上下文切换和其他活动。因此,在可能使用原子操作的地方,它们提供了显著的性能优势。
这些同步方法在同步库中实现。除了可能的单线程应用程序(见下面关于 mcosempty.c
的注释)之外,所有应用程序都必须根据操作系统与包内容中列出的同步库之一进行链接。在可能的情况下,会提供一个使用“原子操作”以避免不必要的内核调用的库版本。大多数应用程序,特别是单线程或数据库活动较低(每秒约一次数据库更新)的多线程应用程序,如果可用,使用“+原子操作”库会受益匪浅。但没有通用的一般规则。许多因素决定了“+原子操作”库是否有效,例如:应用程序的数据库访问模式和速率、内核的调度策略,甚至硬件。
在提供了两个版本的同步库的情况下,所有应用程序必须使用相同的版本。当有多个应用程序将访问数据库,或者在多平台场景中,数据库访问可能包含在使用 C、C++、C# 或 Java 编写的不同应用模块中时,重要的是所有应用模块都与相同的同步库链接。
文件 mcosempty.c 包含一个可以在任何平台上编译的“空心”同步实现。它没有同步代码,因此是最快的实现 - 但它仅对单线程应用程序有效。如果此源文件包含在应用程序构建中,则不需要同步库。
最常用的同步库有:
- mcoslnx - Unix-Linux
- mcosw32 - Windows
直接指针库
正如产品概述中所提到的,为全内存数据库提供了两个版本的运行时库:优化的“直接指针运算”版本和“偏移量”版本。
“偏移量”库的优点是:
- 内存数据库的已保存二进制映像可以加载到内存中的不同起始地址;
- 在共享内存中共享内存数据库的两个(或更多)应用程序不必将共享内存段映射到其本地进程中的相同地址空间。
直接指针运算库的优点是性能更好,对于单个(可能是多线程的)进程中的内存数据库来说是理想的选择。
在 7.1 版本之前的软件包中,该软件包是专门为直接指针或偏移量支持而构建的。对于 7.1 及更高版本,所有软件包都包含两个版本的运行时库。偏移量版本是默认版本,此版本的运行时库位于目录 /target/bin 和 /target/bin.so 中。库的直接指针版本位于目录 /target/bin.dptr 和 /target/bin.dptr.so 中。
- 在 Unix-Linux 系统上构建应用程序时,可以使用 make 命令行选项
PRJ_DIRECTPTR=YES
来实现与直接指针库的链接。 - 在 Windows 上,应用程序通常使用 Visual Studio 进行开发,它没有方便的命令行选项。因此,要与直接指针库链接,必须将项目设置正确设置为 /target/bin.dptr 或 /target/bin.dptr.so 目录。