diff --git a/src/common/backend/catalog/storage.cpp b/src/common/backend/catalog/storage.cpp index bc238184c44b546b915ce9dbb7bca049c486e2d3..7cfee3b19b849f135964adf262f6fd6ccc716fd2 100644 --- a/src/common/backend/catalog/storage.cpp +++ b/src/common/backend/catalog/storage.cpp @@ -1028,6 +1028,10 @@ void smgrDoPendingDeletes(bool isCommit) u_sess->catalog_cxt.pendingDeletes = next; /* do deletion if called for */ if (pending->atCommit == isCommit) { + if (IS_COMPRESS_DELETE_FORK(pending->forknum)) { + SET_OPT_BY_NEGATIVE_FORK(pending->relnode, pending->forknum); + pending->forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(pending->forknum)) { RowRelationDoDeleteFiles( pending->relnode, pending->backend, pending->ownerid, pending->relOid, isCommit); @@ -1144,7 +1148,11 @@ int smgrGetPendingDeletes(bool forCommit, ColFileNodeRel** ptr, bool skipTemp, i rptrRel->filenode.spcNode = pending->relnode.spcNode; rptrRel->filenode.dbNode = pending->relnode.dbNode; rptrRel->filenode.relNode = pending->relnode.relNode; - rptrRel->forknum = pending->forknum; + if (IS_COMPRESSED_RNODE(pending->relnode, pending->forknum)) { + rptrRel->forknum = COMPRESS_FORKNUM; + } else { + rptrRel->forknum = pending->forknum; + } rptrRel->ownerid = pending->ownerid; /* Add bucketid into forknum */ forknum_add_bucketid(rptrRel->forknum, pending->relnode.bucketNode); diff --git a/src/gausskernel/optimizer/commands/indexcmds.cpp b/src/gausskernel/optimizer/commands/indexcmds.cpp index 8021a8c4890a9126f1a570e95714eb23bd0e5cec..6e735dccb17f507a536581212b21d43b17233dbf 100644 --- a/src/gausskernel/optimizer/commands/indexcmds.cpp +++ b/src/gausskernel/optimizer/commands/indexcmds.cpp @@ -1077,8 +1077,6 @@ Oid DefineIndex(Oid relationId, IndexStmt* stmt, Oid indexRelationId, bool is_al } } } - - CheckCompressOption(&indexCreateSupport); /* * Parse AM-specific options, convert to text array form, validate. */ diff --git a/src/gausskernel/storage/access/redo/redo_xlogutils.cpp b/src/gausskernel/storage/access/redo/redo_xlogutils.cpp index 6532996d3734b1cb1bafc4643b2fe3dea9841773..815f5d7da0e41b966150a66773ca72afb8f097fd 100644 --- a/src/gausskernel/storage/access/redo/redo_xlogutils.cpp +++ b/src/gausskernel/storage/access/redo/redo_xlogutils.cpp @@ -1531,6 +1531,10 @@ void XLogBlockDdlDoSmgrAction(XLogBlockHead *blockhead, void *blockrecbody, Redo ColFileNodeRel *colFileNodeRel = xnodes + i; ColFileNode colFileNode; ColFileNodeCopy(&colFileNode, colFileNodeRel); + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(colFileNode.forknum)) { XlogDropRowReation(colFileNode.filenode); } diff --git a/src/gausskernel/storage/access/transam/cbmparsexlog.cpp b/src/gausskernel/storage/access/transam/cbmparsexlog.cpp index 98f31e6a265cbe88811b18afc8c95050d46fed1b..aa6b2cf2ca272b9c245891be327fe940490106a7 100644 --- a/src/gausskernel/storage/access/transam/cbmparsexlog.cpp +++ b/src/gausskernel/storage/access/transam/cbmparsexlog.cpp @@ -1172,6 +1172,12 @@ static void TrackRelStorageDrop(XLogReaderState *record) ColFileNodeCopy(&colFileNodeData, colFileNodeRel); + /* set opt to compressOpt if FORKNUM is compress forknum */ + if (IS_COMPRESS_DELETE_FORK(colFileNodeData.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNodeData.filenode, colFileNodeData.forknum); + colFileNodeData.forknum = MAIN_FORKNUM; + } + /* Logic relfilenode delete is ignored */ if (IsSegmentFileNode(colFileNodeData.filenode)) { continue; diff --git a/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp b/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp index f8bddd3292c8c40a02c85c3037b3dc6fe6f39e76..9390c7f10ce1a1f144da70df1215b5af76cf5094 100644 --- a/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp +++ b/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp @@ -220,6 +220,12 @@ void PRTrackDropFiles(HTAB *redoItemHash, XLogBlockDdlParse *ddlParse, XLogRecPt ColFileNode colFileNode; ColFileNodeRel *colFileNodeRel = xnodes + i; ColFileNodeCopy(&colFileNode, colFileNodeRel); + + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } + if (!IsValidColForkNum(colFileNode.forknum)) { for (int i = 0; i < MAX_FORKNUM; ++i) PRTrackRelTruncate(redoItemHash, colFileNode.filenode, i, 0); diff --git a/src/gausskernel/storage/access/transam/twophase.cpp b/src/gausskernel/storage/access/transam/twophase.cpp index 5463b3cef7bf3e28b88fe53e3520949312dc5386..b3f169b973655d1518a19744405655c616b23ea9 100644 --- a/src/gausskernel/storage/access/transam/twophase.cpp +++ b/src/gausskernel/storage/access/transam/twophase.cpp @@ -2612,6 +2612,10 @@ void FinishPreparedTransaction(const char *gid, bool isCommit) ColFileNodeCopy(&colFileNode, colFileNodeRel); + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(colFileNode.forknum)) { RowRelationDoDeleteFiles(colFileNode.filenode, InvalidBackendId, colFileNode.ownerid); } else { diff --git a/src/gausskernel/storage/access/transam/xact.cpp b/src/gausskernel/storage/access/transam/xact.cpp index e78f94dd113a4e0b0ab9ea7f97cc93c4f773157b..5bfd2a1a1c7a3b1da50556a3a271d282ddb28d66 100755 --- a/src/gausskernel/storage/access/transam/xact.cpp +++ b/src/gausskernel/storage/access/transam/xact.cpp @@ -7167,6 +7167,10 @@ void push_unlink_rel_to_hashtbl(ColFileNodeRel *xnodes, int nrels) DelFileTag *entry = NULL; ColFileNodeCopy(&colFileNode, colFileNodeRel); + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(colFileNode.forknum) && !IsSegmentFileNode(colFileNode.filenode)) { entry = (DelFileTag*)hash_search(relfilenode_hashtbl, &(colFileNode.filenode), HASH_ENTER, &found); if (!found) { @@ -7212,7 +7216,10 @@ static void unlink_relfiles(_in_ ColFileNodeRel *xnodes, _in_ int nrels) ColFileNodeRel *colFileNodeRel = xnodes + i; ColFileNodeCopy(&colFileNode, colFileNodeRel); - + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(colFileNode.forknum)) { RelFileNode relFileNode = colFileNode.filenode; ForkNumber fork; @@ -7815,6 +7822,10 @@ void xactApplyXLogDropRelation(XLogReaderState *record) ColFileNodeRel *nodeRel = xnodes + i; ColFileNodeCopy(&node, nodeRel); + if (IS_COMPRESS_DELETE_FORK(node.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(node.filenode, node.forknum); + node.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(node.forknum)) { for (int fork = 0; fork <= MAX_FORKNUM; fork++) XLogDropRelation(node.filenode, fork); diff --git a/src/gausskernel/storage/access/transam/xlogutils.cpp b/src/gausskernel/storage/access/transam/xlogutils.cpp index 5ef16804467641d8dedc4a468e9632b03ba4ebb2..7559336e2e1ef31bf8287c12dd8ea3c761a8e4b7 100644 --- a/src/gausskernel/storage/access/transam/xlogutils.cpp +++ b/src/gausskernel/storage/access/transam/xlogutils.cpp @@ -1321,6 +1321,10 @@ void XLogForgetDDLRedo(XLogRecParseState *redoblockstate) ColFileNodeRel *colFileNodeRel = xnodes + i; ColFileNode colFileNode; ColFileNodeCopy(&colFileNode, colFileNodeRel); + if (IS_COMPRESS_DELETE_FORK(colFileNode.forknum)) { + SET_OPT_BY_NEGATIVE_FORK(colFileNode.filenode, colFileNode.forknum); + colFileNode.forknum = MAIN_FORKNUM; + } if (!IsValidColForkNum(colFileNode.forknum)) { XlogDropRowReation(colFileNode.filenode); } diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp index 2b73fb32a48ca4707646257c7c05a0cf48dbffaa..1f384f92bae115eb4f375660ad0bf23472000e82 100644 --- a/src/gausskernel/storage/buffer/bufmgr.cpp +++ b/src/gausskernel/storage/buffer/bufmgr.cpp @@ -6535,7 +6535,7 @@ int ckpt_buforder_comparator(const void *pa, const void *pb) } else { /* should not be the same block ... */ return 1; } - /* do not need to compare opt */ + /* do not need to compare opt */ } /* diff --git a/src/include/storage/page_compression.h b/src/include/storage/page_compression.h index 5a181d1a44c578ab1c6f4c78490e4beac18cd78a..645ba11efb874d963247e508230336c100f7f271 100644 --- a/src/include/storage/page_compression.h +++ b/src/include/storage/page_compression.h @@ -212,24 +212,25 @@ inline void TransCompressOptions(const RelFileNode& node, RelFileCompressOption* compressOption = compressOption >> g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].bitLen; } -#define SET_COMPRESS_OPTION(node, byteConvert, diffConvert, preChunks, symbol, level, algorithm, chunkSize) \ - do { \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].bitLen; \ - (node).opt += (byteConvert)&g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_DIFF_CONVERT_INDEX].bitLen; \ - (node).opt += (diffConvert)&g_cmpBitStruct[CMP_DIFF_CONVERT_INDEX].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_PRE_CHUNK_INDEX].bitLen; \ - (node).opt += (preChunks)&g_cmpBitStruct[CMP_PRE_CHUNK_INDEX].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_COMPRESS_LEVEL_SYMBOL].bitLen; \ - (node).opt += (symbol)&g_cmpBitStruct[CMP_COMPRESS_LEVEL_SYMBOL].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_LEVEL_INDEX].bitLen; \ - (node).opt += (level)&g_cmpBitStruct[CMP_LEVEL_INDEX].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_ALGORITHM_INDEX].bitLen; \ - (node).opt += (algorithm)&g_cmpBitStruct[CMP_ALGORITHM_INDEX].mask; \ - (node).opt = (node).opt << g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].bitLen; \ - (node).opt += (chunkSize)&g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].mask; \ +#define SET_COMPRESS_OPTION(node, byteConvert, diffConvert, preChunks, symbol, level, algorithm, chunkSize) \ + do { \ + (node).opt = 0; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].bitLen; \ + (node).opt += (byteConvert)&g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_DIFF_CONVERT_INDEX].bitLen; \ + (node).opt += (diffConvert)&g_cmpBitStruct[CMP_DIFF_CONVERT_INDEX].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_PRE_CHUNK_INDEX].bitLen; \ + (node).opt += (preChunks)&g_cmpBitStruct[CMP_PRE_CHUNK_INDEX].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_COMPRESS_LEVEL_SYMBOL].bitLen; \ + (node).opt += (symbol)&g_cmpBitStruct[CMP_COMPRESS_LEVEL_SYMBOL].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_LEVEL_INDEX].bitLen; \ + (node).opt += (level)&g_cmpBitStruct[CMP_LEVEL_INDEX].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_ALGORITHM_INDEX].bitLen; \ + (node).opt += (algorithm)&g_cmpBitStruct[CMP_ALGORITHM_INDEX].mask; \ + (node).opt = (node).opt << g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].bitLen; \ + (node).opt += (chunkSize)&g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].mask; \ } while (0) - + #define GET_ROW_COL_CONVERT(opt) \ (((opt) >> g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].moveBit) & g_cmpBitStruct[CMP_BYTE_CONVERT_INDEX].mask) #define GET_DIFF_CONVERT(opt) \ @@ -246,8 +247,8 @@ inline void TransCompressOptions(const RelFileNode& node, RelFileCompressOption* (((opt) >> g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].moveBit) & g_cmpBitStruct[CMP_CHUNK_SIZE_INDEX].mask) #define IS_COMPRESSED_MAINFORK(reln, forkNum) ((reln)->smgr_rnode.node.opt != 0 && (forkNum) == MAIN_FORKNUM) +#define IS_COMPRESS_DELETE_FORK(forkNum) ((forkNum) == COMPRESS_FORKNUM) #define IS_COMPRESSED_RNODE(rnode, forkNum) ((rnode).opt != 0 && (forkNum) == MAIN_FORKNUM) - /* Compress function */ template extern int TemplateCompressPage(const char* src, char* dst, int dst_size, RelFileCompressOption option); @@ -261,6 +262,11 @@ int CompressPage(const char* src, char* dst, int dst_size, RelFileCompressOption int DecompressPage(const char* src, char* dst, uint8 algorithm); +#define SET_OPT_BY_NEGATIVE_FORK(rnode, forkNumber) \ + do { \ + SET_COMPRESS_OPTION((rnode), 0, 0, 0, 0, 0, COMPRESS_ALGORITHM_ZSTD, 0); \ + } while (0) + /* Memory mapping function */ extern PageCompressHeader* pc_mmap(int fd, int chunk_size, bool readonly); extern PageCompressHeader* pc_mmap_real_size(int fd, int size, bool readonly); diff --git a/src/include/storage/smgr/relfilenode.h b/src/include/storage/smgr/relfilenode.h index d283d100b82dbea6d7795502204b4692d91798e9..ae2ee480a67d93f773aa8a9d4d56ab161873e3cc 100644 --- a/src/include/storage/smgr/relfilenode.h +++ b/src/include/storage/smgr/relfilenode.h @@ -31,6 +31,9 @@ typedef enum { */ typedef int ForkNumber; +/* used for delete forknum */ +#define COMPRESS_FORKNUM -9 + #define SEGMENT_EXT_8192_FORKNUM -8 #define SEGMENT_EXT_1024_FORKNUM -7 #define SEGMENT_EXT_128_FORKNUM -6 diff --git a/src/test/regress/input/row_compression/twophase.source b/src/test/regress/input/row_compression/twophase.source new file mode 100644 index 0000000000000000000000000000000000000000..2fc24da87f7f324792f86cae0c39d0413d0da517 --- /dev/null +++ b/src/test/regress/input/row_compression/twophase.source @@ -0,0 +1,37 @@ +create schema "compress_2PC"; +create table "compress_2PC".file_count(id int, count int); +checkpoint; +\! @abs_bindir@/gsql -r -p @portstring@ -d regression -c "insert into \"compress_2PC\".file_count values(1, `find @abs_srcdir@ | wc -l`)" +-- create rollback +start transaction; +create table "compress_2PC".normal(a text,b integer); +create table "compress_2PC".compress(a text,b integer) with (compresstype=2); +rollback; +-- drop commit +create table "compress_2PC".normal(id int); +create table "compress_2PC".compress(id int) with (compresstype=2); +start transaction; +drop table "compress_2PC".normal; +drop table "compress_2PC".compress; +commit; +-- 2pc create rollback +begin; +create table "compress_2PC".test_abort1(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_abort2(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_abort3(a text,b integer); +prepare transaction 'the first prepare transaction'; +rollback prepared 'the first prepare transaction'; +--2pc drop rollback +create table "compress_2PC".test_commit1(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_commit2(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_commit3(a text,b integer); +begin; +drop table "compress_2PC".test_commit1; +drop table"compress_2PC". test_commit2; +drop table "compress_2PC".test_commit3; +prepare transaction 'the first prepare transaction'; +commit prepared 'the first prepare transaction'; +-- checkpoint +checkpoint; +\! @abs_bindir@/gsql -r -p @portstring@ -d regression -c "insert into \"compress_2PC\".file_count values(2, `find @abs_srcdir@ | wc -l`)" +select count(distinct(count)) from "compress_2PC".file_count; \ No newline at end of file diff --git a/src/test/regress/output/row_compression/twophase.source b/src/test/regress/output/row_compression/twophase.source new file mode 100644 index 0000000000000000000000000000000000000000..d5bea7865ae1b98812942500e17dc165b7c72993 --- /dev/null +++ b/src/test/regress/output/row_compression/twophase.source @@ -0,0 +1,44 @@ +create schema "compress_2PC"; +create table "compress_2PC".file_count(id int, count int); +checkpoint; +\! @abs_bindir@/gsql -r -p @portstring@ -d regression -c "insert into \"compress_2PC\".file_count values(1, `find @abs_srcdir@ | wc -l`)" +INSERT 0 1 +-- create rollback +start transaction; +create table "compress_2PC".normal(a text,b integer); +create table "compress_2PC".compress(a text,b integer) with (compresstype=2); +rollback; +-- drop commit +create table "compress_2PC".normal(id int); +create table "compress_2PC".compress(id int) with (compresstype=2); +start transaction; +drop table "compress_2PC".normal; +drop table "compress_2PC".compress; +commit; +-- 2pc create rollback +begin; +create table "compress_2PC".test_abort1(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_abort2(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_abort3(a text,b integer); +prepare transaction 'the first prepare transaction'; +rollback prepared 'the first prepare transaction'; +--2pc drop rollback +create table "compress_2PC".test_commit1(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_commit2(a text,b integer) with (compresstype=2); +create table "compress_2PC".test_commit3(a text,b integer); +begin; +drop table "compress_2PC".test_commit1; +drop table"compress_2PC". test_commit2; +drop table "compress_2PC".test_commit3; +prepare transaction 'the first prepare transaction'; +commit prepared 'the first prepare transaction'; +-- checkpoint +checkpoint; +\! @abs_bindir@/gsql -r -p @portstring@ -d regression -c "insert into \"compress_2PC\".file_count values(2, `find @abs_srcdir@ | wc -l`)" +INSERT 0 1 +select count(distinct(count)) from "compress_2PC".file_count; + count +------- + 1 +(1 row) + diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 74288465484a2f4b9e58fc6ece5e3d3918b034af..46e5d377794d2244462ae8812c2bc611274e0154 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -903,6 +903,8 @@ test: toomanyparams test: test_astore_multixact test: row_compression/pg_table_size row_compression/unsupported_feature row_compression/normal_test +test: row_compression/row_compression_basebackup +test: row_compression/twophase test: component_view_enhancements test: single_node_user_mapping