Skip to content

db size for admin api #2430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/node-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Admin api add query `/db_size` to check database size and upsert in metadata

## [10.4.1] - 2024-06-06
### Fixed
- Fix various issue in monitor service, file naming issue and export admin service from node-core
Expand Down
10 changes: 8 additions & 2 deletions packages/node-core/src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@nestjs/common';
import {EventEmitter2, OnEvent} from '@nestjs/event-emitter';
import {TargetBlockPayload, RewindPayload, AdminEvent, IndexerEvent} from '../events';
import {MonitorService, PoiService} from '../indexer';
import {MonitorService, PoiService, StoreService} from '../indexer';
import {getLogger} from '../logger';
import {timeout} from '../utils';
import {BlockRangeDto, BlockRangeDtoInterface} from './blockRange';
Expand Down Expand Up @@ -43,7 +43,8 @@ export class AdminController {
constructor(
private monitorService: MonitorService,
private poiService: PoiService,
private eventEmitter: EventEmitter2
private eventEmitter: EventEmitter2,
private storeService: StoreService
) {}

@Get('index_history/range')
Expand Down Expand Up @@ -118,6 +119,11 @@ export class AdminController {
);
}
}

@Get('db_size')
async getDbSize(): Promise<number> {
return handleServiceCall(() => this.storeService.syncDbSize());
}
}

@Injectable()
Expand Down
27 changes: 19 additions & 8 deletions packages/node-core/src/db/sync-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ export async function getFunctions(sequelize: Sequelize, schema: string, functio
information_schema.routines
WHERE
specific_schema not in ('pg_catalog', 'information_schema')
and routine_type = 'FUNCTION'
and routine_schema = :schema
and routine_type = 'FUNCTION'
and routine_schema = :schema
and routine_name = :functionName;
`,
{
Expand Down Expand Up @@ -214,10 +214,10 @@ export function createNotifyTrigger(schema: string, table: string): string {
return `
DO $$
BEGIN
CREATE TRIGGER "${triggerName}" AFTER INSERT OR UPDATE OR DELETE
ON "${schema}"."${table}"
CREATE TRIGGER "${triggerName}" AFTER INSERT OR UPDATE OR DELETE
ON "${schema}"."${table}"
FOR EACH ROW EXECUTE FUNCTION "${schema}".send_notification('${channelName}');
EXCEPTION
EXCEPTION
WHEN duplicate_object THEN
RAISE NOTICE 'Trigger already exists. Ignoring...';
END$$;
Expand Down Expand Up @@ -276,6 +276,17 @@ export function getExistedIndexesQuery(schema: string): string {
return `SELECT indexname FROM pg_indexes WHERE schemaname = '${schema}'`;
}

export async function getDbSizeQuery(sequelize: Sequelize, schema: string): Promise<number> {
const [size] = (await sequelize.query(
`select sum(pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(tablename)))::bigint from pg_tables where schemaname = :schema`,
{
replacements: {schema},
type: QueryTypes.SELECT,
}
)) as {sum: number}[];
return Number(size.sum);
}

// SQL improvement
const DEFAULT_SQL_EXE_BATCH = 2000;

Expand All @@ -293,7 +304,7 @@ export const sqlIterator = (tableName: string, sql: string, batch: number = DEFA
current_id INT;
BEGIN
SELECT MIN(id), MAX(id) INTO start_id, end_id FROM ${tableName};

IF start_id IS NOT NULL AND end_id IS NOT NULL THEN
FOR current_id IN start_id..end_id BY batch_size LOOP
${sql};
Expand Down Expand Up @@ -564,9 +575,9 @@ export function generateForeignKeyQuery(attribute: ModelAttributeColumnOptions,
DO $$
BEGIN
ALTER TABLE "${foreignTable.schema}"."${tableName}"
ADD
ADD
CONSTRAINT ${fkey}
FOREIGN KEY (${attribute.field})
FOREIGN KEY (${attribute.field})
REFERENCES "${foreignTable.schema}"."${foreignTable.tableName}" (${references.key})`;
if (attribute.onDelete) {
query += ` ON DELETE ${attribute.onDelete}`;
Expand Down
1 change: 1 addition & 0 deletions packages/node-core/src/indexer/entities/Metadata.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface MetadataKeys {
deployments: string;
lastCreatedPoiHeight: number;
latestSyncedPoiHeight: number;
dbSize: number;
latestPoiWithMmr: string; // Deprecated, keep for poi migration
lastPoiHeight: string; // Deprecated, keep for poi migration
}
Expand Down
27 changes: 22 additions & 5 deletions packages/node-core/src/indexer/store.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
BTREE_GIST_EXTENSION_EXIST_QUERY,
createSchemaTrigger,
createSchemaTriggerFunction,
getDbSizeQuery,
getTriggers,
SchemaMigrationService,
} from '../db';
Expand Down Expand Up @@ -58,7 +59,7 @@ export class StoreService {
private _historical?: boolean;
private _dbType?: SUPPORT_DB;
private _metadataModel?: CacheMetadataModel;

private _schema?: string;
// Should be updated each block
private _blockHeight?: number;
private _operationStack?: StoreOperations;
Expand Down Expand Up @@ -103,6 +104,13 @@ export class StoreService {
return this._historical;
}

async syncDbSize(): Promise<number> {
const dbSize = await getDbSizeQuery(this.sequelize, this.schema);
// It doesn't need to update immediately
this.storeCache.metadata.set('dbSize', dbSize);
return dbSize;
}

private get dbType(): SUPPORT_DB {
assert(this._dbType, new NoInitError());
return this._dbType;
Expand All @@ -113,6 +121,11 @@ export class StoreService {
return this._metadataModel;
}

private get schema(): string {
assert(this._schema, new NoInitError());
return this._schema;
}

// Initialize tables and data that isnt' specific to the users data
async initCoreTables(schema: string): Promise<void> {
if (this.config.proofOfIndex) {
Expand All @@ -128,6 +141,7 @@ export class StoreService {
);

this._dbType = await getDbType(this.sequelize);
this._schema = schema;

await this.sequelize.sync();

Expand Down Expand Up @@ -283,10 +297,13 @@ export class StoreService {
{type: QueryTypes.SELECT}
);

const store = res.reduce(function (total, current) {
total[current.key] = current.value;
return total;
}, {} as {[key: string]: string | boolean});
const store = res.reduce(
function (total, current) {
total[current.key] = current.value;
return total;
},
{} as {[key: string]: string | boolean}
);

const useHistorical =
store.historicalStateEnabled === undefined ? !disableHistorical : (store.historicalStateEnabled as boolean);
Expand Down
Loading