作者
digoal
日期
2021-02-15
标签
PostgreSQL , old_snapshot
背景
pg_old_snapshot_time_mapping函数输出OldSnapshotTimeMapping结构内容, 每分钟一条, 有限存储(取决于old_snapshot_threshold参数的设置, 如果设置为2小时, 那么就是120条), 存储空间循环使用.
每分钟1条, 每1条的含义:
- 时间戳,
- 对应的 newest xmin (最新的已提交事务号).
当需要触发oldest snapshot conflict时, 流程大致如下:
- 1、垃圾回收 遇上某 dead tuple xmax id > 某个未结束事务, 原则上无法vacuum回收这条垃圾tuple,
- 2、如果设置了old_snapshot_threshold,
- 3、如果这个未结束事务 的xid < OldSnapshotTimeMapping结构中最早的一条newest xmin
- 4、并且OldSnapshotTimeMapping结构中最早的这条时间戳, 距离当前时间已经大于 old_snapshot_threshold参数
- 5、触发oldest snapshot conflict, 这个事务被回滚, 垃圾tuple也可以被回收.
参考:
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=contrib/old_snapshot/time_mapping.c;h=3df07177ed66151719ed51101637baa32e5709d3;hb=9e596b65f430fcb942685b41860b323398a88873
https://www.postgresql.org/docs/devel/oldsnapshot.html
The old_snapshot module allows inspection of the server state that is used to implement old_snapshot_threshold.
pg_old_snapshot_time_mapping(array_offset OUT int4, end_timestamp OUT timestamptz, newest_xmin OUT xid) returns setof record
Returns all of the entries in the server's timestamp to XID mapping. Each entry represents the newest xmin of any snapshot taken in the corresponding minute.
124 /*
125 * Convert one entry from the old snapshot time mapping to a HeapTuple.
126 */
127 static HeapTuple
128 MakeOldSnapshotTimeMappingTuple(TupleDesc tupdesc, OldSnapshotTimeMapping *mapping)
129 {
130 Datum values[NUM_TIME_MAPPING_COLUMNS];
131 bool nulls[NUM_TIME_MAPPING_COLUMNS];
132 int array_position;
133 TimestampTz timestamp;
134
135 /*
136 * Figure out the array position corresponding to the current index.
137 *
138 * Index 0 means the oldest entry in the mapping, which is stored at
139 * mapping->head_offset. Index 1 means the next-oldest entry, which is a the
140 * following index, and so on. We wrap around when we reach the end of the array.
141 */
142 array_position = (mapping->head_offset + mapping->current_index)
143 % OLD_SNAPSHOT_TIME_MAP_ENTRIES;
144
145 /*
146 * No explicit timestamp is stored for any entry other than the oldest one,
147 * but each entry corresponds to 1-minute period, so we can just add.
148 */
149 timestamp = TimestampTzPlusMilliseconds(mapping->head_timestamp,
150 mapping->current_index * 60000);
151
152 /* Initialize nulls and values arrays. */
153 memset(nulls, 0, sizeof(nulls));
154 values[0] = Int32GetDatum(array_position);
155 values[1] = TimestampTzGetDatum(timestamp);
156 values[2] = TransactionIdGetDatum(mapping->xid_by_minute[array_position]);
157
158 return heap_form_tuple(tupdesc, values, nulls);
159 }
PostgreSQL 许愿链接
您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.
9.9元购买3个月阿里云RDS PostgreSQL实例
PostgreSQL 解决方案集合
德哥 / digoal's github - 公益是一辈子的事.





