Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move pg_tde files to one dir inside PGDATA #349

Merged
merged 4 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ if get_variable('percona_ext', false)
'trigger_on_view',
'change_access_method',
'insert_update_delete',
# 'tablespace',
'tablespace',
'vault_v2_test',
'alter_index',
'merge_join',
Expand Down
110 changes: 29 additions & 81 deletions src/access/pg_tde_tdemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@
}
#endif

#define PG_TDE_MAP_FILENAME "pg_tde.map"
#define PG_TDE_KEYDATA_FILENAME "pg_tde.dat"

#define PG_TDE_FILEMAGIC 0x01454454 /* version ID value = TDE 01 */


Expand Down Expand Up @@ -163,7 +160,7 @@ pg_tde_create_key_map_entry(const RelFileLocator *newrlocator, uint32 entry_type
LWLock *lock_pk = tde_lwlock_enc_keys();

LWLockAcquire(lock_pk, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(newrlocator->dbOid, newrlocator->spcOid, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(newrlocator->dbOid, LW_EXCLUSIVE);
if (principal_key == NULL)
{
LWLockRelease(lock_pk);
Expand All @@ -190,7 +187,7 @@ pg_tde_create_key_map_entry(const RelFileLocator *newrlocator, uint32 entry_type

/* Encrypt the key */
rel_key_data = tde_create_rel_key(newrlocator->relNumber, &int_key, &principal_key->keyInfo);
enc_rel_key_data = tde_encrypt_rel_key(principal_key, rel_key_data, newrlocator);
enc_rel_key_data = tde_encrypt_rel_key(principal_key, rel_key_data, newrlocator->dbOid);

/*
* XLOG internal key
Expand Down Expand Up @@ -244,12 +241,12 @@ tde_create_rel_key(RelFileNumber rel_num, InternalKey *key, TDEPrincipalKeyInfo
* Encrypts a given key and returns the encrypted one.
*/
RelKeyData *
tde_encrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *rel_key_data, const RelFileLocator *rlocator)
tde_encrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *rel_key_data, Oid dbOid)
{
RelKeyData *enc_rel_key_data;
size_t enc_key_bytes;

AesEncryptKey(principal_key, rlocator, rel_key_data, &enc_rel_key_data, &enc_key_bytes);
AesEncryptKey(principal_key, dbOid, rel_key_data, &enc_rel_key_data, &enc_key_bytes);

return enc_rel_key_data;
}
Expand All @@ -259,13 +256,13 @@ tde_encrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *rel_key_data, co
* Returns true if both map and key data files are created.
*/
void
pg_tde_delete_tde_files(Oid dbOid, Oid spcOid)
pg_tde_delete_tde_files(Oid dbOid)
{
char db_map_path[MAXPGPATH] = {0};
char db_keydata_path[MAXPGPATH] = {0};

/* Set the file paths */
pg_tde_set_db_file_paths(dbOid, spcOid, db_map_path, db_keydata_path);
pg_tde_set_db_file_paths(dbOid, db_map_path, db_keydata_path);

/* Remove these files without emitting any error */
PathNameDeleteTemporaryFile(db_map_path, false);
Expand Down Expand Up @@ -294,7 +291,6 @@ pg_tde_save_principal_key(TDEPrincipalKeyInfo *principal_key_info)

/* Set the file paths */
pg_tde_set_db_file_paths(principal_key_info->databaseId,
principal_key_info->tablespaceId,
db_map_path, db_keydata_path);

ereport(LOG, (errmsg("pg_tde_save_principal_key")));
Expand Down Expand Up @@ -434,7 +430,7 @@ pg_tde_write_one_map_entry(int fd, const RelFileLocator *rlocator, uint32 flags,
{
char db_map_path[MAXPGPATH] = {0};

pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL);
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not write tde map file \"%s\": %m",
Expand All @@ -444,7 +440,7 @@ pg_tde_write_one_map_entry(int fd, const RelFileLocator *rlocator, uint32 flags,
{
char db_map_path[MAXPGPATH] = {0};

pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL);
ereport(data_sync_elevel(ERROR),
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", db_map_path)));
Expand Down Expand Up @@ -525,7 +521,7 @@ pg_tde_write_key_map_entry(const RelFileLocator *rlocator, RelKeyData *enc_rel_k
Assert(rlocator);

/* Set the file paths */
pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path);

/* Create the map entry and then add the encrypted key to the data file */
key_index = pg_tde_write_map_entry(rlocator, enc_rel_key_data->internal_key.rel_type, db_map_path, principal_key_info);
Expand All @@ -550,7 +546,7 @@ pg_tde_delete_key_map_entry(const RelFileLocator *rlocator, uint32 key_type)
Assert(rlocator);

/* Get the file paths */
pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path);

errno = 0;
/* Remove the map entry if found */
Expand Down Expand Up @@ -596,7 +592,7 @@ pg_tde_free_key_map_entry(const RelFileLocator *rlocator, uint32 key_type, off_t
Assert(rlocator);

/* Get the file paths */
pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL);

/* Remove the map entry if found */
key_index = pg_tde_process_map_entry(rlocator, key_type, db_map_path, &offset, true);
Expand All @@ -610,17 +606,6 @@ pg_tde_free_key_map_entry(const RelFileLocator *rlocator, uint32 key_type, off_t
db_map_path)));

}
/*
* Remove TDE files it was the last TDE relation in a custom tablespace.
* DROP TABLESPACE needs an empty dir.
*/
if (rlocator->spcOid != GLOBALTABLESPACE_OID &&
rlocator->spcOid != DEFAULTTABLESPACE_OID &&
pg_tde_process_map_entry(NULL, key_type, db_map_path, &start, false) == -1)
{
pg_tde_delete_tde_files(rlocator->dbOid, rlocator->spcOid);
cleanup_key_provider_info(rlocator->dbOid, rlocator->spcOid);
}
}

/*
Expand Down Expand Up @@ -689,7 +674,6 @@ pg_tde_perform_rotate_key(TDEPrincipalKey *principal_key, TDEPrincipalKey *new_p

/* Set the file paths */
pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId,
principal_key->keyInfo.tablespaceId,
db_map_path, db_keydata_path);

/*
Expand Down Expand Up @@ -729,14 +713,13 @@ pg_tde_perform_rotate_key(TDEPrincipalKey *principal_key, TDEPrincipalKey *new_p

rloc.relNumber = read_map_entry.relNumber;
rloc.dbOid = principal_key->keyInfo.databaseId;
rloc.spcOid = principal_key->keyInfo.tablespaceId;

/* Let's get the decrypted key and re-encrypt it with the new key. */
enc_rel_key_data[OLD_PRINCIPAL_KEY] = pg_tde_read_one_keydata(k_fd[OLD_PRINCIPAL_KEY], key_index[OLD_PRINCIPAL_KEY], principal_key);

/* Decrypt and re-encrypt keys */
rel_key_data[OLD_PRINCIPAL_KEY] = tde_decrypt_rel_key(principal_key, enc_rel_key_data[OLD_PRINCIPAL_KEY], &rloc);
enc_rel_key_data[NEW_PRINCIPAL_KEY] = tde_encrypt_rel_key(new_principal_key, rel_key_data[OLD_PRINCIPAL_KEY], &rloc);
rel_key_data[OLD_PRINCIPAL_KEY] = tde_decrypt_rel_key(principal_key, enc_rel_key_data[OLD_PRINCIPAL_KEY], principal_key->keyInfo.databaseId);
enc_rel_key_data[NEW_PRINCIPAL_KEY] = tde_encrypt_rel_key(new_principal_key, rel_key_data[OLD_PRINCIPAL_KEY], principal_key->keyInfo.databaseId);

/* Write the given entry at the location pointed by prev_pos */
prev_pos[NEW_PRINCIPAL_KEY] = curr_pos[NEW_PRINCIPAL_KEY];
Expand Down Expand Up @@ -814,7 +797,6 @@ pg_tde_write_map_keydata_files(off_t map_size, char *m_file_data, off_t keydata_

/* Set the file paths */
pg_tde_set_db_file_paths(fheader->principal_key_info.databaseId,
fheader->principal_key_info.tablespaceId,
db_map_path, db_keydata_path);

/* Initialize the new files and set the names */
Expand Down Expand Up @@ -870,10 +852,7 @@ pg_tde_write_map_keydata_files(off_t map_size, char *m_file_data, off_t keydata_
}

/*
* Move relation's key to the new physical location and cache it with the new
* relfilenode. It recreates *.map and *.dat files with the old principal key
* and re-encrypted with the new relfilenode internal key. And copies the
* old keyring to the new location.
* Saves the relation key with the new relfilenode.
* Needed by ALTER TABLE SET TABLESPACE for example.
*/
bool
Expand All @@ -890,40 +869,21 @@ pg_tde_move_rel_key(const RelFileLocator *newrlocator, const RelFileLocator *old
off_t offset = 0;
int32 key_index = 0;

pg_tde_set_db_file_paths(oldrlocator->dbOid, oldrlocator->spcOid, db_map_path, db_keydata_path);
pg_tde_set_db_file_paths(oldrlocator->dbOid, db_map_path, db_keydata_path);

LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE);

principal_key = GetPrincipalKey(oldrlocator->dbOid, oldrlocator->spcOid, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(oldrlocator->dbOid, LW_EXCLUSIVE);
Assert(principal_key);

/*
* Copy kering provider info.
*
* TODO: we can potentially avoid moving keyring and key tde files keeping
* these files always in dbOid+MyDatabaseTableSpace path. But the
* background writer isn't aware of MyDatabaseTableSpace hence it won't
* work with SMGR -> tde_heap. Revisit this after chages in SMGR (mdcreate)
* interface.
/*
* We don't use internal_key cache to avoid locking complications.
*/
keyring = GetKeyProviderByID(principal_key->keyInfo.keyringId, oldrlocator->dbOid, oldrlocator->spcOid);
Assert(keyring);
memcpy(provider_rec.provider_name, keyring->provider_name, sizeof(keyring->provider_name));
provider_rec.provider_type = keyring->type;
memcpy(provider_rec.options, keyring->options, sizeof(keyring->options));
copy_key_provider_info(&provider_rec, newrlocator->dbOid, newrlocator->spcOid, true);

principal_key->keyInfo.keyringId = provider_rec.provider_id;

key_index = pg_tde_process_map_entry(oldrlocator, MAP_ENTRY_VALID, db_map_path, &offset, false);
Assert(key_index != -1);
/*
* Re-encrypt relation key. We don't use internal_key cache to avoid locking
* complications.
*/

enc_key = pg_tde_read_keydata(db_keydata_path, key_index, principal_key);
rel_key = tde_decrypt_rel_key(principal_key, enc_key, oldrlocator);
enc_key = tde_encrypt_rel_key(principal_key, rel_key, newrlocator);
rel_key = tde_decrypt_rel_key(principal_key, enc_key, oldrlocator->dbOid);

xlrec.rlocator = *newrlocator;
xlrec.relKey = *enc_key;
Expand Down Expand Up @@ -983,7 +943,7 @@ pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool n
* key.
*/
LWLockAcquire(lock_pk, LW_SHARED);
principal_key = GetPrincipalKey(rlocator->dbOid, rlocator->spcOid, LW_SHARED);
principal_key = GetPrincipalKey(rlocator->dbOid, LW_SHARED);
if (principal_key == NULL)
{
LWLockRelease(lock_pk);
Expand All @@ -992,7 +952,7 @@ pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool n
}

/* Get the file paths */
pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path);
pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path);

if (no_map_ok && access(db_map_path, F_OK) == -1)
{
Expand All @@ -1011,23 +971,11 @@ pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool n
enc_rel_key_data = pg_tde_read_keydata(db_keydata_path, key_index, principal_key);
LWLockRelease(lock_pk);

rel_key_data = tde_decrypt_rel_key(principal_key, enc_rel_key_data, rlocator);
rel_key_data = tde_decrypt_rel_key(principal_key, enc_rel_key_data, rlocator->dbOid);

return rel_key_data;
}

inline void
pg_tde_set_db_file_paths(Oid dbOid, Oid spcOid, char *map_path, char *keydata_path)
{
char *db_path = pg_tde_get_tde_file_dir(dbOid, spcOid);

if (map_path)
join_path_components(map_path, db_path, PG_TDE_MAP_FILENAME);
if (keydata_path)
join_path_components(keydata_path, db_path, PG_TDE_KEYDATA_FILENAME);
pfree(db_path);
}

/*
* Returns the index of the read map if we find a valid match; i.e.
* - flags is set to MAP_ENTRY_VALID and the relNumber matches the one
Expand Down Expand Up @@ -1147,12 +1095,12 @@ pg_tde_read_keydata(char *db_keydata_path, int32 key_index, TDEPrincipalKey *pri
* Decrypts a given key and returns the decrypted one.
*/
RelKeyData *
tde_decrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *enc_rel_key_data, const RelFileLocator *rlocator)
tde_decrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *enc_rel_key_data, Oid dbOid)
{
RelKeyData *rel_key_data = NULL;
size_t key_bytes;

AesDecryptKey(principal_key, rlocator, &rel_key_data, enc_rel_key_data, &key_bytes);
AesDecryptKey(principal_key, dbOid, &rel_key_data, enc_rel_key_data, &key_bytes);

return rel_key_data;
}
Expand Down Expand Up @@ -1321,7 +1269,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi
{
char db_keydata_path[MAXPGPATH] = {0};

pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, principal_key->keyInfo.tablespaceId, NULL, db_keydata_path);
pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, NULL, db_keydata_path);
ereport(FATAL,
(errcode(ERRCODE_NO_DATA_FOUND),
errmsg("could not find the required key at index %d in tde data file \"%s\": %m",
Expand All @@ -1335,7 +1283,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi
{
char db_keydata_path[MAXPGPATH] = {0};

pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, principal_key->keyInfo.tablespaceId, NULL, db_keydata_path);
pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, NULL, db_keydata_path);
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not read key at index %d in tde key data file \"%s\": %m",
Expand All @@ -1352,7 +1300,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi
* a LW_SHARED or higher lock on files before calling this function.
*/
TDEPrincipalKeyInfo *
pg_tde_get_principal_key_info(Oid dbOid, Oid spcOid)
pg_tde_get_principal_key_info(Oid dbOid)
{
int fd = -1;
TDEFileHeader fheader;
Expand All @@ -1362,7 +1310,7 @@ pg_tde_get_principal_key_info(Oid dbOid, Oid spcOid)
char db_map_path[MAXPGPATH] = {0};

/* Set the file paths */
pg_tde_set_db_file_paths(dbOid, spcOid, db_map_path, NULL);
pg_tde_set_db_file_paths(dbOid, db_map_path, NULL);

/*
* Ensuring that we always open the file in binary mode. The caller must
Expand Down
5 changes: 2 additions & 3 deletions src/access/pg_tde_xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "catalog/pg_tablespace_d.h"
#include "catalog/tde_keyring.h"
#include "storage/bufmgr.h"
#include "storage/shmem.h"
Expand Down Expand Up @@ -108,13 +107,13 @@ tdeheap_rmgr_desc(StringInfo buf, XLogReaderState *record)
{
TDEPrincipalKeyInfo *xlrec = (TDEPrincipalKeyInfo *) XLogRecGetData(record);

appendStringInfo(buf, "add tde principal key for db %u/%u", xlrec->databaseId, xlrec->tablespaceId);
appendStringInfo(buf, "add tde principal key for db %u", xlrec->databaseId);
}
if (info == XLOG_TDE_EXTENSION_INSTALL_KEY)
{
XLogExtensionInstall *xlrec = (XLogExtensionInstall *) XLogRecGetData(record);

appendStringInfo(buf, "tde extension install for db %u/%u", xlrec->database_id, xlrec->tablespace_id);
appendStringInfo(buf, "tde extension install for db %u", xlrec->database_id);
}
if (info == XLOG_TDE_ROTATE_KEY)
{
Expand Down
1 change: 0 additions & 1 deletion src/access/pg_tde_xlog_encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "catalog/pg_tablespace_d.h"
#include "storage/bufmgr.h"
#include "storage/shmem.h"
#include "utils/guc.h"
Expand Down
Loading
Loading