存储监控
正如在监控内存数据库存储页面中提到的,SmartEDB提供了统计信息 API 以检查实际使用的内存量和可用的空闲内存量,并为嵌入式应用程序提供回调机制,以便在已用内存空间达到阈值时做出反应。
此外,还提供了数据库计算器 API 以帮助估算数据库存储需求。
类统计接口
函数mco_db_free_pages()
、mco_db_total_pages()
和 mco_db_page_size()
都具备简单的报告功能,分别返回数据库连接的空闲页面总数、可用页面(最初分配的页面)总数以及当前页面大小。
MCO_RET mco_db_free_pages(
/*IN*/ mco_db_h db,
/*OUT*/ uint4 *freepages
);
MCO_RET mco_db_total_pages(
/*IN*/ mco_db_h db,
/*OUT*/ uint4 *totalpages
);
MCO_RET mco_db_page_size(
/*IN*/ mco_db_h db,
/*OUT*/ uint2 * page_size
);
应用程序还可以通过mco_class_stat_get()
函数收集统计信息。这个函数接受一个事务句柄和一个类代码,并在mco_class_stat 结构中返回该类的统计数据:
MCO_RET mco_class_stat_get(
/*IN*/ mco_trans_h t,
/*IN*/ uint2 class_code,
/*OUT*/ mco_class_stat_h stat
);
mco_class_stat 结构有如下定义:
typedef struct mco_class_stat_t_
{
mco_counter_t objects_num;
mco_counter32_t core_pages; /* 除 BLOB 数据外,用于所有数据的页面 */
mco_counter32_t blob_pages; /* 由 BLOB 占用的页面 */
mco_counter32_t seq_pages; /* 序列使用的页面 */
mco_counter_t core_space; /* 以字节为单位,不包括blob */
} mco_class_stat_t, * mco_class_stat_h;
索引统计接口
可以调用以下两个函数来获取运行时的索引统计信息:
MCO_RET mco_index_stat_num (mco_trans_h t, uint2 * pnidx);
MCO_RET mco_index_stat_get (mco_trans_h t, uint2 index, mco_index_stat_t * stat);
在mco_index_stat_t 结构中报告给定索引的运行时统计数据,该结构具有以下定义:
typedef struct mco_index_stat_tree_t_
{
mco_counter_t levels_num; /* 树高 */
mco_counter_t duplicates_num; /* 副本数 */
} mco_index_stat_tree_t;
配置回调
以下函数是对上述运行时统计函数的补充:
void mco_register_alloc_callback(
mco_db_h db,
mco_alloc_callback_t callback,
mco_alloc_callback_threshold_kind_t threshold_kind,
mco_offs_t
threshold_value
);
当调用 mco_register_alloc_callback()
或 mco_register_disk_alloc_callback()
时,必须传递一个如下方式定义的回调函数:
typedef MCO_RET (*mco_alloc_callback_t)(
mco_db_h db, //一个有效的数据库连接句柄。
mco_offs_t used //当前内存使用量(以字节为单位)
);
可参阅 SDK 示例 samples/native/core/21-oveflow/transient ,演示了分配回调实现的用法。
分配回调阈值类型
当调用 mco_register_alloc_callback()
或 mco_register_disk_alloc_callback()
时,必须传递一个类型为 mco_alloc_callback_threshold_kind_t
的参数。
在 mco.h
中定义了以下阈值种类:
typedef enum mco_alloc_callback_threshold_kind_t
{
MCO_ALLOC_PERCENT_USED, // 当数据库内存负载达到指定的阈值时,触发回调函数
MCO_ALLOC_FREE_LEFT, // 跟踪内存使用情况,并在剩余内存少于指定阈值(以字节为单位)时触发回调。
MCO_ALLOC_DELTA_USED, // 每次都触发回调threshold_value字节被分配
MCO_ALLOC_USED // 当内存消耗达到给定阈值时触发回调
} mco_alloc_callback_threshold_kind_t;
此功能为应用程序提供了在达到内存阈值时做出反应的方法。阈值标准对于实现应用程序的“垃圾回收器”(在使用无限大小的数据库时)很有用,以避免耗尽磁盘空间等。mco_alloc_callback_threshold_kind_t
(在 mco.h
中枚举)的可能值如下:
MCO_ALLOC_DELTA_USED:假设
threshold_value
为1024,将触发以下运行时行为:程序创建一个600字节的对象后,创建另一个600字节的对象。因为总内存消耗增加了1,200字节(超过阈值),回调将被调用。
可以再创建另一个600字节的对象,但如果又创建另一个600字节的对象,回调将被再次调用。
可以注册两个不同的回调,一个用于临时数据,一个用于持久数据。要注销回调,mco_register_alloc_callback()
应该以NULL
作为回调调用。当需要将任何特定于应用程序的数据传递给回调时,可以通过mco_db_connect_ctx()
创建的连接上下文来完成。每个连接都注册回调,当从注册回调的连接分配内存时调用回调函数。
请注意,应用程序不能从回调函数本身释放数据库内存,这一点很重要。相反,建议通知不同的垃圾收集线程,或者简单地通过回调函数设置一个“全局”标志,并定期从主应用程序线程检查该标志。
数据库计算器
除了上述运行时统计信息外,SmartEDB 还提供了获取任何数据库类的运行时信息的功能。这些信息包括该类在运行时将使用的内存、其索引以及动态对象的大小。通过这些信息,应用程序可以优化模式设计,选择最佳页面大小以及其他存储和性能参数。
为了获取此类信息,应用程序需要将一个计算器对象附加到指定的数据库,并向计算器注册相关类。应用程序应为每个类提供预期存储的对象数量。此外,SmartEDB 提供了计算器 API,允许应用程序在需要时于运行时使用这些功能。
SmartEDB 包还包含一个名为 dbcalc
的完整应用程序源代码,该应用程序演示了计算器 API 的使用方法,开发人员可以利用它来检查和分析他们的数据库。
持续数据库
SmartEDB提供了额外的API来监视持久介质上的数据库存储,并为嵌入式应用程序提供了回调机制,当使用的内存空间达到阈值时,嵌入式应用程序必须做出反应。
应用程序可以调用函数 mco_disk_info()
来获取有关数据库和日志文件当前状态的信息。该函数返回结构mco_disk_info_t,其中包含日志文件的大小(以字节为单位)、数据库文件的大小(以字节为单位)和数据库文件中实际使用的空间量。
void mco_disk_info(
mco_db_h con,
mco_disk_info_t * info
);
磁盘分配回调
以下函数是对上述mco_disk_info()
函数的补充:
void mco_register_disk_alloc_callback(
mco_db_h db,
mco_alloc_callback_t callback,
mco_alloc_callback_threshold_kind_t threshold_kind,
mco_offs_t threshold_value
);
这个注册函数的操作与mco_register_alloc_callback()
完全相同,只是它用于为持久化类分配器注册回调。