数据库创建
有关创建持久数据库,请参阅持久数据库I/O页面。
参数设置
要创建或打开一个持久数据库,应用程序首先在 mco_db_params_t 结构中指定内存设备以及数据库参数,然后将这些参数传递给 mco_db_open_dev()
API 以初始化数据库参数。
对于持久数据库,此结构的关键元素有:
- mem_page_size:数据库对象和索引页的字节大小。
- disk_page_size:这个数据库的持久存储页面的大小(必须是
mem_page_size
的2的幂且至少8倍)。 - db_max_connections:允许连接数据库的总连接数。
- disk_max_database_size:所需的最大磁盘空间。
- file_extension_quantum:数据库运行时在增大数据库文件大小时使用的分配块大小(有助于减少文件碎片)。
- db_log_type:数据库日志文件类型,必须为以下值之一:
- REDO_LOG
- UNDO_LOG
- NO_LOG
- log_params:在
mco_log_params_t
中指定的初始日志设置。 - mode_mask:数据库打开模式标志。
- license_key:商业许可证密钥(可选)
请参考创建数据库页面中讨论的一般准则,以确定结构元素的适当值。
对于 C 语言应用程序,还有一些其他需要注意的因素。
文件最大容量及拓展
数据库容量作为参数传递给 mco_db_open_dev()
函数。根据目标平台的不同,此参数可能是无符号长整型值或无符号长长整型值。无论哪种情况,其类型均为 mco_offset_t
(在mco_spec.h 中定义)。如果不确定最大容量,可以传递MCO_INFINITE_DATABASE_SIZE
。
- disk_max_database_size 元素指定了所消耗的持久性介质空间的最大量。当导致此阈值被超出的事务运行时,数据库运行时将向其报告
MCO_E_DISK_SPACE_EXHAUSTED
或MCO_ERR_DISK_SPACE_EXHAUSTED
(分别取决于是否链接了发布版或调试版库)。 - file_extension_quantum 元素用于确定在扩展文件时分配的持久性介质空间量(最多为
disk_max_database_size
)。通过将其设为disk_page_size
的倍数,可以减少文件碎片并可能提高引用的局部性。
mco_disk_info()
函数可用于收集有关数据库和日志文件当前状态的信息:日志文件的大小(以字节为单位)、数据库文件的大小(以字节为单位)以及数据库文件中实际使用的空间量。
日志参数与事务提交策略
log_params 元素是一个允许微调日志策略的结构。日志文件大小是通过调用
mco_disk_set_log_params()
来设置的。这个函数必须在mco_db_open_dev()
之后调用以建立了事务日志策略。应用程序通过调用
mco_disk_transaction_policy()
函数来设置提交策略,该函数具有以下值之一:- MCO_COMMIT_SYNC_FLUSH
- MCO_COMMIT_BUFFERED
- MCO_COMMIT_DELAYED
- **MCO_COMMIT_NO_SYNC **:应用程序可以通过调用
mco_disk_flush()
’函数显式地强制将缓存刷新到媒体。
注意:mco_disk_flush()
必须在事务范围之外调用。如果从事务内部调用将返回一个错误代码。
恢复未使用的数据存储空间
当使用 MVCC 事务管理器时,在发生崩溃的情况下,持久数据库可能包含未删除的旧版本和数据库对象的工作副本。它们的存在不会破坏数据库的一致性,也不会妨碍应用程序的正常工作,但会不必要地消耗空间。检测这些过时的对象版本需要对数据库进行完整扫描。
出于这个原因,恢复过程不会自动执行此功能。相反,通过调用 mco_disk_database_vacuum()
函数显式地删除未使用的版本:
MCO_RET mco_disk_database_vacuum(mco_db_h con);
请注意,mco_disk_database_vacuum()
需要对数据库进行独占访问。
因此,在清空操作完成并且该函数将控制权返回给应用程序之前,无法对数据库执行任何操作。
或者,可以通过在调用mco_db_open_dev()
时,在mco_db_params_t中设置MCO_DB_MODE_MVCC_AUTO_VACUUM
模式掩码来启用自动修复功能。这样可以确保数据库在需要时自动进行清理和优化,而无需手动干预。
模式选项
mode_mask
是一个位掩码,用于指定运行时选项的任意组合。有关可能选项的详细说明,请参阅数据库打开模式。
创建示例
创建持久化数据库的典型应用程序代码可能如下所示:
#define DATABASE_SEGMENT_SIZE 300 * 1024
#define MEMORY_PAGE_SIZE 128
#define PSTORAGE_PAGE_SIZE 4096
char * db_name = "diskdb";
int main(int argc, char* argv[])
{
MCO_RET rc;
mco_device_t dev[4];
mco_db_params_t db_params;
...
mco_runtime_start();
...
mco_db_params_init ( &db_params );
db_params.mem_page_size = MEMORY_PAGE_SIZE; /* 设置内存部分的页面大小 */
db_params.disk_page_size = PSTORAGE_PAGE_SIZE; /* 设置持久存储的页面大小 */
db_params.db_max_connections = 1; /* 设置与数据库连接的总数 */
db_params.db_log_type = UNDO_LOG; /* 设置日志类型 */
...
rc = mco_db_open_dev(db_name, diskdb_get_dictionary(), dev, 4, &db_params );
if ( MCO_S_OK == rc ) {
// 连接到数据库并执行数据库操作
...
mco_db_close(db_name);
}
...
mco_runtime_stop();
}