설문조사
PostgreSQL/PPAS 관련 듣고 싶은 교육은


총 게시물 94건, 최근 0 건
   

[퀴즈]current_timestamp 와 트랜잭션

글쓴이 : PostgresDBA 날짜 : 2014-11-11 (화) 02:21 조회 : 9274
일단 아래 a.sql 을 음미해보세요.
$> cat a.sql
select now(), current_timestamp, timeofday();
select pg_sleep(1);
select now(), current_timestamp, timeofday();
begin;
select now(), current_timestamp, timeofday();
select pg_sleep(1);
select now(), current_timestamp, timeofday();
select pg_sleep(1);
select now(), current_timestamp, timeofday();
rollback;
select now(), current_timestamp, timeofday();
select pg_sleep(1);
select now(), current_timestamp, timeofday();
$> 
-- now() 와 current_timestamp 는 동의어입니다.
-- pg_sleep(1) 은 1초 만큼 쉬겠다는 의미입니다.


$> psql  -f a.sql      -- 이제 실행시켜 볼까요?
              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:07.662907+09 | 2014-11-11 02:13:07.662907+09 | Tue Nov 11 02:13:07.663760 2014 KST
(1 row)

 pg_sleep 
----------
 
(1 row)

              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:08.667238+09 | 2014-11-11 02:13:08.667238+09 | Tue Nov 11 02:13:08.667349 2014 KST
(1 row)

BEGIN
              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:08.667904+09 | 2014-11-11 02:13:08.667904+09 | Tue Nov 11 02:13:08.668357 2014 KST
(1 row)

 pg_sleep 
----------
 
(1 row)

              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:08.667904+09 | 2014-11-11 02:13:08.667904+09 | Tue Nov 11 02:13:09.671390 2014 KST
(1 row)

 pg_sleep 
----------
 
(1 row)

              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:08.667904+09 | 2014-11-11 02:13:08.667904+09 | Tue Nov 11 02:13:10.674596 2014 KST
(1 row)

ROLLBACK
              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:10.676134+09 | 2014-11-11 02:13:10.676134+09 | Tue Nov 11 02:13:10.676236 2014 KST
(1 row)

 pg_sleep 
----------
 
(1 row)

              now              |              now              |              timeofday              
-------------------------------+-------------------------------+-------------------------------------
 2014-11-11 02:13:11.679289+09 | 2014-11-11 02:13:11.679289+09 | Tue Nov 11 02:13:11.679478 2014 KST
(1 row)
$>

위 결과를 자세히 살펴보면 begin..rollback; 트랜젹션 구간의 now() 와 current_timestamp 값은 
이상하게도 값이 변하지 않고 있습니다. timeofday() 만 변하고 있네요.

now()/current_timestamp 는 단순히 현재의 시각을 반환하는 함수가 아닌거 같네요.
일반적인 오라클의 sysdate 와 다른 개념 인가봅니다.
그럼 무슨 시간을 의미하는걸까요? 

퀴즈입니다!

cloudy 2014-11-13 (목) 09:06
해당 함수들은 트랜잭션이 시작되는 시간을 그대로 유지합니다
한 트랜잭션내에서 실제 입력이나 변화되는 시간을 찍고 싶으면 clock_timestamp를 사용하면 되는것으로 알고 있습니다
댓글주소
     
     
PostgresDBA 2014-11-13 (목) 14:42
정답입니다.
댓글주소
주킹 2014-11-13 (목) 10:13
많은 도움주셔서 감사합니다.

http://www.postgresql.org/docs/current/static/functions-datetime.html
메뉴얼과 같이 변하지 않는 함수는 현재 transaction이 시작하였을 경우의 시간을 나타냅니다.
clock_timestamp와 timeofday()는 구문이 시작한 시간을 나타내주는 함수 입니다.
그런데 제가 동일하게 test하고

begin

select current_time,current_timestamp,localtimestamp,now(),timeofday(),clock_timestamp();


 
      timetz      |      current_timestamp      |      localtimestamp      |              now              |            timeofday              |        clock_timestamp       
-------------------+-------------------------------+----------------------------+-------------------------------+------------------------------------+-------------------------------
09:48:15.340608+09 | 2014-11-13 09:48:21.815818+09 | 2014-11-13 09:48:21.816782 | 2014-11-13 09:48:15.340608+09 | hu No  13 09:48:21.816795 2014 KST | 2014-11-13 09:48:21.816815+09


      timetz      |      current_timestamp      |      localtimestamp      |              now              |            timeofday              |        clock_timestamp       
--------------------+-------------------------------+----------------------------+-------------------------------+------------------------------------+-------------------------------
 09:48:15.340608+09 | 2014-11-13 09:49:58.092839+09 | 2014-11-13 09:49:58.093148 | 2014-11-13 09:48:15.340608+09 |Thu Nov 13 09:49:58.093153 2014 KST | 2014-11-13 09:49:58.093167+09
(1 row)


      timetz      |      current_timestamp      |      localtimestamp      |              now              |            timeofday              |        clock_timestamp       
--------------------+-------------------------------+----------------------------+-------------------------------+------------------------------------+-------------------------------
 09:48:15.340608+09 | 2014-11-13 09:51:29.864818+09 | 2014-11-13 09:51:29.865112 | 2014-11-13 09:48:15.340608+09 |Thu Nov 13 09:51:29.865118 2014 KST | 2014-11-13 09:51:29.865132+09

begin후에 임의로 했을 경우에도 PPAS 9.3.5,PPAS9.3.1에서 current_timestamp에서도 변하는 것을 확인하였습니다.

혹시 방법이 잘못된 건지...linux환경에서 동일하게 script 수행해도 변하네요 ..
댓글주소
cloudy 2014-11-13 (목) 11:12
PPAS 9.3 버전의 bug으로 보여집니다. postgres 9.3에서는 메뉴얼대로 current_timestamp는 Current date and time (start of current transaction); 이게 맞습니다
edb=# select current_timestamp,now() ;
-[ RECORD 1 ]-----+---------------------------------
current_timestamp | 13-NOV-14 11:10:53.721237 +09:00
now              | 13-NOV-14 11:00:40.948158 +09:00

edb=# select current_timestamp,now() ;
-[ RECORD 1 ]-----+---------------------------------
current_timestamp | 13-NOV-14 11:10:55.627184 +09:00
now              | 13-NOV-14 11:00:40.948158 +09:00

postgres=# select current_timestamp,now() ;
-[ RECORD 1 ]----------------------
now | 2014-11-13 11:09:47.657242+09
now | 2014-11-13 11:09:47.657242+09

postgres=# select current_timestamp,now() ;
-[ RECORD 1 ]----------------------
now | 2014-11-13 11:09:47.657242+09
now | 2014-11-13 11:09:47.657242+09
댓글주소
cloudy 2014-11-13 (목) 11:35
PPAS 9.2에서도 동일 현상이네요.. EDB쪽에 bug report를 해야겠습니다
댓글주소
cloudy 2014-11-13 (목) 12:50
아 죄송합니다.
PPAS가 의도적으로 이렇게 만든듯 보여집니다
oracle compatiblility 내용을 보면
CURRENT_TIMESTAMP returns the current date and time. When called from a single SQL statement,
it will return the same value for each occurrence within the statement.
If called from multiple statements within a transaction, may return different values for each occurrence.
If called from a function, may return a different value than the value returned by current_timestamp in the caller
위와 같은 내용이 나옵니다
아래와 같이 단일 쿼리문으로 insert를 하는 경우 current_timestamp는 변동이 없는게 확인 됩니다.
edb=# insert into test values (generate_series(1,10), now(),current_timestamp,clock_timestamp());
INSERT 0 10
edb=# select * from test;                                                                       
-[ RECORD 1 ]-----------------------
a | 1
b | 13-NOV-14 11:52:37.137223 +09:00
c | 13-NOV-14 11:52:37.137223 +09:00
d | 13-NOV-14 11:52:37.137649 +09:00
-[ RECORD 2 ]-----------------------
a | 2
b | 13-NOV-14 11:52:37.137223 +09:00
c | 13-NOV-14 11:52:37.137223 +09:00
d | 13-NOV-14 11:52:37.137652 +09:00
-[ RECORD 3 ]-----------------------
a | 3
b | 13-NOV-14 11:52:37.137223 +09:00
c | 13-NOV-14 11:52:37.137223 +09:00
d | 13-NOV-14 11:52:37.137653 +09:00
댓글주소
PostgresDBA 2014-11-13 (목) 14:42
PPAS 는 다르군요. 좋은걸 배웠습니다.
댓글주소
   

postgresdba.com