* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* og_miner_desc.c
*
*
* IDENTIFICATION
* src/ogbox/og_miner_desc.c
*
* -------------------------------------------------------------------------
*/
#include "og_tbox_module.h"
#include "og_miner_desc.h"
#include "pcr_btree.h"
#include "dtc_database.h"
static status_t miner_time2str(time_t time, char *str, uint16 size)
{
text_t fmt_text;
text_t time_text;
if (strlen("YYYY-MM-DD HH24:MI:SS") >= size) {
OG_THROW_ERROR(ERR_BUFFER_UNDERFLOW, size, strlen("YYYY-MM-DD HH24:MI:SS"));
return OG_ERROR;
}
cm_str2text("YYYY-MM-DD HH24:MI:SS", &fmt_text);
time_text.str = str;
time_text.len = 0;
return cm_time2text(time, &fmt_text, &time_text, size);
}
static inline void miner_desc_entry(log_entry_t *log, page_id_t page_id)
{
printf("\tentry: %-20s len: %-4u \tflag: %u \tpage: %u-%u \tdesc: ",
g_log_desc[log->type].name, (uint32)log->size, log->flag, (uint32)page_id.file, (uint32)page_id.page);
if (g_log_desc[log->type].desc_proc != NULL) {
g_log_desc[log->type].desc_proc(log);
} else {
printf("<missed desc proc>\n");
}
}
void miner_desc_group(log_group_t *group)
{
uint32 offset;
page_id_t page[KNL_MAX_ATOMIC_PAGES];
uint32 level;
log_entry_t *entry = NULL;
rd_enter_page_t *redo = NULL;
level = 0;
page[0] = INVALID_PAGID;
offset = sizeof(log_group_t);
printf("group: %llu size: %u rmid: %u nologging insert: %u\n", group->lsn,
(uint32)LOG_GROUP_ACTUAL_SIZE(group), group->rmid, group->nologging_insert);
while (offset < LOG_GROUP_ACTUAL_SIZE(group)) {
entry = (log_entry_t *)((char *)group + offset);
if (RD_TYPE_IS_ENTER_PAGE(entry->type)) {
level++;
redo = (rd_enter_page_t *)entry->data;
page[level] = MAKE_PAGID(redo->file, redo->page);
}
miner_desc_entry(entry, page[level]);
if (RD_TYPE_IS_LEAVE_PAGE(entry->type) && level > 0) {
level--;
}
offset += entry->size;
}
}
void miner_desc_group_xid(log_group_t *group, bool32 has_xid, tx_msg_t *tx_msg, uint8 xid_cnt)
{
uint32 offset;
page_id_t page[KNL_MAX_ATOMIC_PAGES];
uint32 level;
log_entry_t *entry = NULL;
rd_tx_end_t *data = NULL;
level = 0;
page[0] = INVALID_PAGID;
offset = sizeof(log_group_t);
while (offset < LOG_GROUP_ACTUAL_SIZE(group)) {
entry = (log_entry_t *)((char *)group + offset);
if (entry->type != RD_TX_BEGIN && entry->type != RD_TX_END) {
offset += entry->size;
continue;
}
if (entry->type == RD_TX_BEGIN) {
xid_t cur_xid = *(xid_t *)entry->data;
for (uint8 i = 0; i < xid_cnt; i++) {
if (cur_xid.value == tx_msg[i].xid.value) {
tx_msg[i].rmid = group->rmid;
break;
}
}
}
if (entry->type == RD_TX_END) {
for (uint8 i = 0; i < xid_cnt; i++) {
data = (rd_tx_end_t *)entry->data;
if ((uint32)data->xmap.seg_id == tx_msg[i].xid.xmap.seg_id &&
(uint32)data->xmap.slot == tx_msg[i].xid.xmap.slot && group->rmid == tx_msg[i].rmid) {
printf("group: %llu size: %u rmid: %u nologging insert: %u\n",
group->lsn, (uint32)LOG_GROUP_ACTUAL_SIZE(group), group->rmid, group->nologging_insert);
miner_desc_entry(entry, page[level]);
break;
}
}
}
offset += entry->size;
}
}
static void print_heap_information(heap_page_t *page)
{
printf("heap page information\n");
printf("\t{ map.file: %u, map.page: %u, map.list_id: %u, map.slot: %u }\n",
(uint32)page->map.file, (uint32)page->map.page, (uint32)page->map.list_id, (uint32)page->map.slot);
printf("\t{ org_scn: %llu }\n", page->org_scn);
printf("\t{ seg_scn: %llu }\n", page->seg_scn);
printf("\t{ uid: %u }\n", page->uid);
printf("\t{ oid: %u }\n", page->oid);
printf("\t{ first_free_dir: %u }\n", (uint32)(page->first_free_dir));
printf("\t{ next %u-%u }\n", (uint32)(AS_PAGID_PTR(page->next)->file), (uint32)(AS_PAGID_PTR(page->next)->page));
printf("\t{ free_begin: %u }\n", (uint32)(page->free_begin));
printf("\t{ free_end: %u }\n", (uint32)(page->free_end));
printf("\t{ free_size: %u }\n", (uint32)(page->free_size));
printf("\t{ rows: %u }\n", page->rows);
printf("\t{ dirs: %u }\n", page->dirs);
printf("\t{ itls: %u }\n", page->itls);
printf("\t{ scn: %llu }\n", page->scn);
}
static void print_heap_itl_information(heap_page_t *page)
{
itl_t *itl = NULL;
uint32 slot;
printf("itl information on this page {\n");
for (slot = 0; slot < page->itls; slot++) {
itl = heap_get_itl(page, slot);
printf("\titls[%u] ", slot);
printf("\tscn: %-3llu", itl->scn);
printf("\txid.xmap.seg_id: %u", itl->xid.xmap.seg_id);
printf("\txid.xmap.slot: %u", itl->xid.xmap.slot);
printf("\txid.xnum: %u", itl->xid.xnum);
printf("\tfsc: %u", itl->fsc);
printf("\tis_active: %u", itl->is_active);
printf("\tis_owscn: %u", itl->is_owscn);
printf("\tis_copied: %u\n", itl->is_copied);
}
printf("}\n");
}
static void print_heap_row_information(heap_page_t *page)
{
uint32 slot;
row_dir_t *dir = NULL;
row_head_t *row = NULL;
printf("row information on this page {\n");
for (slot = 0; slot < page->dirs; slot++) {
dir = heap_get_dir(page, slot);
printf("\tdirs[%u] ", slot);
printf("\toffset: %-5u", dir->offset);
printf("\tscn: %llu", dir->scn);
printf("\tis_owscn: %u", dir->is_owscn);
printf("\tundo_page: %u-%u", (uint32)dir->undo_page.file, (uint32)dir->undo_page.page);
printf("\tundo_slot: %u", (uint16)dir->undo_slot);
if (dir->is_free) {
printf("\tis_free: 1\n");
continue;
}
row = HEAP_GET_ROW(page, dir);
printf("\trows[%u] ", slot);
printf("\tsize: %u", row->size);
if (IS_SPRS_ROW(row)) {
printf("\tsprs_count: %u", ROW_COLUMN_COUNT(row));
printf("\tsprs_itl_id: %u", ROW_ITL_ID(row));
} else {
printf("\tcolumn_count: %u", ROW_COLUMN_COUNT(row));
printf("\titl_id: %u", ROW_ITL_ID(row));
}
printf("\tis_deleted/is_link/is_migr/self_chg/is_changed %u/%u/%u/%u/%u\n",
row->is_deleted, row->is_link, row->is_migr, row->self_chg, row->is_changed);
}
printf("}\n");
}
static void miner_desc_heap_page(heap_page_t *page)
{
print_heap_information(page);
print_heap_itl_information(page);
print_heap_row_information(page);
}
static void print_pcr_heap_page_information(heap_page_t *page)
{
printf("PCR heap page information\n");
printf("\t{ map.file: %u, map.page: %u, map.list_id: %u, map.slot: %u }\n",
(uint32)page->map.file, (uint32)page->map.page, (uint32)page->map.list_id, (uint32)page->map.slot);
printf("\t{ org_scn: %llu }\n", page->org_scn);
printf("\t{ seg_scn: %llu }\n", page->seg_scn);
printf("\t{ uid: %u }\n", page->uid);
printf("\t{ oid: %u }\n", page->oid);
printf("\t{ first_free_dir: %u }\n", (uint32)(page->first_free_dir));
printf("\t{ next %u-%u }\n", (uint32)(AS_PAGID_PTR(page->next)->file), (uint32)(AS_PAGID_PTR(page->next)->page));
printf("\t{ free_begin: %u }\n", (uint32)(page->free_begin));
printf("\t{ free_end: %u }\n", (uint32)(page->free_end));
printf("\t{ free_size: %u }\n", (uint32)(page->free_size));
printf("\t{ rows: %u }\n", page->rows);
printf("\t{ dirs: %u }\n", page->dirs);
printf("\t{ itls: %u }\n", page->itls);
printf("\t{ scn: %llu }\n", page->scn);
}
static void print_pcrh_itl_information(heap_page_t *page)
{
pcr_itl_t *itl = NULL;
uint32 slot;
printf("itl information on this page {\n");
for (slot = 0; slot < page->itls; slot++) {
itl = pcrh_get_itl(page, slot);
printf("\titls[%u] ", slot);
printf("\tis_active: %u", itl->is_active);
if (itl->is_active) {
printf("\tssn: %u", itl->ssn);
printf("\tfsc: %u", itl->fsc);
} else {
printf("\tscn: %llu", itl->scn);
printf("\tis_owscn: %u", itl->is_owscn);
}
printf("\txid.xmap.seg_id: %u", itl->xid.xmap.seg_id);
printf("\txid.xmap.slot: %u", itl->xid.xmap.slot);
printf("\txid.xnum: %u", itl->xid.xnum);
printf("\tundo_page: %u-%u", (uint32)itl->undo_page.file, (uint32)itl->undo_page.page);
printf("\tundo_slot: %u\n", (uint16)itl->undo_slot);
}
printf("}\n");
}
static void print_pcrh_row_information(heap_page_t *page)
{
pcr_row_dir_t *dir = NULL;
row_head_t *row = NULL;
uint32 slot;
printf("row information on this page {\n");
for (slot = 0; slot < page->dirs; slot++) {
printf("\tdirs[%u] ", slot);
dir = pcrh_get_dir(page, slot);
if (PCRH_DIR_IS_FREE(dir)) {
printf("\tfree dir, next %d\n", PCRH_NEXT_FREE_DIR(dir));
continue;
}
printf("\toffset: %-5u", *dir);
row = PCRH_GET_ROW(page, dir);
printf("\trows[%u] ", slot);
printf("\tsize: %u", row->size);
if (IS_SPRS_ROW(row)) {
printf("\tsprs_count: %u", ROW_COLUMN_COUNT(row));
printf("\tsprs_itl_id: %u", ROW_ITL_ID(row));
} else {
printf("\tcolumn_count: %u", ROW_COLUMN_COUNT(row));
printf("\titl_id: %u", ROW_ITL_ID(row));
}
printf("\tis_deleted/is_link/is_migr/self_chg/is_changed %u/%u/%u/%u/%u",
row->is_deleted, row->is_link, row->is_migr, row->self_chg, row->is_changed);
if (row->is_link || row->is_migr) {
rowid_t *rowid = PCRH_NEXT_ROWID(row);
printf("\tnext_rowid.file: %u", (uint32)rowid->file);
printf("\tnext_rowid.page: %u", (uint32)rowid->page);
printf("\tnext_rowid.slot: %u\n", (uint32)rowid->slot);
} else {
printf("\n");
}
}
printf("}\n");
}
static void miner_desc_pcrh_page(heap_page_t *page)
{
print_pcr_heap_page_information(page);
print_pcrh_itl_information(page);
print_pcrh_row_information(page);
}
static void miner_desc_undo_page(undo_page_t *page)
{
undo_row_t *row = NULL;
page_id_t seg_id;
uint32 slot;
printf("undo page information\n");
printf("\t{ prev: %u-%u }\n", (uint32)page->prev.file, (uint32)page->prev.page);
printf("\t{ ss_time: %lld }\n", page->ss_time);
printf("\t{ rows: %u }\n", page->rows);
printf("\t{ free_size: %u }\n", page->free_size);
printf("\t{ free_begin: %u }\n", page->free_begin);
printf("\t{ begin_slot: %u }\n", page->begin_slot);
printf("row information on this page {\n");
for (slot = 0; slot < page->rows; slot++) {
row = (undo_row_t *)((char *)page + *(uint16 *)((char *)page + PAGE_SIZE(page->head) -
(sizeof(page_tail_t) + (slot + 1) * sizeof(uint16))));
printf("rows[%u], type %s, ", slot, undo_type((uint8)row->type));
printf("is_cleaned %u, is_xfirst %u, scn %llu, is_owscn %u, xid.xmap.seg_id %u, xid.xmap.slot %u, "
"xid.xnum %u, ssn %u ",
(uint32)row->is_cleaned, (uint32)row->is_xfirst, (uint64)row->scn, (uint32)row->is_owscn,
(uint32)row->xid.xmap.seg_id, (uint32)row->xid.xmap.slot, (uint32)row->xid.xnum, row->ssn);
if (row->type == UNDO_BTREE_INSERT || row->type == UNDO_BTREE_DELETE) {
seg_id = MAKE_PAGID((uint16)row->seg_file, (uint32)row->seg_page);
printf("seg_file %u, seg_page %u, index_id %u, is_shadow %d, ", (uint32)seg_id.file, (uint32)seg_id.page,
(uint32)row->index_id, (row->index_id == OG_SHADOW_INDEX_ID ? 1 : 0));
} else if (row->type == UNDO_TEMP_BTREE_INSERT || row->type == UNDO_TEMP_BTREE_DELETE) {
printf("user_id %u, seg_page(table_id) %u, index_id %u, ", (uint32)row->user_id,
(uint32)row->seg_page, (uint32)row->index_id);
} else {
printf("rowid.file %u, rowid.page %u, rowid.slot %u, ", (uint32)row->rowid.file,
(uint32)row->rowid.page, (uint32)row->rowid.slot);
}
printf("prev_page %u-%u, prev_slot %u\n", (uint32)row->prev_page.file,
(uint32)row->prev_page.page, (uint32)row->prev_slot);
}
printf("}\n");
}
static void print_btree_information(btree_page_t *page)
{
printf("btree page information\n");
printf("\t{ seg_scn: %llu }\n", page->seg_scn);
printf("\t{ is_recycled: %u }\n", page->is_recycled);
printf("\t{ prev: %u-%u }\n", (uint32)AS_PAGID_PTR(page->prev)->file, (uint32)AS_PAGID_PTR(page->prev)->page);
printf("\t{ next: %u-%u }\n", (uint32)AS_PAGID_PTR(page->next)->file, (uint32)AS_PAGID_PTR(page->next)->page);
printf("\t{ level: %u }\n", page->level);
printf("\t{ keys: %u }\n", page->keys);
printf("\t{ itls: %u }\n", page->itls);
printf("\t{ free_begin: %u }\n", page->free_begin);
printf("\t{ free_end: %u }\n", page->free_end);
printf("\t{ free_size: %u }\n", page->free_size);
printf("\t{ scn: %llu }\n", page->scn);
}
static void print_btree_itl_information(btree_page_t *page)
{
itl_t *itl = NULL;
printf("itl information on this page {\n");
for (uint32 slot = 0; slot < page->itls; slot++) {
itl = BTREE_GET_ITL(page, slot);
printf("\titls[%u]: ", slot);
printf("\tscn: %-3llu", itl->scn);
printf("\txid.xmap.seg_id: %u", itl->xid.xmap.seg_id);
printf("\txid.xmap.slot: %u", itl->xid.xmap.slot);
printf("\txid.xnum: %u", itl->xid.xnum);
printf("\tfsc: %u", itl->fsc);
printf("\tis_active: %u", itl->is_active);
printf("\tis_owscn: %u", itl->is_owscn);
printf("\tis_copied: %u\n", itl->is_copied);
}
printf("}\n");
}
static void print_btree_key_information(btree_page_t *page)
{
btree_dir_t *dir = NULL;
btree_key_t *key = NULL;
printf("key information on this page {\n");
for (uint32 slot = 0; slot < page->keys; slot++) {
dir = BTREE_GET_DIR(page, slot);
key = BTREE_GET_KEY(page, dir);
printf("\tdirs[%u] ", slot);
printf("\toffset: %-5u", dir->offset);
printf("\titl_id: %u", dir->itl_id);
printf("\tkeys[%u] ", slot);
printf("\tscn: %llu", key->scn);
printf("\tis_owscn/is_infinite/is_deleted/is_cleaned: %u/%u/%u/%u",
key->is_owscn, key->is_infinite, key->is_deleted, key->is_cleaned);
printf("\trowid.file: %u", (uint32)key->rowid.file);
printf("\trowid.page: %u", (uint32)key->rowid.page);
printf("\trowid.slot: %u", (uint32)key->rowid.slot);
printf("\tundo_page: %u-%u", (uint32)key->undo_page.file, (uint32)key->undo_page.page);
printf("\tundo_slot: %u", key->undo_slot);
printf("\tsize: %u\n", (uint32)key->size);
}
printf("}\n");
}
static void miner_desc_btree_page(btree_page_t *page)
{
print_btree_information(page);
print_btree_itl_information(page);
print_btree_key_information(page);
}
static void print_pcrb_information(btree_page_t *page)
{
printf("PCR btree page information\n");
printf("\t{ seg_scn: %llu }\n", page->seg_scn);
printf("\t{ is_recycled: %u }\n", page->is_recycled);
printf("\t{ prev: %u-%u }\n", (uint32)AS_PAGID_PTR(page->prev)->file, (uint32)AS_PAGID_PTR(page->prev)->page);
printf("\t{ next: %u-%u }\n", (uint32)AS_PAGID_PTR(page->next)->file, (uint32)AS_PAGID_PTR(page->next)->page);
printf("\t{ level: %u }\n", page->level);
printf("\t{ keys: %u }\n", page->keys);
printf("\t{ itls: %u }\n", page->itls);
printf("\t{ free_begin: %u }\n", page->free_begin);
printf("\t{ free_end: %u }\n", page->free_end);
printf("\t{ free_size: %u }\n", page->free_size);
}
static void print_pcrb_itl_information(btree_page_t *page)
{
pcr_itl_t *itl = NULL;
uint32 slot;
printf("itl information on this page {\n");
for (slot = 0; slot < page->itls; slot++) {
itl = pcrb_get_itl(page, slot);
printf("\titls[%u] ", slot);
printf("\tis_active: %u", itl->is_active);
if (itl->is_active) {
printf("\tssn: %u", itl->ssn);
printf("\tfsc: %u", itl->fsc);
} else {
printf("\tscn: %llu", itl->scn);
printf("\tis_owscn: %u", itl->is_owscn);
}
printf("\txid.xmap.seg_id: %u", itl->xid.xmap.seg_id);
printf("\txid.xmap.slot: %u", itl->xid.xmap.slot);
printf("\txid.xnum: %u", itl->xid.xnum);
printf("\tundo_page: %u-%u", (uint32)itl->undo_page.file, (uint32)itl->undo_page.page);
printf("\tundo_slot: %u", (uint16)itl->undo_slot);
printf("\tis_copied: %u\n", itl->is_copied);
}
printf("}\n");
}
static void print_pcrb_key_information(btree_page_t *page)
{
pcrb_dir_t *dir = NULL;
pcrb_key_t *key = NULL;
page_id_t child;
uint32 slot;
printf("key information on this page {\n");
for (slot = 0; slot < page->keys; slot++) {
dir = pcrb_get_dir(page, slot);
key = PCRB_GET_KEY(page, dir);
printf("\tdirs[%u] ", slot);
printf("\toffset: %-5u", *dir);
printf("\tkeys[%u] ", slot);
printf("\tsize: %u", (uint32)key->size);
printf("\titl_id: %u", key->itl_id);
printf("\tis_infinite/is_deleted/is_cleaned: %u/%u/%u",
key->is_infinite, key->is_deleted, key->is_cleaned);
printf("\trowid.file: %u", (uint32)key->rowid.file);
printf("\trowid.page: %u", (uint32)key->rowid.page);
printf("\trowid.slot: %u", (uint32)key->rowid.slot);
if (page->level > 0) {
child = pcrb_get_child(key);
printf("\tchild: %u-%u", (uint32)child.file, (uint32)child.page);
}
printf("\n");
}
printf("}\n");
}
static void miner_desc_pcrb_page(btree_page_t *page)
{
print_pcrb_information(page);
print_pcrb_itl_information(page);
print_pcrb_key_information(page);
}
static void miner_desc_map_page(map_page_t *page)
{
map_node_t *node = NULL;
uint32 slot;
printf("map page information {\n");
printf("\tmap.file %u, map.page %u, map.slot %u, map.list_id %u }\n",
(uint32)page->map.file, (uint32)page->map.page, (uint32)page->map.slot, (uint32)page->map.list_id);
printf("\t{ hwm: %u }\n", page->hwm);
printf("list information on this page {\n");
for (slot = 0; slot < HEAP_FREE_LIST_COUNT; slot++) {
printf("\tlists[%u] ", slot);
printf("\tcount: #%-3u", page->lists[slot].count);
printf("\tfirst: %u\n", page->lists[slot].first);
}
printf("}\n");
printf("map information on this page {\n");
for (slot = 0; slot < (uint32)page->hwm; slot++) {
node = (map_node_t *)((char *)page + sizeof(map_page_t) + slot * sizeof(map_node_t));
printf("\tnodes[%u] ", slot);
printf("\tfile: %-3u", (uint32)node->file);
printf("\tpage: %u", (uint32)node->page);
printf("\tprev: %u", (uint32)node->prev);
printf("\tnext: %u\n", (uint32)node->next);
}
printf("}\n");
}
static void miner_desc_txn_page(txn_page_t *page)
{
txn_t *txn = NULL;
page_id_t first;
page_id_t last;
uint32 count;
uint32 slot;
count = (PAGE_SIZE(page->head) - sizeof(page_head_t) - sizeof(page_tail_t)) / sizeof(txn_t);
printf("txn page information {\n");
for (slot = 0; slot < count; slot++) {
txn = &page->items[slot];
first = PAGID_U2N(txn->undo_pages.first);
last = PAGID_U2N(txn->undo_pages.last);
printf("\titems[%u] ", slot);
printf("\txnum: %-3u", txn->xnum);
printf("\tstatus: %s", txn_status((xact_status_t)txn->status));
printf("\tscn: %llu", txn->scn);
printf("\tundo_pages: count %u first %u-%u last %u-%u\n", txn->undo_pages.count,
(uint32)first.file, (uint32)first.page, (uint32)last.file, (uint32)last.page);
}
printf("}\n");
}
static status_t miner_desc_page_head_tail(uint32 id, page_head_t *head, uint32 page_size, bool32 is_checksum, bool32 is_force)
{
page_tail_t *tail = NULL;
bool32 pass_cks;
printf("\ninformation of page %u\n", id);
printf("\tpage head info {\n");
printf("\tpage_id: %u-%u", AS_PAGID_PTR(head->id)->file, AS_PAGID_PTR(head->id)->page);
printf("\tlsn: %llu", head->lsn);
printf("\tpcn: %u", head->pcn);
printf("\tsize_units: %u", head->size_units);
printf("\tsize: %d", PAGE_SIZE(*head));
printf("\ttype: %s", page_type(head->type));
printf("\text_size: %u", head->ext_size);
printf("\tencrypted: %u", head->encrypted);
printf("\tcompressed: %u", head->compressed);
printf("\tsof_damage: %u", head->soft_damage);
printf("\thard_damage: %u", head->hard_damage);
printf("\tnext_ext: %u-%u }\n", AS_PAGID_PTR(head->next_ext)->file, AS_PAGID_PTR(head->next_ext)->page);
if (page_size != PAGE_SIZE(*head) && !is_force) {
printf("\tinvalid page size %d,expected %u.\n", PAGE_SIZE(*head), page_size);
return OG_ERROR;
}
if (head->compressed) {
return OG_SUCCESS;
}
tail = (page_tail_t *)((char *)head + PAGE_SIZE(*head) - sizeof(page_tail_t));
printf("\tpage tail info {\n");
printf("\tchecksum: %u", tail->checksum);
if (tail->checksum != OG_INVALID_CHECKSUM) {
pass_cks = page_verify_checksum(head, page_size);
printf("\tverify checksum: %s", pass_cks ? "success" : "corrupted");
}
printf("\treserve: %u", tail->reserve);
printf("\tpcn: %u }\n", tail->pcn);
return OG_SUCCESS;
}
static void miner_desc_punch_head(spc_punch_head_t *head)
{
printf("punch head information\n");
if (head->punching_exts.count != 0) {
printf("\t{ punching_exts: count %u first %u-%u last %u-%u }\n", head->punching_exts.count,
head->punching_exts.first.file, head->punching_exts.first.page,
head->punching_exts.last.file, head->punching_exts.last.page);
} else {
printf("\t{ punching_exts: count 0 invalid page id range}\n");
}
if (head->punched_exts.count != 0) {
printf("\t{ punched_exts: count %u first %u-%u last %u-%u }\n", head->punched_exts.count,
head->punched_exts.first.file, head->punched_exts.first.page,
head->punched_exts.last.file, head->punched_exts.last.page);
} else {
printf("\t{ punched_exts: count 0 invalid page id range}\n");
}
}
static void miner_desc_space_head(space_head_t *head)
{
uint32 slot;
printf("space head information\n");
printf("\t{ segment_count: %u }\n", head->segment_count);
printf("\t{ datafile_count: %u }\n", head->datafile_count);
printf("\t{ free_extents: count %u first %u-%u last %u-%u }\n", head->free_extents.count,
head->free_extents.first.file, head->free_extents.first.page,
head->free_extents.last.file, head->free_extents.last.page);
miner_desc_punch_head((spc_punch_head_t *)((char *)head + sizeof(space_head_t)));
printf("datafile hwms information {");
for (slot = 0; slot < OG_MAX_SPACE_FILES; slot++) {
if (slot % SPACE_FILES_PER_LINE == 0) {
printf("\n\t");
}
printf("%u ", head->hwms[slot]);
}
printf(" }\n");
}
static void miner_desc_undo_head(undo_segment_t *segment)
{
uint32 slot;
printf("undo segment information\n");
printf("\t{ page lists: count %u first %u-%u last %u-%u }\n", segment->page_list.count,
segment->page_list.first.file, segment->page_list.first.page,
segment->page_list.last.file, segment->page_list.last.page);
printf("\t{ txn_page_count: %u }\n", segment->txn_page_count);
printf("txn_page information on this page {");
for (slot = 0; slot < segment->txn_page_count; slot++) {
if (slot % TXN_PAGE_PER_LINE == 0) {
printf("\n\t");
}
printf("%u-%u ", segment->txn_page[slot].file, segment->txn_page[slot].page);
}
printf("}\n");
}
static void miner_desc_btree_head(btree_segment_t *segment)
{
printf("btree segment information\n");
printf("\t{ tree_info.root %u-%u, tree_info.level %u }\n", (uint32)AS_PAGID(segment->tree_info.root).file,
(uint32)AS_PAGID(segment->tree_info.root).page, (uint32)segment->tree_info.level);
printf("\t{ org_scn: %llu }\n", segment->org_scn);
printf("\t{ seg_scn: %llu }\n", segment->seg_scn);
printf("\t{ table_id: %u }\n", segment->table_id);
printf("\t{ uid: %u }\n", segment->uid);
printf("\t{ index_id: %u }\n", segment->index_id);
printf("\t{ space_id: %u }\n", segment->space_id);
printf("\t{ initrans: %u }\n", segment->initrans);
printf("\t{ cr_mode: %u }\n", segment->cr_mode);
printf("\t{ del_scn: %llu }\n", segment->del_scn);
printf("\t{ del_pages: count %u, first %u-%u, last %u-%u\n", segment->del_pages.count,
segment->del_pages.first.file, segment->del_pages.first.page,
segment->del_pages.last.file, segment->del_pages.last.page);
printf("\t{ pctfree: %u }\n", segment->pctfree);
printf("btree storage information\n");
printf("\t{ extents: count %u, first %u-%u, last %u-%u }\n", segment->extents.count,
segment->extents.first.file, segment->extents.first.page,
segment->extents.last.file, segment->extents.last.page);
printf("\t{ ufp_count: %u }\n", segment->ufp_count);
printf("\t{ ufp_first: %u-%u }\n", segment->ufp_first.file, segment->ufp_first.page);
printf("\t{ ufp_extent: %u-%u }\n", segment->ufp_extent.file, segment->ufp_extent.page);
printf("\t{ page_count: %u }\n", segment->page_count);
printf("\t{ garbage_size: %llu }\n", segment->garbage_size);
printf("\t{ first_recycle_scn: %llu }\n", segment->first_recycle_scn);
printf("\t{ ow_del_scn: %llu }\n", segment->ow_del_scn);
printf("\t{ ow_recycle_scn: %lld }\n", segment->ow_recycle_scn);
printf("\t{ recycle_version_scn: %lld }\n", segment->recycle_ver_scn);
printf("\t{ last_recycle_scn: %llu }\n", segment->last_recycle_scn);
printf("\t{ recycled_pages: count %u, first %u-%u, last %u-%u\n", segment->recycled_pages.count,
segment->recycled_pages.first.file, segment->recycled_pages.first.page,
segment->recycled_pages.last.file, segment->recycled_pages.last.page);
}
static void miner_desc_heap_head(heap_segment_t *segment)
{
uint32 i;
printf("heap segment information\n");
printf("\t{ uid: %u }\n", segment->uid);
printf("\t{ oid: %u }\n", segment->oid);
printf("\t{ space_id: %u }\n", segment->space_id);
printf("\t{ initrans: %u }\n", segment->initrans);
printf("\t{ org_scn: %llu }\n", segment->org_scn);
printf("\t{ seg_scn: %llu }\n", segment->seg_scn);
printf("\t{ cr_mode: %u }\n", segment->cr_mode);
printf("\t{ serial: %llu }\n", segment->serial);
printf("heap storage information\n");
printf("\t{ ufp_count: %u }\n", segment->ufp_count);
printf("\t{ extents: count %u, first %u-%u, last %u-%u }\n", segment->extents.count,
segment->extents.first.file, segment->extents.first.page,
segment->extents.last.file, segment->extents.last.page);
printf("\t{ free_extents: count %u, first %u-%u, last %u-%u }\n", segment->free_extents.count,
segment->free_extents.first.file, segment->free_extents.first.page,
segment->free_extents.last.file, segment->free_extents.last.page);
printf("\t{ free_ufp: %u-%u }\n", segment->free_ufp.file, segment->free_ufp.page);
printf("\t{ data_first: %u-%u }\n", segment->data_first.file, segment->data_first.page);
printf("\t{ data_last: %u-%u }\n", segment->data_last.file, segment->data_last.page);
printf("\t{ cmp_hwm: %u-%u }\n", segment->cmp_hwm.file, segment->cmp_hwm.page);
printf("\t{ shrinkable_scn: %llu }\n", segment->shrinkable_scn);
printf("\t{ page_count: %u }\n", segment->page_count);
printf("\t{ free_page_count: %u }\n", segment->free_page_count);
printf("\t{ last_ext_size: %u }\n", (uint32)segment->last_ext_size);
printf("\t{ compress: %u }\n", (uint32)segment->compress);
printf("heap map information\n");
printf("\t{ tree_info.level: %u", (uint32)segment->tree_info.level);
printf("\ttree_info.root: %u-%u }", (uint32)AS_PAGID(segment->tree_info.root).file,
(uint32)AS_PAGID(segment->tree_info.root).page);
printf("\n\tcurr_map { ");
for (i = 0; i <= (uint32)segment->tree_info.level; i++) {
printf("%u-%u ", segment->curr_map[i].file, segment->curr_map[i].page);
}
printf("}");
printf("\n\tmap_count { ");
for (i = 0; i <= (uint32)segment->tree_info.level; i++) {
printf("%u ", segment->map_count[i]);
}
printf("}");
printf("\n\tlist_range { ");
for (i = 0; i < HEAP_FREE_LIST_COUNT; i++) {
printf("%u ", segment->list_range[i]);
}
printf("}\n");
}
static void miner_desc_lob_head(lob_segment_t *segment)
{
printf("lob segment information\n");
printf("\t{ table_id: %u }\n", segment->table_id);
printf("\t{ uid: %u }\n", segment->uid);
printf("\t{ space_id: %u }\n", segment->space_id);
printf("\t{ column_id: %u }\n", segment->column_id);
printf("\t{ org_scn: %llu }\n", segment->org_scn);
printf("\t{ seg_scn: %llu }\n", segment->seg_scn);
printf("\t{ shrink_scn: %llu }\n", segment->shrink_scn);
printf("lob storage information\n");
printf("\t{ extents: count %u, first %u-%u, last %u-%u }\n", segment->extents.count,
segment->extents.first.file, segment->extents.first.page,
segment->extents.last.file, segment->extents.last.page);
printf("\t{ free_list: count %u, first %u-%u, last %u-%u }\n", segment->free_list.count,
segment->free_list.first.file, segment->free_list.first.page,
segment->free_list.last.file, segment->free_list.last.page);
printf("\t{ ufp_count: %u }\n", segment->ufp_count);
printf("\t{ ufp_first: %u-%u }\n", segment->ufp_first.file, segment->ufp_first.page);
printf("\t{ ufp_extent: %u-%u }\n", segment->ufp_extent.file, segment->ufp_extent.page);
}
static void miner_desc_lob_data(lob_data_page_t *page)
{
lob_chunk_t *chunk = &page->chunk;
printf("lob page chunk information {\n");
printf("\tinsert_xid: ins_xid.xmap.seg_id %u, ins_xid.xmap.slot %u, ins_xid.xnum %u\n",
chunk->ins_xid.xmap.seg_id, chunk->ins_xid.xmap.slot, chunk->ins_xid.xnum);
printf("\tdelete_xid: del_xid.xmap.seg_id %u, del_xid.xmap.slot %u, del_xid.xnum %u\n",
chunk->del_xid.xmap.seg_id, chunk->del_xid.xmap.slot, chunk->del_xid.xnum);
printf("\torg_scn %llu", chunk->org_scn);
printf("\tsize %u", chunk->size);
printf("\tnext %u-%u", (uint32)chunk->next.file, chunk->next.page);
printf("\tfree_next %u-%u", (uint32)chunk->free_next.file, chunk->free_next.page);
printf("\tis_recycle: %u\n", (uint32)chunk->is_recycled);
printf("}\n");
}
static void miner_desc_map_head(const df_map_head_t *page)
{
printf("datafile dump map head information\n");
printf("\tbit unit:%u, group count:%u, reserved:%u \n", (uint32)page->bit_unit, (uint32)page->group_count,
page->reserved);
printf("datafile group information\n");
for (uint32 i = 0; i < (uint32)page->group_count; i++) {
printf("\t page:%u, file:%u, page count:%u \n", page->groups[i].first_map.page,
(uint32)page->groups[i].first_map.file, (uint32)page->groups[i].page_count);
}
}
static void miner_desc_map_data(df_map_page_t *page, uint32 page_size)
{
printf("datafile dump map data information\n");
printf("\t first managed page:%u, file:%u\n", (uint32)page->first_page.page, (uint32)page->first_page.file);
printf("\t first free_bit:%u, free_bits:%u, reserved:%u \n", (uint32)page->free_begin,
(uint32)page->free_bits, page->reserved);
printf("bit map use information(1:use,0:unused)\n");
uint8 *bitmap = page->bitmap;
uint32 bit_cnt = (page_size - sizeof(df_map_page_t) - sizeof(page_tail_t)) * DF_BYTE_TO_BITS;
for (uint32 i = 0; i < bit_cnt; i++) {
if (!DF_MAP_MATCH(bitmap, i)) {
printf("1");
} else {
printf("0");
}
if ((i + 1) % DF_PAGE_PER_LINE == 0) {
if ((i + 1) % DF_PAGE_PER_LINE_COUNT == 0) {
printf("\n");
} else {
printf("\t ");
}
}
}
}
static void miner_desc_page_by_type(char *buf, uint8 type, uint32 page_size)
{
switch (type) {
case PAGE_TYPE_SPACE_HEAD:
miner_desc_space_head((space_head_t *)(buf + sizeof(page_head_t)));
break;
case PAGE_TYPE_HEAP_HEAD:
miner_desc_heap_head((heap_segment_t *)(buf + sizeof(page_head_t)));
break;
case PAGE_TYPE_HEAP_MAP:
miner_desc_map_page((map_page_t *)buf);
break;
case PAGE_TYPE_HEAP_DATA:
miner_desc_heap_page((heap_page_t *)buf);
break;
case PAGE_TYPE_UNDO_HEAD:
miner_desc_undo_head((undo_segment_t *)(buf + sizeof(page_head_t)));
break;
case PAGE_TYPE_TXN:
miner_desc_txn_page((txn_page_t *)buf);
break;
case PAGE_TYPE_UNDO:
miner_desc_undo_page((undo_page_t *)buf);
break;
case PAGE_TYPE_BTREE_HEAD:
miner_desc_btree_head((btree_segment_t *)(buf + sizeof(btree_page_t)));
break;
case PAGE_TYPE_BTREE_NODE:
miner_desc_btree_page((btree_page_t *)buf);
break;
case PAGE_TYPE_LOB_HEAD:
miner_desc_lob_head((lob_segment_t *)(buf + sizeof(page_head_t)));
break;
case PAGE_TYPE_LOB_DATA:
miner_desc_lob_data((lob_data_page_t *)buf);
break;
case PAGE_TYPE_PCRH_DATA:
miner_desc_pcrh_page((heap_page_t *)buf);
break;
case PAGE_TYPE_PCRB_NODE:
miner_desc_pcrb_page((btree_page_t *)buf);
break;
case PAGE_TYPE_FILE_HEAD:
break;
case PAGE_TYPE_DF_MAP_HEAD:
miner_desc_map_head((df_map_head_t *)buf);
break;
case PAGE_TYPE_DF_MAP_DATA:
miner_desc_map_data((df_map_page_t *)buf, page_size);
break;
case PAGE_TYPE_PUNCH_PAGE:
printf("This a punch page without information.\n");
break;
default:
printf("unsupported page type\n");
break;
}
}
static cipher_ctrl_t *miner_page_cipher_ctrl(page_head_t *page)
{
uint32 ctrl_offset = 0;
switch (page->type) {
case PAGE_TYPE_HEAP_DATA:
case PAGE_TYPE_PCRH_DATA:
ctrl_offset = sizeof(heap_page_t);
break;
case PAGE_TYPE_BTREE_NODE:
case PAGE_TYPE_PCRB_NODE:
ctrl_offset = sizeof(btree_page_t);
break;
case PAGE_TYPE_UNDO:
ctrl_offset = sizeof(undo_page_t);
break;
case PAGE_TYPE_LOB_DATA:
ctrl_offset = PAGE_SIZE(*page) - sizeof(page_tail_t) - sizeof(cipher_ctrl_t);
break;
default:
printf("[miner page encrypt]page type not support.");
break;
}
return (cipher_ctrl_t *)((char *)page + ctrl_offset);
}
static char *miner_page_plain_buf(page_head_t *page, uint8 reserve_size)
{
char *plain_buf = NULL;
switch (page->type) {
case PAGE_TYPE_HEAP_DATA:
case PAGE_TYPE_PCRH_DATA:
plain_buf = (char *)page + sizeof(heap_page_t) + reserve_size;
break;
case PAGE_TYPE_BTREE_NODE:
case PAGE_TYPE_PCRB_NODE:
plain_buf = (char *)page + sizeof(btree_page_t) + reserve_size;
break;
case PAGE_TYPE_LOB_DATA:
plain_buf = (char *)page + sizeof(lob_data_page_t);
break;
case PAGE_TYPE_UNDO:
plain_buf = (char *)page + sizeof(undo_page_t) + reserve_size;
break;
default:
printf("[miner page encrypt]page type not support.");
break;
}
return plain_buf;
}
static uint32 miner_page_plain_len(page_head_t *page, uint8 reserve_size)
{
uint32 page_meta_size = 0;
uint32 page_left_size = PAGE_SIZE(*page) - sizeof(page_tail_t) - reserve_size;
switch (page->type) {
case PAGE_TYPE_HEAP_DATA:
case PAGE_TYPE_PCRH_DATA:
page_meta_size = sizeof(heap_page_t);
break;
case PAGE_TYPE_BTREE_NODE:
case PAGE_TYPE_PCRB_NODE:
page_meta_size = sizeof(btree_page_t);
break;
case PAGE_TYPE_LOB_DATA:
page_meta_size = sizeof(lob_data_page_t);
break;
case PAGE_TYPE_UNDO:
page_meta_size = sizeof(undo_page_t);
break;
default:
printf("[miner page encrypt]page type not support.");
break;
}
return page_left_size - page_meta_size;
}
static status_t miner_decrypt_page(page_head_t *page)
{
cipher_ctrl_t *cipher_ctrl = miner_page_cipher_ctrl(page);
char *org_plain_buf = miner_page_plain_buf(page, CIPHER_RESERVE_SIZE);
uint32 org_plain_len = miner_page_plain_len(page, CIPHER_RESERVE_SIZE);
uint32 cipher_len = org_plain_len + cipher_ctrl->cipher_expanded_size;
uint32 MAX_PAGE_SIZE_K = 32;
char *plain_buf = (char *)malloc(SIZE_K(MAX_PAGE_SIZE_K));
if (plain_buf == NULL) {
OG_THROW_ERROR(ERR_ALLOC_MEMORY, (uint64)(SIZE_K(MAX_PAGE_SIZE_K)), "miner batch page");
return OG_ERROR;
}
uint32 plain_len = PAGE_SIZE(*page);
if (cm_decrypt_impl((char *)page + cipher_ctrl->offset, cipher_len, plain_buf, &plain_len) !=
OG_SUCCESS) {
printf("[MINER KMC ERROR]page decrypt failed");
CM_FREE_PTR(plain_buf);
return OG_ERROR;
}
errno_t ret = memcpy_sp(org_plain_buf, PAGE_SIZE(*page), plain_buf, plain_len);
knl_securec_check(ret);
CM_FREE_PTR(plain_buf);
return OG_SUCCESS;
}
void miner_compressed_page(uint32 id, page_head_t *head)
{
int len = PAGE_SIZE(*head);
char *compress_algo = NULL;
uint32 size;
uint32 algo;
uint32 gcnt;
uint32 unused;
uint16 checksum;
if (miner_desc_page_head_tail(id, head, len, OG_FALSE, OG_FALSE) != OG_SUCCESS) {
return;
}
gcnt = COMPRESS_PAGE_HEAD(head)->group_cnt;
size = COMPRESS_PAGE_HEAD(head)->compressed_size;
algo = COMPRESS_PAGE_HEAD(head)->compress_algo;
checksum = COMPRESS_PAGE_HEAD(head)->checksum;
unused = COMPRESS_PAGE_HEAD(head)->unused;
switch (algo) {
case COMPRESS_NONE:
compress_algo = "none";
break;
case COMPRESS_ZLIB:
compress_algo = "zlib";
break;
case COMPRESS_ZSTD:
compress_algo = "zstd";
break;
case COMPRESS_LZ4:
compress_algo = "lz4";
break;
default:
compress_algo = "invalid";
break;
}
printf("\tcompress head info {\n");
printf("\tcompressed_size:%u\t compress_algo:%s\t group_cnt:%u\t checksum: %u\t ",
size, compress_algo, gcnt, checksum);
if (checksum != OG_INVALID_CHECKSUM) {
bool32 pass_cks = page_compress_verify_checksum(head, len);
printf("verify checksum: %s\t", pass_cks ? "success" : "corrupted");
}
printf("unused:%u ", unused);
printf("}\n");
}
void miner_desc_page(uint32 id, char *buf, uint32 page_size, bool32 is_checksum, bool32 is_force)
{
page_head_t *head = (page_head_t *)buf;
if (head->compressed) {
miner_compressed_page(id, head);
return;
}
if (miner_desc_page_head_tail(id, head, page_size, is_checksum, is_force) != OG_SUCCESS) {
return;
}
if (head->encrypted) {
if (miner_decrypt_page(head) != OG_SUCCESS) {
printf("miner page decrypt failed");
return;
}
}
miner_desc_page_by_type(buf, head->type, page_size);
}
static void miner_desc_ctrlfile_nodes_info(database_ctrl_t *ctrl)
{
(void)printf("\tnodes information:\n");
for (uint32 i = 0; i < ctrl->core.node_count; i++) {
dtc_node_ctrl_t *node_ctrl = (dtc_node_ctrl_t *)ctrl->pages[CTRL_LOG_SEGMENT + i].buf;
(void)printf("\tnode id: %u\n", i);
(void)printf("\tscn: %lld\n", node_ctrl->scn);
(void)printf("\trcy_point: asn(%llu)-block_id(%llu)-rst_id(%llu)-lfn(%llu)-lsn(%llu)\n",
(uint64)node_ctrl->rcy_point.asn, (uint64)node_ctrl->rcy_point.block_id,
(uint64)node_ctrl->rcy_point.rst_id, (uint64)node_ctrl->rcy_point.lfn, node_ctrl->rcy_point.lsn);
(void)printf("\tlrp_point: asn(%llu)-block_id(%llu)-rst_id(%llu)-lfn(%llu)-lsn(%llu)\n",
(uint64)node_ctrl->lrp_point.asn, (uint64)node_ctrl->lrp_point.block_id,
(uint64)node_ctrl->lrp_point.rst_id, (uint64)node_ctrl->lrp_point.lfn, node_ctrl->lrp_point.lsn);
(void)printf("\tckpt_id: %llu\n", node_ctrl->ckpt_id);
(void)printf("\tlsn: %lld\n", node_ctrl->lsn);
(void)printf("\tlfn: %lld\n", node_ctrl->lfn);
(void)printf("\tlog_count: %u\n", node_ctrl->log_count);
(void)printf("\tlog_hwm: %u\n", node_ctrl->log_hwm);
(void)printf("\tlog_first: %u\n", node_ctrl->log_first);
(void)printf("\tlog_last: %u\n", node_ctrl->log_last);
(void)printf("\tshutdown_consistency: %u\n", node_ctrl->shutdown_consistency);
(void)printf("\topen_inconsistency: %u\n", node_ctrl->open_inconsistency);
(void)printf("\tconsistent_lfn: %llu\n", node_ctrl->consistent_lfn);
(void)printf("\tundo_space: %u\n", node_ctrl->undo_space);
(void)printf("\tswap_space: %u\n", node_ctrl->swap_space);
(void)printf("\ttemp_undo_space: %u\n", node_ctrl->temp_undo_space);
(void)printf("\tarchived_start: %u\n", node_ctrl->archived_start);
(void)printf("\tarchived_end: %u\n", node_ctrl->archived_end);
(void)printf("\tdoublewrite_start: %u\n", node_ctrl->dw_start);
(void)printf("\tdoublewrite_end: %u\n", node_ctrl->dw_end);
(void)printf("\tlast_asn: %u\n", node_ctrl->last_asn);
(void)printf("\tlast_lfn: %u\n", node_ctrl->last_lfn);
(void)printf("\n");
}
}
static void miner_desc_ctrlfile_logfile_info(database_ctrl_t *ctrl)
{
log_file_ctrl_t *logfile = NULL;
(void)printf("\tlogfiles information:\n");
for (uint32 i = 0; i < ctrl->core.node_count; i++) {
(void)printf("\t(id, name, size, hwm, seq, block_size, flg, type, status, forward, backward):\n");
for (uint32 j = 0; j < OG_MAX_LOG_FILES; j++) {
logfile = (log_file_ctrl_t *)db_get_log_ctrl_item(ctrl->pages, j, sizeof(log_file_ctrl_t),
ctrl->log_segment, i);
(void)printf("\t#%u-%-2u ", i, j);
(void)printf("\t%-*s ", (int)strlen(logfile->name), NULL_2_STR(logfile->name));
(void)printf("\t%lld ", logfile->size);
(void)printf("\t%lld ", logfile->hwm);
(void)printf("\t%u ", logfile->seq);
(void)printf("\t%u ", logfile->block_size);
(void)printf("\t%u ", (uint32)logfile->flg);
(void)printf("\t%u ", (uint32)logfile->type);
(void)printf("\t%u ", (uint32)logfile->status);
(void)printf("\t%u ", (uint32)logfile->forward);
(void)printf("\t%u\n", (uint32)logfile->backward);
}
(void)printf("\n");
}
}
static void miner_desc_ctrlfile_space_info(database_ctrl_t *ctrl)
{
space_ctrl_t *space = NULL;
(void)printf("\tspaces information:\n");
(void)printf("\t(id, spaceid, used, name, flg, block_size, extent_size, file_hwm, type, org_scn,"
" encrypt_version, cipher_reserve_size, files):\n");
for (uint32 i = 0; i < OG_MAX_SPACES; i++) {
space = (space_ctrl_t *)db_get_ctrl_item(ctrl->pages, i, sizeof(space_ctrl_t), ctrl->space_segment);
(void)printf("\t#%-2u ", i);
(void)printf("\t%u ", space->id);
(void)printf("\t%u ", (uint32)space->used);
(void)printf("\t%-*s ", (int)strlen(space->name), NULL_2_STR(space->name));
(void)printf("\t%u ", (uint32)space->flag);
(void)printf("\t%u ", (uint32)space->block_size);
(void)printf("\t%u ", space->extent_size);
(void)printf("\t%u ", space->file_hwm);
(void)printf("\t%u ", (uint32)space->type);
(void)printf("\t%llu ", space->org_scn);
(void)printf("\t%u ", space->encrypt_version);
(void)printf("\t%u ", space->cipher_reserve_size);
(void)printf("\t%u", space->files[0]);
for (uint32 j = 1; j < space->file_hwm; j++) {
(void)printf(", %u", space->files[j]);
}
(void)printf("\n");
}
}
static void miner_desc_ctrlfile_datafile_info(database_ctrl_t *ctrl)
{
datafile_ctrl_t *datafile = NULL;
(void)printf("\tdatafiles information:\n");
(void)printf("\t(id, dfileid, used, name, size, block_size, flg, type, auto_extend_size, auto_extend_maxsize):\n");
for (uint32 i = 0; i < OG_MAX_DATA_FILES; i++) {
datafile = (datafile_ctrl_t *)db_get_ctrl_item(ctrl->pages, i, sizeof(datafile_ctrl_t), ctrl->datafile_segment);
(void)printf("\t#%-2u ", i);
(void)printf("\t%u ", datafile->id);
(void)printf("\t%u ", (uint32)datafile->used);
(void)printf("\t%-*s ", (int)strlen(datafile->name), NULL_2_STR(datafile->name));
(void)printf("\t%lld ", datafile->size);
(void)printf("\t%u ", (uint32)datafile->block_size);
(void)printf("\t%u ", (uint32)datafile->flag);
(void)printf("\t%u ", (uint32)datafile->type);
(void)printf("\t%lld ", datafile->auto_extend_size);
(void)printf("\t%lld\n", datafile->auto_extend_maxsize);
}
}
static void miner_desc_ctrlfile_archlog_info(database_ctrl_t *ctrl)
{
arch_ctrl_t *arch_ctrl = NULL;
(void)printf("\tarchive log information:\n");
(void)printf("\t(id, recid, dest_id, rst_id, asn, stamp, blocks, block_size, "
"logic_size, real_size, first, last, start_lsn, end_lsn, name):\n");
for (uint32 i = 0; i < ctrl->core.node_count; i++) {
for (uint32 j = 0; j < OG_MAX_ARCH_NUM; j++) {
arch_ctrl = (arch_ctrl_t *)db_get_log_ctrl_item(ctrl->pages, j, sizeof(arch_ctrl_t), ctrl->arch_segment, i);
(void)printf("\t#%u-%-2u ", i, j);
(void)printf("\t%u ", arch_ctrl->recid);
(void)printf("\t%u ", arch_ctrl->dest_id);
(void)printf("\t%u ", arch_ctrl->rst_id);
(void)printf("\t%u ", arch_ctrl->asn);
(void)printf("\t%lld", arch_ctrl->stamp);
(void)printf("\t%d", arch_ctrl->blocks);
(void)printf("\t%d", arch_ctrl->block_size);
(void)printf("\t%lld", (int64)arch_ctrl->blocks * arch_ctrl->block_size);
(void)printf("\t%lld", arch_get_ctrl_real_size(arch_ctrl));
(void)printf("\t%llu", arch_ctrl->first);
(void)printf("\t%llu", arch_ctrl->last);
(void)printf("\t%llu", arch_ctrl->start_lsn);
(void)printf("\t%llu", arch_ctrl->end_lsn);
(void)printf("\t%-*s\n", (int)strlen(arch_ctrl->name), NULL_2_STR(arch_ctrl->name));
}
(void)printf("\n");
}
}
static void miner_desc_ctrl_core_attribute(database_ctrl_t *ctrl)
{
char *str = (char *)malloc(OG_MAX_TIME_STRLEN);
if (str == NULL) {
OG_THROW_ERROR(ERR_ALLOC_MEMORY, (uint64)OG_MAX_TIME_STRLEN, "core init time");
return;
}
str[0] = '\0';
(void)printf("\tversion: %u-%u-%u-%u\n", ctrl->core.version.main, ctrl->core.version.major,
ctrl->core.version.revision, ctrl->core.version.inner);
(void)printf("\tstartup times: %u\n", ctrl->core.open_count);
(void)printf("\tdbid times: %u\n", ctrl->core.dbid);
(void)printf("\tdatabase name: %s\n", NULL_2_STR(ctrl->core.name));
if (miner_time2str(ctrl->core.init_time, str, OG_MAX_TIME_STRLEN) != OG_SUCCESS) {
(void)printf("\tinit time: %s\n", "null");
} else {
(void)printf("\tinit time: %s\n", NULL_2_STR(str));
}
CM_FREE_PTR(str);
(void)printf("\tclustered: %u\n", ctrl->core.clustered);
(void)printf("\tnode_count: %u\n", ctrl->core.node_count);
(void)printf("\tmax_nodes: %u\n", ctrl->core.max_nodes);
(void)printf("\ttable$ entry: %u-%u\n", ctrl->core.sys_table_entry.file, ctrl->core.sys_table_entry.page);
(void)printf("\tix_table$1 entry: %u-%u\n", ctrl->core.ix_sys_table1_entry.file, ctrl->core.ix_sys_table1_entry.page);
(void)printf("\tix_table$2 entry: %u-%u\n", ctrl->core.ix_sys_table2_entry.file, ctrl->core.ix_sys_table2_entry.page);
(void)printf("\tcolumn$ entry: %u-%u\n", ctrl->core.sys_column_entry.file, ctrl->core.sys_column_entry.page);
(void)printf("\tix_column$ entry: %u-%u\n", ctrl->core.ix_sys_column_entry.file, ctrl->core.ix_sys_column_entry.page);
(void)printf("\tindex$ entry: %u-%u\n", ctrl->core.sys_index_entry.file, ctrl->core.sys_index_entry.page);
(void)printf("\tix_index$1 entry: %u-%u\n", ctrl->core.ix_sys_index1_entry.file, ctrl->core.ix_sys_index1_entry.page);
(void)printf("\tix_index$2 entry: %u-%u\n", ctrl->core.ix_sys_index2_entry.file, ctrl->core.ix_sys_index2_entry.page);
(void)printf("\tuser$_entry: %u-%u\n", ctrl->core.sys_user_entry.file, ctrl->core.sys_user_entry.page);
(void)printf("\tix_user$1 entry: %u-%u\n", ctrl->core.ix_sys_user1_entry.file, ctrl->core.ix_sys_user1_entry.page);
(void)printf("\tix_user$2 entry: %u-%u\n", ctrl->core.ix_sys_user2_entry.file, ctrl->core.ix_sys_user2_entry.page);
}
static void miner_desc_ctrl_core_log_attributes(database_ctrl_t *ctrl)
{
(void)printf("\traft flush point: scn(%llu)-lfn(%llu)-raft_index(%llu)\n",
ctrl->core.raft_flush_point.scn, ctrl->core.raft_flush_point.lfn, ctrl->core.raft_flush_point.raft_index);
(void)printf("\tbuild completed: %u\n", (uint32)ctrl->core.build_completed);
(void)printf("\tarchive mode: %u\n", (uint32)ctrl->core.log_mode);
(void)printf("\tarchive logs: %llu", ctrl->core.archived_log[0].arch_log);
for (uint32 i = 1; i < OG_MAX_ARCH_DEST; i++) {
(void)printf("-%llu", ctrl->core.archived_log[i].arch_log);
}
(void)printf("\n");
}
static void miner_desc_ctrl_core_space_attributes(database_ctrl_t *ctrl)
{
(void)printf("\tdb_role: %u\n", (uint32)ctrl->core.db_role);
(void)printf("\tprotect mode: %u\n", (uint32)ctrl->core.protect_mode);
(void)printf("\tspace count: %u\n", ctrl->core.space_count);
(void)printf("\tdevice count: %u\n", ctrl->core.device_count);
(void)printf("\tpage size: %u\n", ctrl->core.page_size);
(void)printf("\tundo segments: %u\n", ctrl->core.undo_segments);
(void)printf("\tundo segments extend: %u\n", ctrl->core.undo_segments_extended);
(void)printf("\treset logs: %u-%u-%llu\n",
ctrl->core.resetlogs.rst_id, ctrl->core.resetlogs.last_asn, ctrl->core.resetlogs.last_lfn);
(void)printf("\tlogic replication mode: %u\n", (uint32)ctrl->core.lrep_mode);
(void)printf("\tmax column count: %u\n", ctrl->core.max_column_count);
(void)printf("\topen inconsistency: %u\n", ctrl->core.open_inconsistency);
(void)printf("\tcharacter set id: %u\n", ctrl->core.charset_id);
(void)printf("\tdouble write file_id: %u\n", ctrl->core.dw_file_id);
(void)printf("\tdouble write area pages: %u\n", ctrl->core.dw_area_pages);
(void)printf("\tsystem space: %u\n", ctrl->core.system_space);
(void)printf("\tsysaux space: %u\n", ctrl->core.sysaux_space);
(void)printf("\tuser space: %u\n", ctrl->core.user_space);
(void)printf("\ttemp undo_space: %u\n", ctrl->core.temp_undo_space);
(void)printf("\ttemp space: %u\n", ctrl->core.temp_space);
(void)printf("\tsystem data version: %u\n", ctrl->core.sysdata_version);
}
void miner_desc_ctrlfile(database_ctrl_t *ctrl)
{
(void)printf("core information:\n");
miner_desc_ctrl_core_attribute(ctrl);
miner_desc_ctrl_core_log_attributes(ctrl);
miner_desc_ctrl_core_space_attributes(ctrl);
(void)printf("storage information:\n");
miner_desc_ctrlfile_nodes_info(ctrl);
miner_desc_ctrlfile_logfile_info(ctrl);
miner_desc_ctrlfile_space_info(ctrl);
miner_desc_ctrlfile_datafile_info(ctrl);
miner_desc_ctrlfile_archlog_info(ctrl);
}
static void print_bakcup_time_str(time_t time, const char *name)
{
char str[OG_MAX_TIME_STRLEN] = { 0 };
if (miner_time2str(time, str, OG_MAX_TIME_STRLEN) != OG_SUCCESS) {
(void)printf("\t%s%s\n", name, "null");
} else {
(void)printf("\t%s%s\n", name, NULL_2_STR(str));
}
}
static void print_backup_information(bak_head_t *bak_head)
{
printf("backupset information\n");
printf("\tversion: %u.%u.%u\n", bak_head->version.major_ver, bak_head->version.min_ver,
bak_head->version.magic);
printf("\ttag: %s\n", bak_head->attr.tag);
printf("\tbase_lsn: %llu\n", bak_head->attr.base_lsn);
printf("\tbase_tag: %s\n", bak_head->attr.base_tag);
printf("\tbackup_type: %u\n", bak_head->attr.backup_type);
printf("\tlevel: %u\n", bak_head->attr.level);
printf("\tcompress: %u\n", bak_head->attr.compress);
printf("\thead_checksum: %u\n", (uint32)bak_head->attr.head_checksum);
printf("\tfile_checksum: %u\n", (uint32)bak_head->attr.file_checksum);
printf("\tcompress_func: %s\n", bak_head->attr.compress_func);
printf("\trcy_point: [%llu-%u-%u] lfn %llu\n", (uint64)bak_head->ctrlinfo.rcy_point.rst_id,
bak_head->ctrlinfo.rcy_point.asn, bak_head->ctrlinfo.rcy_point.block_id,
(uint64)bak_head->ctrlinfo.rcy_point.lfn);
printf("\tlrp_point: [%llu-%u-%u] lfn %llu\n", (uint64)bak_head->ctrlinfo.lrp_point.rst_id,
bak_head->ctrlinfo.lrp_point.asn, bak_head->ctrlinfo.lrp_point.block_id,
(uint64)bak_head->ctrlinfo.lrp_point.lfn);
printf("\tscn: %llu\n", (uint64)bak_head->ctrlinfo.scn);
timeval_t time_val;
KNL_SCN_TO_TIME(bak_head->ctrlinfo.scn, &time_val, bak_head->db_init_time);
time_t scn_time = cm_date2time(cm_timeval2date(time_val));
print_bakcup_time_str(scn_time, "scn_time: ");
printf("\tlsn: %llu\n", bak_head->ctrlinfo.lsn);
printf("\tfile_count: %u\n", bak_head->file_count);
printf("\tdepend_num: %u\n", bak_head->depend_num);
time_t start_time = cm_date2time((date_t)bak_head->start_time);
print_bakcup_time_str(start_time, "start_time: ");
time_t completion_time = cm_date2time((date_t)bak_head->completion_time);
print_bakcup_time_str(completion_time, "completion_time: ");
printf("\tlog_fisrt_slot: %u\n", bak_head->log_fisrt_slot);
printf("\tdb_id: %u\n", bak_head->db_id);
print_bakcup_time_str(bak_head->db_init_time, "db_init_time: ");
printf("\tdb_role: %u\n", bak_head->db_role);
printf("\tdb_name: %s\n", bak_head->db_name);
printf("\tdb_version: %s\n", bak_head->db_version);
printf("\ttbox_version: %u\n", bak_head->df_struc_version);
}
static void print_backup_file_information(bak_head_t *bak_head, const char *read_buf, uint32 *offset)
{
bak_file_t *bak_files = (bak_file_t *)(read_buf + (*offset));
bak_file_t *file = NULL;
bak_head->file_count = MIN(bak_head->file_count, BAK_MAX_FILE_NUM);
*offset += bak_head->file_count * sizeof(bak_file_t);
for (uint32 i = 0; i < bak_head->file_count; i++) {
file = &bak_files[i];
printf("backup file %u information\n", i);
printf("\ttype: %u\n", file->type);
printf("\tid: %u\n", file->id);
printf("\tsec_id: %u\n", file->sec_id);
printf("\tsize: %llu\n", file->size);
printf("\tsec_start: %llu\n", file->sec_start);
printf("\tsec_end: %llu\n", file->sec_end);
}
}
static void print_backup_dependency(bak_head_t *bak_head, const char *read_buf, uint32 offset)
{
bak_dependence_t *bak_depends = (bak_dependence_t *)(read_buf + offset);
bak_dependence_t *depend = NULL;
bak_head->depend_num = MIN(bak_head->depend_num, BAK_MAX_DEPEND_NUM);
for (uint32 i = 0; i < bak_head->depend_num; i++) {
depend = &bak_depends[i];
printf("backup depentdence %u information\n", i);
printf("\tdevice: %u\n", depend->device);
printf("\tpolicy: %s\n", depend->policy);
printf("\tfile_dest: %s\n", depend->file_dest);
}
}
void miner_desc_backup_info(bak_head_t *bak_head, const char *read_buf, uint32 offset)
{
print_backup_information(bak_head);
print_backup_file_information(bak_head, read_buf, &offset);
print_backup_dependency(bak_head, read_buf, offset);
}