feat: db storage usage report (#18464)

Basic report to check storage usage by each table.

Note: This is not 100% accurate and will never be 100% accurate but gives rough indication of which table is consuming how much storage.

`no-docs`

[skip ci]
This commit is contained in:
Ankush Menat 2022-10-19 15:23:00 +05:30 committed by GitHub
parent 59387d1a74
commit abaa830bbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 0 deletions

View file

@ -0,0 +1,7 @@
// Copyright (c) 2022, Frappe Technologies and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Database Storage Usage By Tables"] = {
filters: [],
};

View file

@ -0,0 +1,28 @@
{
"add_total_row": 1,
"columns": [],
"creation": "2022-10-19 02:25:24.326791",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"letter_head": "abc",
"modified": "2022-10-19 02:59:00.365307",
"modified_by": "Administrator",
"module": "Core",
"name": "Database Storage Usage By Tables",
"owner": "Administrator",
"prepared_report": 0,
"query": "",
"ref_doctype": "Error Log",
"report_name": "Database Storage Usage By Tables",
"report_type": "Script Report",
"roles": [
{
"role": "System Manager"
}
]
}

View file

@ -0,0 +1,40 @@
# Copyright (c) 2022, Frappe Technologies and contributors
# For license information, please see license.txt
import frappe
COLUMNS = [
{"label": "Table", "fieldname": "table", "fieldtype": "Data", "width": 200},
{"label": "Size (MB)", "fieldname": "size", "fieldtype": "Float"},
{"label": "Data (MB)", "fieldname": "data_size", "fieldtype": "Float"},
{"label": "Index (MB)", "fieldname": "index_size", "fieldtype": "Float"},
]
def execute(filters=None):
frappe.only_for("System Manager")
data = frappe.db.multisql(
{
"mariadb": """
SELECT table_name AS `table`,
round(((data_length + index_length) / 1024 / 1024), 2) `size`,
round((data_length / 1024 / 1024), 2) as data_size,
round((index_length / 1024 / 1024), 2) as index_size
FROM information_schema.TABLES
ORDER BY (data_length + index_length) DESC;
""",
"postgres": """
SELECT
table_name as "table",
round(pg_total_relation_size(quote_ident(table_name)) / 1024 / 1024, 2) as "size",
round(pg_relation_size(quote_ident(table_name)) / 1024 / 1024, 2) as "data_size",
round(pg_indexes_size(quote_ident(table_name)) / 1024 / 1024, 2) as "index_size"
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY 2 DESC;
""",
},
as_dict=1,
)
return COLUMNS, data

View file

@ -0,0 +1,15 @@
# Copyright (c) 2022, Frappe Technologies and contributors
# For license information, please see license.txt
from frappe.core.report.database_storage_usage_by_tables.database_storage_usage_by_tables import (
execute,
)
from frappe.tests.utils import FrappeTestCase
class TestDBUsageReport(FrappeTestCase):
def test_basic_query(self):
_, data = execute()
tables = [d.table for d in data]
self.assertFalse({"tabUser", "tabDocField"}.difference(tables))