/**
* MySQL Resource - InnoDB
*
* InnoDB buffer pool and engine status metrics.
*/
import type { MySQLAdapter } from "../MySQLAdapter.js";
import type {
ResourceDefinition,
RequestContext,
} from "../../../types/index.js";
export function createInnodbResource(
adapter: MySQLAdapter,
): ResourceDefinition {
return {
uri: "mysql://innodb",
name: "InnoDB Status",
title: "MySQL InnoDB Status",
description: "InnoDB buffer pool statistics and engine status",
mimeType: "application/json",
annotations: {
audience: ["user", "assistant"],
priority: 0.7,
},
handler: async (_uri: string, _context: RequestContext) => {
// Get buffer pool status
const bufferPoolResult = await adapter.executeQuery(`
SHOW GLOBAL STATUS WHERE Variable_name LIKE 'Innodb_buffer_pool%'
`);
const bufferPool: Record<string, number> = {};
for (const row of bufferPoolResult.rows ?? []) {
bufferPool[row["Variable_name"] as string] = parseInt(
row["Value"] as string,
10,
);
}
// Get buffer pool size configuration
const configResult = await adapter.executeQuery(`
SHOW GLOBAL VARIABLES WHERE Variable_name IN (
'innodb_buffer_pool_size', 'innodb_buffer_pool_instances',
'innodb_log_file_size', 'innodb_log_files_in_group',
'innodb_flush_log_at_trx_commit', 'innodb_file_per_table'
)
`);
const config: Record<string, string> = {};
for (const row of configResult.rows ?? []) {
config[row["Variable_name"] as string] = row["Value"] as string;
}
// Get row operations
const opsResult = await adapter.executeQuery(`
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Innodb_rows_read', 'Innodb_rows_inserted',
'Innodb_rows_updated', 'Innodb_rows_deleted',
'Innodb_data_reads', 'Innodb_data_writes',
'Innodb_os_log_written', 'Innodb_log_writes'
)
`);
const operations: Record<string, number> = {};
for (const row of opsResult.rows ?? []) {
operations[row["Variable_name"] as string] = parseInt(
row["Value"] as string,
10,
);
}
// Calculate buffer pool efficiency
const readRequests = bufferPool["Innodb_buffer_pool_read_requests"] ?? 0;
const reads = bufferPool["Innodb_buffer_pool_reads"] ?? 0;
const hitRatio =
readRequests > 0
? Math.round(((readRequests - reads) / readRequests) * 100 * 100) /
100
: 100;
const pagesTotal = bufferPool["Innodb_buffer_pool_pages_total"] ?? 0;
const pagesFree = bufferPool["Innodb_buffer_pool_pages_free"] ?? 0;
const pagesData = bufferPool["Innodb_buffer_pool_pages_data"] ?? 0;
const pagesDirty = bufferPool["Innodb_buffer_pool_pages_dirty"] ?? 0;
return {
buffer_pool: {
size_bytes: parseInt(config["innodb_buffer_pool_size"] ?? "0", 10),
instances: parseInt(
config["innodb_buffer_pool_instances"] ?? "1",
10,
),
hit_ratio_percent: hitRatio,
pages: {
total: pagesTotal,
free: pagesFree,
data: pagesData,
dirty: pagesDirty,
dirty_percent:
pagesTotal > 0 ? Math.round((pagesDirty / pagesTotal) * 100) : 0,
},
read_requests: readRequests,
reads: reads,
write_requests: bufferPool["Innodb_buffer_pool_write_requests"] ?? 0,
},
configuration: {
buffer_pool_size: config["innodb_buffer_pool_size"],
log_file_size: config["innodb_log_file_size"],
log_files_in_group: config["innodb_log_files_in_group"],
flush_log_at_trx_commit: config["innodb_flush_log_at_trx_commit"],
file_per_table: config["innodb_file_per_table"],
},
row_operations: {
reads: operations["Innodb_rows_read"] ?? 0,
inserts: operations["Innodb_rows_inserted"] ?? 0,
updates: operations["Innodb_rows_updated"] ?? 0,
deletes: operations["Innodb_rows_deleted"] ?? 0,
},
io: {
data_reads: operations["Innodb_data_reads"] ?? 0,
data_writes: operations["Innodb_data_writes"] ?? 0,
log_writes: operations["Innodb_log_writes"] ?? 0,
os_log_written: operations["Innodb_os_log_written"] ?? 0,
},
};
},
};
}