Implement CDB_CheckAnalysisQuota

see #279
This commit is contained in:
Javier Goizueta 2016-10-11 15:14:44 +02:00
parent 091aea088e
commit fa6f9a8a66
4 changed files with 107 additions and 0 deletions

View File

@ -0,0 +1,50 @@
-- Get the factor (fraction of the quota) for Camshaft cached analysis tables
CREATE OR REPLACE FUNCTION _CDB_AnalysisQuotaFactor()
RETURNS float8 AS
$$
DECLARE
factor float8;
BEGIN
-- We use a floating point cdb_conf parameter
SELECT cdb_conf_getconf::text::float8 INTO factor FROM CDB_Conf_GetConf('analysis_cache_factor');
-- With a default value
IF factor IS NULL THEN
factor := 0.2;
END IF;
RETURN factor;
END;
$$
LANGUAGE 'plpgsql' STABLE;
-- This checks the space used up by Camshaft cached analysis tables.
-- An exception will be raised if the limits are exceeded.
-- The name of an analysis table is passed; this, in addition to the
-- db role that executes this function is used to determined which
-- analysis tables will be considered.
CREATE OR REPLACE FUNCTION CDB_CheckAnalysisQuota(table_name TEXT)
RETURNS void AS
$$
DECLARE
schema_name TEXT;
user_name TEXT;
qmax int8;
cache_size float8;
BEGIN
-- We rely on the search_path to determine the user's schema and
-- check for all analysis tables in that schema.
-- An alternative would be to use cdb_analysis_catalog to
-- select analysis tables (cache_tables) from the same user, analysis or node.
-- For example:
-- SELECT unnest(cache_tables) FROM cdb_analysis_catalog
-- WHERE username IN (SELECT username FROM cdb_analysis_catalog
-- WHERE table_name::regclass = ANY (cache_tables));
-- At the moment we're not using the provided table_name.
SELECT current_schema() INTO schema_name;
EXECUTE FORMAT('SELECT %I._CDB_UserQuotaInBytes();', schema_name) INTO qmax;
IF qmax*_CDB_AnalysisQuotaFactor() < _CDB_AnalysisDataSize(schema_name) THEN
-- The limit is defined by a factor applied to the total space quota for the user
RAISE EXCEPTION 'Analysis cache space limits exceeded';
END IF;
END;
$$ LANGUAGE PLPGSQL;

View File

@ -0,0 +1,55 @@
-- Internal auxiliar functions to deal with [Camshaft](https://github.com/cartodb/camshaft) cached analysis tables.
-- This function returns TRUE if a given table name corresponds to a Camshaft cached analysis table
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_IsAnalysisTableName(table_name TEXT)
RETURNS BOOLEAN
AS $$
BEGIN
RETURN table_name SIMILAR TO '\Aanalysis_[0-9a-f]{10}_[0-9a-f]{40}\Z';
END;
$$ LANGUAGE PLPGSQL IMMUTABLE;
-- This function returns a relation of Camshaft cached analysis tables in the given schema.
-- If the schema name parameter is NULL, then tables from all schemas
-- that may contain user tables are returned.
-- For each table, the regclass, schema name and table name are returned.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_AnalysisTablesInSchema(schema_name text DEFAULT NULL)
RETURNS TABLE(table_regclass REGCLASS, schema_name TEXT, table_name TEXT)
AS $$
SELECT * FROM _CDB_UserTablesInSchema(schema_name) WHERE _CDB_IsAnalysisTableName(table_name);
$$ LANGUAGE 'sql';
-- This function returns a relation user tables excluding analysis tables
-- If the schema name parameter is NULL, then tables from all schemas
-- that may contain user tables are returned.
-- For each table, the regclass, schema name and table name are returned.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_NonAnalysisTablesInSchema(schema_name text DEFAULT NULL)
RETURNS TABLE(table_regclass REGCLASS, schema_name TEXT, table_name TEXT)
AS $$
SELECT * FROM _CDB_UserTablesInSchema(schema_name) WHERE Not _CDB_IsAnalysisTableName(table_name);
$$ LANGUAGE 'sql';
-- Total spaced used up by Camshaft cached analysis tables in the given schema.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_AnalysisDataSize(schema_name TEXT DEFAULT NULL)
RETURNS bigint AS
$$
DECLARE
total_size INT8;
BEGIN
WITH analysis_tables AS (
SELECT t.schema_name, t.table_name FROM _CDB_AnalysisTablesInSchema(schema_name) t
)
SELECT COALESCE(INT8(SUM(_CDB_total_relation_size(analysis_tables.schema_name, analysis_tables.table_name))))::int8
INTO total_size FROM analysis_tables;
IF total_size IS NOT NULL THEN
RETURN total_size;
ELSE
RETURN 0;
END IF;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;

View File

@ -0,0 +1 @@
../scripts-available/CDB_AnalysisSupport.sql

View File

@ -0,0 +1 @@
../scripts-available/CDB_AnalysisCheck.sql