diff --git a/include/url.h b/include/url.h index c6d6737..dc3bbbb 100644 --- a/include/url.h +++ b/include/url.h @@ -19,6 +19,9 @@ std::string yezzey_block_file_path(const std::string &nspname, relnodeCoord coords, int32_t segid); std::string yezzey_block_namespace_path(int32_t segid); +std::string yezzey_block_db_file_path(const std::string &nspname, + const std::string &relname, + relnodeCoord coords, int32_t segid); /* un-prefixed version of `craftStoragePrefixedPath` */ std::string craftStorageUnPrefixedPath(const std::shared_ptr &adv, diff --git a/include/xvacuum.h b/include/xvacuum.h index fa02a52..d7b4917 100644 --- a/include/xvacuum.h +++ b/include/xvacuum.h @@ -14,5 +14,6 @@ EXTERNC int yezzey_delete_chunk_internal(const char *external_chunk_path); EXTERNC int yezzey_vacuum_garbage_internal(int segindx, bool confirm, bool crazyDrop); - +EXTERNC int yezzey_vacuum_garbage_relation_internal(Oid reloid, int segindx, bool confirm, + bool crazyDrop); #endif /* YEZZEY_XVACUUM_H */ \ No newline at end of file diff --git a/src/url.cpp b/src/url.cpp index 3446f95..f1bfc9f 100644 --- a/src/url.cpp +++ b/src/url.cpp @@ -53,7 +53,16 @@ std::string yezzey_block_file_path(const std::string &nspname, return url; } +std::string yezzey_block_db_file_path(const std::string &nspname, + const std::string &relname, + relnodeCoord coords, int32_t segid){ + std::string url = yezzey_block_namespace_path(segid); + url += std::to_string(coords.spcNode) + "_" + std::to_string(coords.dboid) + "_"; + auto md = yezzey_fqrelname_md5(nspname, relname); + url += md; + return url; +} /* prefix-independent WAL-G compatable path */ std::string craftStorageUnPrefixedPath(const std::shared_ptr &adv, ssize_t segindx, ssize_t modcount, diff --git a/src/xvacuum.cpp b/src/xvacuum.cpp index 449c099..72bc1fa 100644 --- a/src/xvacuum.cpp +++ b/src/xvacuum.cpp @@ -75,3 +75,51 @@ int yezzey_vacuum_garbage_internal(int segindx, bool confirm, bool crazyDrop) { } return 0; } +int yezzey_vacuum_garbage_relation_internal(Relation rel,int segindx, bool confirm,bool crazyDrop){ + try { + auto ioadv = std::make_shared( + std::string(gpg_engine_path), std::string(gpg_key_id), + std::string(storage_config), "", "", std::string(storage_host /*host*/), + std::string(storage_bucket /*bucket*/), + std::string(storage_prefix /*prefix*/), + std::string(storage_class /*storage_class*/), multipart_chunksize, + DEFAULTTABLESPACE_OID, "" /* coords */, InvalidOid /* reloid */, + std::string(walg_bin_path), std::string(walg_config_path), + use_gpg_crypto, yproxy_socket); + + auto tp = SearchSysCache1(NAMESPACEOID, + ObjectIdGetDatum(RelationGetNamespace(rel))); + + if (!HeapTupleIsValid(tp)) { + elog(ERROR, "yezzey: failed to get namescape name of relation %d", + RelationGetNamespace(rel)); + } + + relnodeCoord coords{1663,rel->rd_node.dbNode,rel->rd_node.relNode,segindx}; + Form_pg_namespace nsptup = (Form_pg_namespace)GETSTRUCT(tp); + auto nspname = std::string(nsptup->nspname.data); + std::string relname = RelationGetRelationName(rel); + + std::string storage_path(yezzey_block_db_file_path(nspname,relname,coords,segindx)); + + auto deleter = + std::make_shared(ioadv, ssize_t(segindx), confirm); + ReleaseSysCache(tp); + + if (deleter->deleteChunk(storage_path)) { + return 0; + } + + return -1; + } catch (...) { + elog(ERROR, "failed to prepare x-storage reader for chunk"); + return 0; + } + return 0; +} +int yezzey_vacuum_garbage_relation_internal(Oid reloid,int segindx, bool confirm, bool crazyDrop) { + Relation rel = relation_open(reloid,NoLock); + int rc = yezzey_vacuum_garbage_relation_internal(rel,segindx,confirm,crazyDrop); + relation_close(rel,NoLock); + return rc; +} diff --git a/worker.c b/worker.c index 748f4df..622e13e 100644 --- a/worker.c +++ b/worker.c @@ -477,12 +477,17 @@ yezzey_ProcessUtility_hook(Node *parsetree, #if IsGreenplum6 { VacuumStmt *stmt = (VacuumStmt *) parsetree; - if (stmt->options & VACOPT_YEZZEY) { + if(!stmt->relation){ + break; + } + Relation rel = relation_openrv(stmt->relation,NoLock); + if (stmt->options & VACOPT_YEZZEY & (rel->rd_node.spcNode == YEZZEYTABLESPACE_OID)) { if (Gp_role == GP_ROLE_EXECUTE) { Assert(GpIdentity.segindex != -1); - yezzey_vacuum_garbage_internal(GpIdentity.segindex, true, false); + yezzey_vacuum_garbage_relation_internal(rel, GpIdentity.segindex,true,false); } } + relation_close(rel,NoLock); } #endif break; diff --git a/yezzey--1.8--1.8.1.sql b/yezzey--1.8--1.8.1.sql index 83ea513..c152260 100644 --- a/yezzey--1.8--1.8.1.sql +++ b/yezzey--1.8--1.8.1.sql @@ -6,4 +6,54 @@ CREATE OR REPLACE FUNCTION yezzey_vacuum_garbage( AS 'MODULE_PATHNAME' VOLATILE EXECUTE ON ALL SEGMENTS -LANGUAGE C STRICT; \ No newline at end of file +LANGUAGE C STRICT; + +CREATE OR REPLACE FUNCTION yezzey_vacuum_relation( + reloid OID, + confirm BOOLEAN DEFAULT FALSE, + crazyDrop BOOLEAN DEFAULT FALSE +) RETURNS void +AS 'MODULE_PATHNAME' +VOLATILE +EXECUTE ON ALL SEGMENTS +LANGUAGE C STRICT; + + +CREATE OR REPLACE FUNCTION yezzey_vacuum_garbage_relation( + i_offload_nspname TEXT, + i_offload_relname TEXT, + confirm BOOLEAN DEFAULT FALSE, + crazyDrop BOOLEAN DEFAULT FALSE +) RETURNS void +AS $$ +DECLARE + v_reloid OID; +BEGIN + SELECT + oid + FROM + pg_catalog.pg_class + INTO v_reloid + WHERE + relname = i_offload_relname AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = i_offload_nspname); + + PERFORM yezzey_vacuum_relation( + v_reloid,confirm,crazyDrop + ); +END; +$$ +LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION +yezzey_vacuum_garbage_relation( + i_offload_relname TEXT, + confirm BOOLEAN DEFAULT FALSE, + crazyDrop BOOLEAN DEFAULT FALSE) +RETURNS VOID +AS $$ +BEGIN + PERFORM yezzey_vacuum_garbage_relation('public', i_offload_relname, confirm, crazyDrop); +END; +$$ +LANGUAGE PLPGSQL; \ No newline at end of file diff --git a/yezzey.c b/yezzey.c index 71fd9ce..a5d9c87 100644 --- a/yezzey.c +++ b/yezzey.c @@ -106,6 +106,7 @@ PG_FUNCTION_INFO_V1(yezzey_check_part_exr); PG_FUNCTION_INFO_V1(yezzey_delete_chunk); PG_FUNCTION_INFO_V1(yezzey_vacuum_garbage); +PG_FUNCTION_INFO_V1(yezzey_vacuum_relation); /* Create yezzey metadata tables */ @@ -123,7 +124,7 @@ int yezzey_offload_relation_internal(Oid reloid, bool remove_locally, int yezzey_delete_chunk_internal(const char *external_chunk_path); int yezzey_vacuum_garbage_internal(int segindx, bool confirm, bool crazyDrop); - +int yezzey_vacuum_garbage_relation_internal(Oid reloid,int segindx, bool confirm, bool crazyDrop); /* * yezzey_define_relation_offload_policy_internal: * do all the work with initial relation offloading @@ -430,6 +431,26 @@ Datum yezzey_vacuum_garbage(PG_FUNCTION_ARGS) { PG_RETURN_VOID(); } +Datum yezzey_vacuum_relation(PG_FUNCTION_ARGS) { + Oid reloid = PG_GETARG_OID(0); + bool confirm; + bool crazyDrop; + int rc; + confirm = PG_GETARG_BOOL(1); + crazyDrop = PG_GETARG_BOOL(2); + if (GpIdentity.segindex == -1) { + elog(ERROR, "yezzey_vacuum_garbage_internal should be executed on SEGMENT"); + } + + if (crazyDrop && !superuser()) { + elog(ERROR, "crazyDrop forbidden for non-superuser"); + } + + rc = yezzey_vacuum_garbage_relation_internal(reloid,GpIdentity.segindex,confirm,crazyDrop); + + PG_RETURN_VOID(); + +} Datum yezzey_show_relation_external_path(PG_FUNCTION_ARGS) { Oid reloid; Relation aorel;