设备参数
C 和 C++ 应用程序通过 mco_device_t 结构体数组在运行时指定存储设备:传递给 mco_db_open_dev()
的参数。在调用之前会在栈上分配并初始化一个设备结构体数组。
设备参数
每个内存设备都由一个 mco_device_t 结构体定义,该结构体的参数如下:
type
内存区域的类型必须是 mco.h
中定义的以下值之一:
- MCO_MEMORY_CONV:常规(非共享)内存
- MCO_MEMORY_NAMED:命名(共享)内存
请参阅数据写入持久存储以了解这些事务策略的含义。
assignment
此设备的用途必须是 mco.h
中定义的以下值之一:
- MCO_MEMORY_ASSIGN_DATABASE:用于元数据和用户数据、索引及其他数据库结构的内存区域。
- MCO_MEMORY_ASSIGN_CACHE:磁盘管理器缓存(页面池)的内存区域。
MCO_MEMORY_ASSIGN_PERSISTENT
:持久存储设备(可以是文件、多文件或 RAID)。如果定义了持久设备且应用程序未显式分配磁盘页面大小,运行时将为其分配默认值 4096 字节。如果多个应用程序或任务尝试为同一个数据库分配不同的磁盘页面大小,运行时将返回错误代码。- MCO_MEMORY_ASSIGN_LOG:包含数据库日志文件的设备。
- MCO_MEMORY_ASSIGN_HA_ASYNC_BUF:用于 SmartEDB 高可用性的异步缓冲设备。
- MCO_MEMORY_ASSIGN_PIPE_BUF:用于 SmartEDB 事务日志管道的缓冲区。
size
此设备的大小(以字节为单位)。
dev
union
包含了指向为常规/共享内存设备/文件预分配内存的指针,以及持久存储设备的选项。在 mco.h
中定义如下:
typedef struct mco_device_t_ {
unsigned int type;
unsigned int assignment;
mco_size_t size;
union {
struct {
void * ptr;
int flags;
} conv; // 常规内存参数
struct {
char name[MCO_MAX_MEMORY_NAME];
unsigned int flags;
void * hint;
} named; // 共享内存参数
struct {
int flags;
char name[MCO_MAX_FILE_NAME];
} file;
struct {
int flags;
char name[MCO_MAX_MULTIFILE_NAME];
mco_offs_t segment_size;
} multifile; // 持久存储参数
struct {
int flags;
char name[MCO_MAX_MULTIFILE_NAME];
int level;
mco_offs_t offset;
} raid; // raid持久存储参数
struct {
unsigned long handle;
} idesc; // 保留供将来使用
} dev;
} mco_device_t, *mco_device_h;
请注意,struct
的 idesc
部分保留供将来使用,旨在用于所有其他自定义嵌入式内存驱动程序实现。目前,运行时未使用此功能。
conv:常规内存参数
- ptr:为数据库分配的内存块的地址。
- flags:运行时内部使用,非应用程序使用;可设置为零或被应用程序忽略。
named:共享内存参数
对于共享内存设备,有必要指定名称、选项和提示地址以确定操作系统共享内存池中共享内存块的位置。
有关 Windows 和 Unix-Linux 系统中共享内存提示地址影响的详细解释,请参阅共享内存运行时选项。
- name:共享内存设备名称。
- flags:在使用 POSIX mcompsx 内存驱动程序的 Unix-Linux 系统中,
flags
可以设置为MCO_RT_POSIX_SHM_SHARED
(用于“所有进程可访问”的数据库)或MCO_RT_POSIX_SHM_ANONYMOUS
(用于进程“私有”的数据库)。对于所有其他内存驱动程序,此选项不使用,最初应设置为零。 - hint:此参数设置为0时,将由SmartEDB确定实际共享内存段地址。但当从第二个进程尝试打开共享数据库时可能会失败。在这种情况下,应用程序必须提供有效的提示地址。
multifile:持久存储参数
- name:对于持久存储设备,必须指定名称。
- flags:可选。
- segment_size:可选。
raid:持久存储参数
- name:对于持久存储设备,必须指定名称。
- flags:可选。
- level:必须指定。
- offset:必须指定。
持久存储参数
文件打开模式由选项定义,其可取值如下(不同组合的选项可通过“|”运算符进行或运算):
MCO_FILE_OPEN_DEFAULT
以符合目标平台文件系统要求的方式打开文件的标准、统一且安全的流程。该流程依据链接至目标可执行文件中的文件系统封装器来执行以下操作:
目标平台 文件 说明 KDSA mcofcblk.c
使用 cblk_open()
调用创建用于 I/O 操作的文件描述符。KDSA mcofkdsa.c
使用 xpd_init_device_name()
、xpd_connect_via_link()
和xpd_set_handle_flags()
调用为后续的 I/O 操作初始化设备头。uCOS FAT32 mcofucos.c
调用 FILE_OpenShort(FILE_MODE_READ | FILE_MODE_WRITE)
将打开文件以进行读写操作。但不检查文件是否存在,如果文件已存在,其内容将会丢失。Windows - 以下Windows API选项含义:
- GENERIC_READ:读取访问。
-GENERIC_WRITE
:写入访问。
-FILE_SHARE_READ
:可读共享。
-FILE_SHARE_WRITE
:可写共享。
-OPEN_ALWAYS
:总是打开文件。Win32 (NT) mcofw32.c
使用选项组合 GENERIC_READ | GENERIC_WRITE
,FILE_SHARE_READ | FILE_SHARE_WRITE
或OPEN_ALWAYS
,调用CreateFile()
。将创建指定文件,并以读写访问权限打开。WinRT mcofwrt.c
使用选项组合 GENERIC_READ |GENERIC_WRITE
,FILE_SHARE_READ |FILE_SHARE_WRITE
或OPEN_ALWAYS
,调用CreateFile2()
。将创建指定文件,并以读写访问权限打开。内存中 mcofmem.c
由于此实现方式并未打开任何实际文件,而是通过内存进行模拟,因此不会调用任何文件系统调用。 POSIX - 使用选项组合 O_RDWR | O_CREAT
,调用open()
来初始化。此调用在文件不存在时创建该文件,并以读写方式打开它。
POSIX 规范的说明:
-O_RDWR
- 以读写方式打开;
-O_RDONLY
- 仅以读方式打开;
-O_CREAT
- 如果文件不存在则创建文件;
-O_LARGEFILE
- 允许打开大小无法用off_t
或off64_t
表示的文件。POSIX mcofecos.c
eCos 的文件实现。 POSIX mcofintp.c
完整性操作系统(POSIX)的文件实现。 POSIX mcofose.c
OSE 嵌入式文件系统的文件实现。EFS 是 OSE 实时内核的文件系统。 POSIX mcofuni.c
在不支持 pread
和pwrite
的 Unix 系统上的文件实现。POSIX mcofvx.c
VxWorks 的文件实现。 Unix - 以下文件系统封装器执行与上述类似的 open()
调用,同时使用O_LARGEFILE
选项来启用对大文件(> 4G)的操作。Unix mcofu98aio.c
异步文件实现,支持预读 pread
和预写pwrite
(Unix98 标准)Unix mcofu98.c
支持预读 pread
和预写pwrite
的 Unix 文件实现(Unix98 标准)Unix mcofu98zip.c
压缩文件实现,支持预读 pread
和预写pwrite
(Unix98 标准)Unix mcofu98ziplog
压缩文件实现,支持预读 pread
和预写pwrite
(Unix98 标准)MCO_FILE_OPEN_READ_ONLY
为文件设置只读模式,将不允许对该文件进行任何修改。
目标平台 文件 说明 KDSA mcofcblk.c
,mcofkdsa.c
无需执行任何操作。 uCOS FAT32 mcofucos.c
调用 FILE_OpenShort()
,选项组合仅保留FILE_SHARE_READ
。Win32 (NT) mcofw32.c
在 CreateFiles()
调用的选项中添加GENERIC_READ
。WinRT mcofwrt.c
在 CreateFiles2()
调用的选项中添加GENERIC_READ
。内存中 mcofmem.c
无需执行任何操作。 POSIX mcofecos.c
,mcofintp.c
,mcofose.c
,mcofuni.c
,mcofvx.c
在 open()
调用的选项中添加O_RDONLY
。Unix mcofu98aio.c
,mcofu98.c
,mcofu98zip.c
,mcofu98ziplog
在 open()
调用的选项中添加O_RDONLY
。MCO_FILE_OPEN_TRUNCATE
在使用前将正在打开的文件截断为零长度。
目标平台 文件 说明 KDSA mcofcblk.c
调用 cblk_file_truncate()
。KDSA mcofkdsa.c
调用 kdsa_file_truncate()
。uCOS FAT32 mcofucos.c
调用 FILE_Truncate()
。Win32 (NT) / WinRT mcofw32.c
,mcofwrt.c
将选项设置为 CREATE_ALWAYS
,调用CreateFiles()
/CreateFiles2()
。内存中 mcofmem.c
无需调用。 POSIX / Unix mcofecos.c
,mcofintp.c
,mcofose.c
,mcofuni.c
,mcofvx.c
,mcofu98aio.c
,mcofu98.c
,mcofu98zip.c
,mcofu98ziplog
在 open()
调用的选项中添加O_TRUNC
。MCO_FILE_OPEN_NO_BUFFERING
指示底层文件系统不要缓存文件内容,而是立即执行 I/O 操作。
目标平台 文件 说明 KDSA mcofcblk.c
,mcofkdsa.c
无需执行任何操作。 uCOS FAT32 mcofucos.c
无需执行任何操作。 Win32 (NT) / WinRT mcofw32.c
,mcofwrt.c
在 CreateFiles2()
/CreateFiles2()
调用的选项中添加FILE_FLAG_NO_BUFFERING
。内存中 mcofmem.c
无需执行任何操作。 POSIX / Unix mcofecos.c
,mcofintp.c
,mcofose.c
,mcofuni.c
,mcofvx.c
,mcofu98aio.c
,mcofu98.c
,mcofu98zip.c
,mcofu98ziplog
在 open()
调用的选项中包含O_DIRECT
对于 SunOS:调用directio(DIRECTIO_ON)
。MCO_FILE_OPEN_EXISTING
要求只在文件存在时打开该文件,不会创建一个新文件。
目标平台 文件 说明 KDSA mcofcblk.c
,mcofkdsa.c
无需执行任何操作。 uCOS FAT32 mcofucos.c
无需执行任何操作。 Win32 (NT) / WinRT mcofw32.c
,mcofwrt.c
在调用 CreateFiles()
/CreateFiles2()
初始选项组合中添加OPEN_EXISTING
,将仅在文件或设备存在时打开。内存中 mcofmem.c
无需执行任何操作。 POSIX / Unix mcofecos.c
,mcofintp.c
,mcofose.c
,mcofuni.c
,mcofvx.c
,mcofu98aio.c
,mcofu98.c
,mcofu98zip.c
,mcofu98ziplog
从 open() 调用的初始选项组合中排除 O_CREAT
。open()
将仅在文件存在时打开该文件,不会创建新文件。MCO_FILE_OPEN_TEMPORARY
指示底层文件系统将该文件作为临时文件打开。根据文件系统封装器的实现,执行以下操作:
目标平台 文件 说明 KDSA mcofcblk.c
,mcofkdsa.c
对于标记为 MCO_FILE_OPEN_TEMPORARY
的文件,不做任何操作。uCOS FAT32 mcofucos.c
对于标记为 MCO_FILE_OPEN_TEMPORARY
的文件,不做任何操作。Win32 (NT) / WinRT mcofw32.c
,mcofwrt.c
在调用 CreateFiles()
/CreateFiles2()
选项组合中添加FILE_ATTRIBUTE_TEMPORARY
,允许文件用于临时存储。内存中 mcofmem.c
无需执行任何操作。 POSIX / Unix mcofecos.c
,mcofintp.c
,mcofose.c
,mcofuni.c
,mcofvx.c
,mcofu98aio.c
,mcofu98.c
,mcofu98zip.c
,mcofu98ziplog
对于标记为 MCO_FILE_OPEN_TEMPORARY
的文件,不做任何操作。MCO_FILE_OPEN_FSYNC_FIX
启用 UNIX-98 文件系统封装器的刷新操作修复。该修复确认底层文件系统(特别是 ext3 文件系统)确实将文件内容修改写入存储。此用法仅适用于 ext3,并且在某些罕见情况下,当确认底层文件系统存在与刷新相关的故障时才需要使用。
MCO_FILE_OPEN_SUBPARTITION
用于数据库持久存储的 RAID 实现。此选项指定文件系统封装器必须考虑
mco_device_t
结构的偏移字段的值,以适用于 RAID 的所有段。MCO_FILE_OPEN_FSYNC_AIO_BARRIER
适用于 AIO(u98aio)文件系统封装器。此选项指定封装器必须为刷新操作执行屏障操作——在执行刷新操作之前,所有 I/O 操作都必须完成。
MCO_FILE_OPEN_COMPRESSED
适用于压缩(
u98zip
和u98ziplog
)文件系统封装器。此选项指定文件必须被压缩。否则,文件系统封装器将与文件协同工作。MCO_FILE_OPEN_LOCK
仅适用于 u98 实现。
调用
flock()
,此选项指示文件系统封装器设置规则以锁定文件。POSIX:如果另一个进程持有不兼容的锁,则
flock()
调用可能会阻塞。MCO_FILE_OPEN_NO_READ_BUFFERING 和 MCO_FILE_OPEN_NO_WRITE_BUFFERING
仅适用于 u98 实现。
调用
posix_fadvise()
,控制底层文件系统的预读和预写提示的使用。POSIX:程序可以使用
posix_fadvise()
来宣布未来以特定模式访问文件数据的意图,从而允许内核执行适当的优化。MAP_HUGETLB
在大多数现代 Linux 系统中,可以配置虚拟内存空间的一部分以使用大页面。大页面功能使 Linux 内核不仅能够管理标准的 4KB(适用于 x86 和 x86_64 架构)或 16KB(适用于 IA64 架构)页面大小,还能处理大页面内存。当系统需要访问虚拟内存位置时,它通过页表将虚拟地址转换为物理地址。使用大页面减少了需要加载到转换后备缓冲区(Translation Lookaside Buffer, TLB)中的映射数量。TLB 是 CPU 上用于加速虚拟地址到物理地址转换的页表缓存。
启用大页面功能允许内核在 TLB 中使用指向大页面的 hugetlb 条目。hugetlb 条目意味着每个 TLB 条目可以覆盖更大的地址空间,从而减少所需的条目数量来映射相同的内存区域。**对于运行 SmartEDB 数据库且内存容量超过 16GB 的系统,启用大页面功能可显著提高数据库性能。**通过指定
MAP_HUGETLB
标志(在mmap
调用中),可以启用大页面功能。SHM_HUGETLB
此选项与
MAP_HUGETLB
具有相同的效果,但适用于 SmartEDB 共享内存数据库(即shmget
)。