标簽
PostgreSQL , Linux , stat , file , atime , mtime , ctime
https://github.com/digoal/blog/blob/master/201804/20180413_01.md#%E8%83%8C%E6%99%AF 背景
PG的一些中繼資料沒有時間字段,例如對象的建立時間、DDL的修改時間。
如果要獲得這個時間資訊,我們可以
1、通過事件觸發器,将DDL事件記錄到某個中繼資料表中,來獲得。
2、或者打開DDL審計日志,從審計日志中獲得。
3、與事件觸發器類似,不過是通過PG的HOOK來實作的,在執行DDL時,通過代碼中對應的HOOK來跟蹤記錄DDL的時間。
還有沒有其他方法呢?
人民群衆的智慧是無限的,我收集了一個方法,來自PGer(智宏):
https://github.com/digoal/blog/blob/master/201804/20180413_01.md#%E9%80%9A%E8%BF%87%E6%9F%A5%E7%9C%8B%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%9B%E5%BB%BA%E6%97%B6%E9%97%B4%E8%8E%B7%E5%BE%97%E4%B8%80%E4%BA%9B%E4%BF%A1%E6%81%AF 通過檢視檔案的建立時間,獲得一些資訊
例如資料庫的建立時間。
在建立資料庫時,會在“表空間/資料庫”或“pg_tblspc/表空間/版本/資料庫”目錄中新增一個PG_VERSION檔案,新增後就不會變化。是以通過檢視這個檔案的建立時間,我們可以知道資料庫的建立時間。
stat PG_VERSION
File: ‘PG_VERSION’
Size: 3 Blocks: 8 IO Block: 4096 regular file
Device: fd11h/64785d Inode: 1315077 Links: 1
Access: (0600/-rw-------) Uid: ( 1000/ digoal) Gid: ( 1000/ digoal)
Access: 2018-04-07 17:07:02.431482742 +0800
Modify: 2018-04-07 17:07:02.431482742 +0800
Change: 2018-04-07 17:07:02.431482742 +0800
Birth: -
目錄例子:
/data01/pg/pg_root4000/pg_tblspc/28704/PG_11_201804061/28705
/data01/pg/pg_root4000/base/13220
使用SQL查詢所有資料庫的建立時間,取modification。
select
datname,
(pg_stat_file(format('%s/%s/PG_VERSION',
case
when spcname='pg_default' then 'base'
else 'pg_tblspc/'||t2.oid||'/PG_11_201804061/'
end,
t1.oid))).*
from
pg_database t1,
pg_tablespace t2
where t1.dattablespace=t2.oid;
datname | size | access | modification | change | creation | isdir
-----------+------+------------------------+------------------------+------------------------+----------+-------
postgres | 3 | 2018-04-07 17:07:05+08 | 2018-04-07 17:07:05+08 | 2018-04-07 17:07:05+08 | | f
test | 3 | 2018-04-13 16:30:08+08 | 2018-04-13 16:30:08+08 | 2018-04-13 16:30:08+08 | | f
template1 | 3 | 2018-04-07 17:07:02+08 | 2018-04-07 17:07:02+08 | 2018-04-07 17:07:02+08 | | f
template0 | 3 | 2018-04-07 17:07:05+08 | 2018-04-07 17:07:05+08 | 2018-04-07 17:07:05+08 | | f
(4 rows)
https://github.com/digoal/blog/blob/master/201804/20180413_01.md#%E8%83%8C%E6%99%AF%E7%9F%A5%E8%AF%86 背景知識
Linux offers three timestamps for files:
time of last access of contents (atime),
time of last modification of contents (mtime),
and time of last modification of the inode (metadata, ctime). 當檔案大小發生變化時,會修改INODE導緻ctime變化
The directory's mtime corresponds to the last file creation or deletion that happened, though.
The stat command may output this - (dash).
I guess it depends on the filesystem you are using.
stat calls it the "Birth time". On my ext4 fs it is empty, though.
%w Time of file birth, human-readable; - if unknown
%W Time of file birth, seconds since Epoch; 0 if unknown
stat foo.txt
File: `foo.txt'
Size: 239 Blocks: 8 IO Block: 4096 regular file
Device: 900h/2304d Inode: 121037111 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ adrian) Gid: ( 100/ users)
Access: 2011-10-26 13:57:15.000000000 -0600
Modify: 2011-10-26 13:57:15.000000000 -0600
Change: 2011-10-26 13:57:15.000000000 -0600
Birth: -
但是,它對表的建立時間是無法準确獲得的,原因如下:
1、access time,
mount atime=off
的話,不記錄atime
2、注意表在rewrite(例如truncate, 導緻rewrite的alter)後,會産生新的filenode,是以即使access time不變,也不完全準确。
3、touch檔案,會改變access time