@@ -45,7 +45,7 @@ static void *EncryptionCryptCtx = NULL;
45
45
static InternalKey EncryptionKey =
46
46
{
47
47
.type = MAP_ENTRY_EMPTY ,
48
- .start_lsn = InvalidXLogRecPtr ,
48
+ .wal_start = {. tli = 0 , . lsn = InvalidXLogRecPtr } ,
49
49
};
50
50
51
51
/*
@@ -66,7 +66,13 @@ static InternalKey EncryptionKey =
66
66
typedef struct EncryptionStateData
67
67
{
68
68
char db_map_path [MAXPGPATH ];
69
- pg_atomic_uint64 enc_key_lsn ; /* to sync with readers */
69
+
70
+ /*
71
+ * To sync with readers. We sync on LSN only and TLI here just to
72
+ * communicate its value to readers.
73
+ */
74
+ pg_atomic_uint32 enc_key_tli ;
75
+ pg_atomic_uint64 enc_key_lsn ;
70
76
} EncryptionStateData ;
71
77
72
78
static EncryptionStateData * EncryptionState = NULL ;
@@ -80,11 +86,18 @@ TDEXLogGetEncKeyLsn()
80
86
}
81
87
82
88
static void
83
- TDEXLogSetEncKeyLsn ( XLogRecPtr start_lsn )
89
+ TDEXLogSetEncKeyLocation ( WALLocation loc )
84
90
{
85
- pg_atomic_write_u64 (& EncryptionState -> enc_key_lsn , start_lsn );
91
+ pg_atomic_init_u32 (& EncryptionState -> enc_key_tli , loc .tli );
92
+ pg_atomic_write_u64 (& EncryptionState -> enc_key_lsn , loc .lsn );
86
93
}
87
94
95
+ static TimeLineID
96
+ TDEXLogGetEncKeyTli ()
97
+ {
98
+ return (TimeLineID ) pg_atomic_read_u32 (& EncryptionState -> enc_key_tli );
99
+ }
100
+
88
101
static Size TDEXLogEncryptBuffSize (void );
89
102
90
103
static int XLOGChooseNumBuffers (void );
@@ -159,6 +172,7 @@ TDEXLogShmemInit(void)
159
172
}
160
173
161
174
pg_atomic_init_u64 (& EncryptionState -> enc_key_lsn , 0 );
175
+ pg_atomic_init_u32 (& EncryptionState -> enc_key_tli , 0 );
162
176
163
177
elog (DEBUG1 , "pg_tde: initialized encryption buffer %lu bytes" , TDEXLogEncryptStateSize ());
164
178
}
@@ -168,6 +182,7 @@ TDEXLogShmemInit(void)
168
182
typedef struct EncryptionStateData
169
183
{
170
184
char db_map_path [MAXPGPATH ];
185
+ XLogRecPtr enc_key_tli ; /* to sync with reader */
171
186
XLogRecPtr enc_key_lsn ; /* to sync with reader */
172
187
} EncryptionStateData ;
173
188
@@ -184,9 +199,16 @@ TDEXLogGetEncKeyLsn()
184
199
}
185
200
186
201
static void
187
- TDEXLogSetEncKeyLsn (XLogRecPtr start_lsn )
202
+ TDEXLogSetEncKeyLocation (WALLocation loc )
203
+ {
204
+ EncryptionState -> enc_key_tli = loc .tli ;
205
+ EncryptionState -> enc_key_lsn = loc .lsn ;
206
+ }
207
+
208
+ static TimeLineID
209
+ TDEXLogGetEncKeyTli ()
188
210
{
189
- EncryptionState -> enc_key_lsn = EncryptionKey . start_lsn ;
211
+ return ( TimeLineID ) EncryptionState -> enc_key_tli ;
190
212
}
191
213
192
214
#endif /* FRONTEND */
@@ -197,6 +219,7 @@ TDEXLogSmgrInit()
197
219
SetXLogSmgr (& tde_xlog_smgr );
198
220
}
199
221
222
+ /* On backend it should be called only during the startup */
200
223
void
201
224
TDEXLogSmgrInitWrite (bool encrypt_xlog )
202
225
{
@@ -220,7 +243,7 @@ TDEXLogSmgrInitWrite(bool encrypt_xlog)
220
243
else if (key )
221
244
{
222
245
EncryptionKey = * key ;
223
- TDEXLogSetEncKeyLsn (EncryptionKey .start_lsn );
246
+ TDEXLogSetEncKeyLocation (EncryptionKey .wal_start );
224
247
}
225
248
226
249
if (key )
@@ -237,7 +260,7 @@ TDEXLogSmgrInitWriteReuseKey()
237
260
if (key )
238
261
{
239
262
EncryptionKey = * key ;
240
- TDEXLogSetEncKeyLsn (EncryptionKey .start_lsn );
263
+ TDEXLogSetEncKeyLocation (EncryptionKey .wal_start );
241
264
pfree (key );
242
265
}
243
266
@@ -260,8 +283,8 @@ TDEXLogWriteEncryptedPages(int fd, const void *buf, size_t count, off_t offset,
260
283
#endif
261
284
262
285
#ifdef TDE_XLOG_DEBUG
263
- elog (DEBUG1 , "write encrypted WAL, size: %lu, offset: %ld [%lX], seg: %X/%X, key_start_lsn: %X/%X" ,
264
- count , offset , offset , LSN_FORMAT_ARGS (segno ), LSN_FORMAT_ARGS (key -> start_lsn ));
286
+ elog (DEBUG1 , "write encrypted WAL, size: %lu, offset: %ld [%lX], seg: %X/%X, key_start_lsn: %u_% X/%X" ,
287
+ count , offset , offset , LSN_FORMAT_ARGS (segno ), key -> wal_start . tli , LSN_FORMAT_ARGS (key -> wal_start . lsn ));
265
288
#endif
266
289
267
290
CalcXLogPageIVPrefix (tli , segno , key -> base_iv , iv_prefix );
@@ -287,9 +310,10 @@ tdeheap_xlog_seg_write(int fd, const void *buf, size_t count, off_t offset,
287
310
288
311
XLogSegNoOffsetToRecPtr (segno , offset , segSize , lsn );
289
312
290
- pg_tde_wal_last_key_set_lsn (lsn , EncryptionState -> db_map_path );
291
- EncryptionKey .start_lsn = lsn ;
292
- TDEXLogSetEncKeyLsn (lsn );
313
+ pg_tde_wal_last_key_set_lsn (lsn , tli , EncryptionState -> db_map_path );
314
+ EncryptionKey .wal_start .tli = tli ;
315
+ EncryptionKey .wal_start .lsn = lsn ;
316
+ TDEXLogSetEncKeyLocation (EncryptionKey .wal_start );
293
317
}
294
318
295
319
if (EncryptionKey .type == TDE_KEY_TYPE_WAL_ENCRYPTED )
@@ -308,12 +332,12 @@ tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset,
308
332
ssize_t readsz ;
309
333
WALKeyCacheRec * keys = pg_tde_get_wal_cache_keys ();
310
334
XLogRecPtr write_key_lsn ;
311
- XLogRecPtr data_start ;
312
- XLogRecPtr data_end ;
335
+ WALLocation data_start = {. tli = tli } ;
336
+ WALLocation data_end = {. tli = tli } ;
313
337
314
338
#ifdef TDE_XLOG_DEBUG
315
- elog (DEBUG1 , "read from a WAL segment, size: %lu offset: %ld [%lX], seg: %X/%X" ,
316
- count , offset , offset , LSN_FORMAT_ARGS (segno ));
339
+ elog (DEBUG1 , "read from a WAL segment, size: %lu offset: %ld [%lX], seg: %u_% X/%X" ,
340
+ count , offset , offset , tli , LSN_FORMAT_ARGS (segno ));
317
341
#endif
318
342
319
343
readsz = pg_pread (fd , buf , count , offset );
@@ -323,30 +347,32 @@ tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset,
323
347
324
348
if (!keys )
325
349
{
350
+ WALLocation start = {.tli = 1 , .lsn = 0 };
326
351
/* cache is empty, try to read keys from disk */
327
- keys = pg_tde_fetch_wal_keys (InvalidXLogRecPtr );
352
+ keys = pg_tde_fetch_wal_keys (start );
328
353
}
329
354
330
355
write_key_lsn = TDEXLogGetEncKeyLsn ();
331
356
332
357
if (!XLogRecPtrIsInvalid (write_key_lsn ))
333
358
{
334
359
WALKeyCacheRec * last_key = pg_tde_get_last_wal_key ();
360
+ WALLocation write_loc = {.tli = TDEXLogGetEncKeyTli (), .lsn = write_key_lsn };
335
361
336
362
Assert (last_key );
337
363
338
364
/* write has generated a new key, need to fetch it */
339
- if (last_key -> start_lsn < write_key_lsn )
365
+ if (wal_location_cmp ( last_key -> start , write_loc ) < 0 )
340
366
{
341
- pg_tde_fetch_wal_keys (write_key_lsn );
367
+ pg_tde_fetch_wal_keys (write_loc );
342
368
343
369
/* in case cache was empty before */
344
370
keys = pg_tde_get_wal_cache_keys ();
345
371
}
346
372
}
347
373
348
- XLogSegNoOffsetToRecPtr (segno , offset , segSize , data_start );
349
- XLogSegNoOffsetToRecPtr (segno , offset + readsz , segSize , data_end );
374
+ XLogSegNoOffsetToRecPtr (segno , offset , segSize , data_start . lsn );
375
+ XLogSegNoOffsetToRecPtr (segno , offset + readsz , segSize , data_end . lsn );
350
376
351
377
/*
352
378
* TODO: this is higly ineffective. We should get rid of linked list and
@@ -355,24 +381,25 @@ tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset,
355
381
for (WALKeyCacheRec * curr_key = keys ; curr_key != NULL ; curr_key = curr_key -> next )
356
382
{
357
383
#ifdef TDE_XLOG_DEBUG
358
- elog (DEBUG1 , "WAL key %X/%X- %X/%X, encrypted: %s" ,
359
- LSN_FORMAT_ARGS (curr_key -> start_lsn ),
360
- LSN_FORMAT_ARGS (curr_key -> end_lsn ),
384
+ elog (DEBUG1 , "WAL key %u_% X/%X - %u_ %X/%X, encrypted: %s" ,
385
+ curr_key -> start . tli , LSN_FORMAT_ARGS (curr_key -> start . lsn ),
386
+ curr_key -> end . tli , LSN_FORMAT_ARGS (curr_key -> end . lsn ),
361
387
curr_key -> key .type == TDE_KEY_TYPE_WAL_ENCRYPTED ? "yes" : "no" );
362
388
#endif
363
389
364
- if (curr_key -> key .start_lsn != InvalidXLogRecPtr &&
390
+ if (wal_location_valid ( curr_key -> key .wal_start ) &&
365
391
curr_key -> key .type == TDE_KEY_TYPE_WAL_ENCRYPTED )
366
392
{
367
393
/*
368
394
* Check if the key's range overlaps with the buffer's and decypt
369
395
* the part that does.
370
396
*/
371
- if (data_start < curr_key -> end_lsn && data_end > curr_key -> start_lsn )
397
+
398
+ if (wal_location_cmp (data_start , curr_key -> end ) < 0 && wal_location_cmp (data_end , curr_key -> start ) > 0 )
372
399
{
373
400
char iv_prefix [16 ];
374
- off_t dec_off = XLogSegmentOffset (Max (data_start , curr_key -> start_lsn ), segSize );
375
- off_t dec_end = XLogSegmentOffset (Min (data_end , curr_key -> end_lsn ), segSize );
401
+ off_t dec_off = XLogSegmentOffset (Max (data_start . lsn , curr_key -> start . lsn ), segSize );
402
+ off_t dec_end = XLogSegmentOffset (Min (data_end . lsn , curr_key -> end . lsn ), segSize );
376
403
size_t dec_sz ;
377
404
char * dec_buf = (char * ) buf + (dec_off - offset );
378
405
@@ -389,8 +416,8 @@ tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset,
389
416
dec_sz = dec_end - dec_off ;
390
417
391
418
#ifdef TDE_XLOG_DEBUG
392
- elog (DEBUG1 , "decrypt WAL, dec_off: %lu [buff_off %lu], sz: %lu | key %X/%X" ,
393
- dec_off , dec_off - offset , dec_sz , LSN_FORMAT_ARGS ( curr_key -> key -> start_lsn ));
419
+ elog (DEBUG1 , "decrypt WAL, dec_off: %lu [buff_off %lu], sz: %lu | key %u_% X/%X" ,
420
+ dec_off , dec_off - offset , dec_sz , curr_key -> key . wal_start . tli , LSN_FORMAT_ARGS ( curr_key -> key . wal_start . lsn ));
394
421
#endif
395
422
pg_tde_stream_crypt (iv_prefix , dec_off , dec_buf , dec_sz , dec_buf ,
396
423
& curr_key -> key , & curr_key -> crypt_ctx );
0 commit comments