跨多个过程调用缓存 getdate() 的 Redshift 问题

Posted

技术标签:

【中文标题】跨多个过程调用缓存 getdate() 的 Redshift 问题【英文标题】:Redshift problem with getdate() being cached across multiple procedure calls 【发布时间】:2021-03-09 13:34:54 【问题描述】:

我希望在执行过程时有时间戳,我使用 GETDATE() 但调用过程第二次、第三次等次,不断返回相同的时间戳,似乎 redshift 在 GETDATE() 上进行某种缓存?

OK - getdate() 外部程序,正确地不断返回不同的时间戳:

select getdate();
2021-03-09 13:03:18.0
select getdate();
2021-03-09 13:03:26.0

NOK - 现在将创建测试过程,捕获开始和结束时间戳(以及用于暂停的大 FOR 循环),并调用过程超过 1 次,我看到在第 2 次、第 3 次返回相同的开始/结束值处决等。

create or replace procedure tests.test_getdate_cache()
as $$ 
declare
    ts  timestamp;
    f   float;
begin
--    execute 'SET enable_result_cache_for_session TO OFF';
    
    ts:= getdate();
    raise info 'START - getdate()=[%]', ts;

    FOR i IN 1..10000000 LOOP
--        ts:= getdate();
--        raise info '**loop[%]  getdate()=[%]', i, ts;
        f:= i * 1234.4234;
    END LOOP;
    
    ts:= getdate();
    raise info 'END - getdate()=[%]', ts;

--    execute 'SET enable_result_cache_for_session TO ON';
end;
$$ LANGUAGE plpgsql;
/

call tests.test_getdate_cache();
START - getdate()=[2021-03-09 13:15:47]
END - getdate()=[2021-03-09 13:16:00

START - getdate()=[2021-03-09 13:15:47]       <---- DUPLICATED VALUE
END - getdate()=[2021-03-09 13:16:00]         <---- DUPLICATED VALUE

--cache results off
START - getdate()=[2021-03-09 13:23:22]
END - getdate()=[2021-03-09 13:23:34]

START - getdate()=[2021-03-09 13:23:22]       <---- DUPLICATED VALUE
END - getdate()=[2021-03-09 13:23:34]         <---- DUPLICATED VALUE


SELECT * FROM svl_stored_proc_messages WHERE 1=1 ORDER BY recordtime desc limit 4
userid | session_userid | pid   | xid     | query | recordtime          | loglevel | loglevel_text | message                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | linenum | querytxt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | label                                                                                                                                                                                                                                                                                                                            | aborted
-------+----------------+-------+---------+-------+---------------------+----------+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------
   101 |            101 | 31870 | 1540358 |  4332 | 2021-03-09 13:16:32 |       30 | INFO          | END - getdate()=[2021-03-09 13:16:00]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |      16 | call tests.test_getdate_cache()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | default                                                                                                                                                                                                                                                                                                                          |       0
   101 |            101 | 31870 | 1540358 |  4332 | 2021-03-09 13:16:19 |       30 | INFO          | START - getdate()=[2021-03-09 13:15:47]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |       7 | call tests.test_getdate_cache()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | default                                                                                                                                                                                                                                                                                                                          |       0

   101 |            101 | 31870 | 1540334 |  4325 | 2021-03-09 13:16:00 |       30 | INFO          | END - getdate()=[2021-03-09 13:16:00]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |      16 | call tests.test_getdate_cache()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | default                                                                                                                                                                                                                                                                                                                          |       0
   101 |            101 | 31870 | 1540334 |  4325 | 2021-03-09 13:15:47 |       30 | INFO          | START - getdate()=[2021-03-09 13:15:47]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |       7 | call tests.test_getdate_cache()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | default                                                                                                                                                                                                                                                                                                                          |       0
\

我什至尝试关闭结果缓存,尽管这可能仅适用于 SELECTs 而 getdate() 是函数,但是,无论如何试一试,但结果相同,时间戳保持不变。只需取消注释以上行 -- 执行 'SET enable_result_cache_for_session TO OFF'; -- 执行'SET enable_result_cache_for_session TO ON';

知道如何在程序早期以及何时退出时获得新的时间戳吗?

谢谢。

【问题讨论】:

【参考方案1】:

Getdate() 返回当前语句时间,由于存储过程调用是单个语句,它将在整个过程中返回相同的时间。见:https://docs.aws.amazon.com/redshift/latest/dg/Date_functions_header.html

我认为您尝试做的事情(可靠地)行不通。请记住,Redshift 是一个联网计算机集群,虽然它们的时钟是同步的,但这并不完美。每个节点的时钟都会略有不同,并且相互交谈的网络时间也会影响比较。您的程序不是在一个地方运行,而是在多个地方运行。您可能可以通过使用 python UDF 获得每个节点的实时信息,但随后您必须从不同的结果中找出您所看到的内容。这对于对 UDF 的单次调用可能是可行的,但是当您将该过程应用于存储在多个节点上的真实数据时,您可能会看到许多相互矛盾的答案。

【讨论】:

以上是关于跨多个过程调用缓存 getdate() 的 Redshift 问题的主要内容,如果未能解决你的问题,请参考以下文章

以克为单位跨 APP 保存数据

Linux下跨语言调用C++实践

跨多个应用程序共享存储过程

Spring 中使用redis缓存方法记录

防止跨多个服务器重复 POST API 调用

如何在 .net Core API 项目中跨多个线程限制对 HttpClient 的所有传出异步调用