This will sound weird, but i would like to solve problem without fixing the missing or corrupted chunk.
I do not maintain database, so my understanding of it is a bit vague. But from my understanding old chunks are archived on a NAS and not stored on production ssd. So it is not wanted/desired to have any functions that do check data on those old chunks duo to disk wear and slower operation.
Which will result in fixing or limiting a bunch of functions to a time frame.
While i understand that errors such as these have to be fixed, i would also like to avoid getting my function broken duo to a chunk that is not needed for function.
Bigger problem is i am trying to understand why its trying to look where it should not and how to limit it.
Time is stored as epoch in ms.
Error i get is:
ERROR: could not open file “pg_tblspc/16400/PG_14_202107181/17549/134380077”: No such file or directory
CONTEXT: PL/pgSQL assignment “temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94824 AND “timestamp” >= timestamp_from – 1209600000 AND “timestamp” <= item.timestamp ORDER BY “timestamp” DESC LIMIT 1)”
PL/pgSQL function cto_pec(bigint,bigint) line 28 at assignment
The – 1209600000 is to limit time frame to 2 weeks before selected timeframe.
The missing file is not in that time frame if i try to look in that time frame by select sentence.
The script:
CREATE OR REPLACE FUNCTION CTO_pec(timestamp_from bigint, timestamp_to bigint)
RETURNS TABLE (cas bigint, ciljna_temp decimal) AS $$
DECLARE
temperatura decimal;
item record;
last_item_temperatura decimal;
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS myTempTable(
time bigint,
ciljna_temp decimal
);
-- UNION to draw line on graph from start of graph
FOR item IN
(SELECT CAST(value AS integer), timestamp FROM kepware_messages WHERE tag_id = 94828 AND timestamp >= timestamp_from AND timestamp <= timestamp_to UNION
(SELECT CAST(value AS integer), timestamp_from AS "timestamp" FROM kepware_messages WHERE tag_id = 94828 AND
timestamp >= timestamp_from - 1209600000 AND timestamp <= timestamp_from ORDER BY "timestamp" DESC LIMIT 1))
LOOP
CASE item.value
WHEN 1 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94816 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
WHEN 2 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94818 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
WHEN 3 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94820 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
WHEN 4 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94822 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
WHEN 5 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94824 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
WHEN 6 THEN
temperatura := (SELECT value FROM kepware_messages WHERE tag_id = 94826 AND "timestamp" >= timestamp_from - 1209600000 AND "timestamp" <= item.timestamp ORDER BY "timestamp" DESC LIMIT 1);
END CASE;
last_item_temperatura := temperatura;
INSERT INTO myTempTable VALUES (item.timestamp, temperatura);
END LOOP;
INSERT INTO myTempTable VALUES (timestamp_to, last_item_temperatura);
RETURN QUERY SELECT * FROM myTempTable;
DROP TABLE IF EXISTS myTempTable;
END;
$$ LANGUAGE plpgsql;
While the following script works fine despite running in same time frame in union:
CREATE OR REPLACE FUNCTION CTO_pec(timestamp_from bigint, timestamp_to bigint)
RETURNS TABLE (cas bigint, ciljna_temp decimal) AS $$
DECLARE
temperatura decimal;
item record;
last_item_temperatura decimal;
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS myTempTable(
time bigint,
ciljna_temp decimal
);
-- UNION to draw line on graph from start of graph
FOR item IN
(SELECT CAST(value AS integer), timestamp FROM kepware_messages WHERE tag_id = 94828 AND timestamp >= timestamp_from AND timestamp <= timestamp_to UNION
(SELECT CAST(value AS integer), timestamp_from AS "timestamp" FROM kepware_messages WHERE tag_id = 94828 AND
timestamp >= timestamp_from - 1209600000 AND timestamp <= timestamp_from ORDER BY "timestamp" DESC LIMIT 1))
LOOP
last_item_temperatura := item.value;
INSERT INTO myTempTable VALUES (item.timestamp, item.value);
RAISE NOTICE '%, %', item.value, item.timestamp;
END LOOP;
INSERT INTO myTempTable VALUES (timestamp_to, last_item_temperatura);
RETURN QUERY SELECT * FROM myTempTable;
DROP TABLE IF EXISTS myTempTable;
END;
$$ LANGUAGE plpgsql;
You cannot avoid that error. If the file behind a table or index is missing, you will get an error message.
You can opt to ignore the error on the client side though.
I don’t see the point of keeping data on storage that deatroys them. Unreliable data will give unreliable query results. You might as well generrate your results randomly.