forked from huawei/openGauss-server
Compare commits
370 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
07ad2fc0b2 | |
|
|
c7dddf6ace | |
|
|
91b3e149f9 | |
|
|
c6c3b2c722 | |
|
|
2c3bc6a56b | |
|
|
40c7176f03 | |
|
|
b7fcc134ae | |
|
|
b03341beb0 | |
|
|
bf712a1cc6 | |
|
|
e03e4cfbfe | |
|
|
b9bd5888a7 | |
|
|
0db9f3ea1e | |
|
|
21d976ed18 | |
|
|
787eaed932 | |
|
|
80052edd8e | |
|
|
c0bee891b0 | |
|
|
9d5e7f9044 | |
|
|
a3584e3a2e | |
|
|
62b1943825 | |
|
|
6206f03d67 | |
|
|
de396a512b | |
|
|
dc4dc6a870 | |
|
|
213b7432ef | |
|
|
56422b713a | |
|
|
dfb522b74f | |
|
|
34ad8af43f | |
|
|
0d77d960a4 | |
|
|
e1fc374ae4 | |
|
|
839a6b4801 | |
|
|
c81a284cad | |
|
|
cc6b8bc62d | |
|
|
f927083841 | |
|
|
9313d708ce | |
|
|
c420fde60e | |
|
|
e78e3c4eff | |
|
|
38d7c01fac | |
|
|
e001cbee91 | |
|
|
ef7949c398 | |
|
|
7344c83601 | |
|
|
7ffe72acb5 | |
|
|
29340beb1d | |
|
|
1db5ddc8f9 | |
|
|
e4e060ec84 | |
|
|
55986704fc | |
|
|
abcdefd4a3 | |
|
|
ee99c06af3 | |
|
|
bbff7b4f8a | |
|
|
e5a91d0c00 | |
|
|
ce5358b2dc | |
|
|
7ed416426a | |
|
|
ebd0d53b9a | |
|
|
83d10255b7 | |
|
|
c3b98cd084 | |
|
|
f5e1bf0ef7 | |
|
|
80e06757ad | |
|
|
3bfba81357 | |
|
|
839880b73e | |
|
|
82d949068d | |
|
|
f14f8188c4 | |
|
|
f615b8d514 | |
|
|
30c77fb771 | |
|
|
3f10a35464 | |
|
|
2eed7552d4 | |
|
|
e642f9d5f8 | |
|
|
a2c22701a8 | |
|
|
424b1c0b79 | |
|
|
a2faea7d96 | |
|
|
ec386db397 | |
|
|
112023186b | |
|
|
ee30a37bb3 | |
|
|
556aad463c | |
|
|
f2c925df9a | |
|
|
be4a969aa5 | |
|
|
66b956bfce | |
|
|
e72573a4c3 | |
|
|
2a1399e97b | |
|
|
7eef88d8dd | |
|
|
940fc12903 | |
|
|
9c3c898e52 | |
|
|
06112da4c6 | |
|
|
40ee83640d | |
|
|
3290af6a23 | |
|
|
87139aeb02 | |
|
|
7ef4caf5bb | |
|
|
881c689aec | |
|
|
5bc68d9c1c | |
|
|
d251f7caeb | |
|
|
78af441670 | |
|
|
91d2dfd761 | |
|
|
f53ea60351 | |
|
|
61cd9e6bcc | |
|
|
497cca8886 | |
|
|
d5b6f9ebc5 | |
|
|
d52064490d | |
|
|
b66511e9a9 | |
|
|
179ecce641 | |
|
|
05641397b1 | |
|
|
e7d541bc7a | |
|
|
2e6a0bd5e6 | |
|
|
426a5ef54f | |
|
|
75bce00aed | |
|
|
3830e90d8b | |
|
|
7be46e0e8c | |
|
|
34909bdaa7 | |
|
|
f6d2a542b3 | |
|
|
e54711814b | |
|
|
69a8bb769b | |
|
|
a10f3f8702 | |
|
|
2e14ad8b05 | |
|
|
e5295761b5 | |
|
|
82f41211b8 | |
|
|
518f8250d6 | |
|
|
66e71ca295 | |
|
|
d31aeb6bbf | |
|
|
e3d719e68d | |
|
|
868c3193d7 | |
|
|
aedb48e7e1 | |
|
|
960b1f040c | |
|
|
86e8c7686d | |
|
|
8725ceff6e | |
|
|
f13767aa88 | |
|
|
a75fa7ba38 | |
|
|
53e0a7b5e3 | |
|
|
107dbfc873 | |
|
|
24cdd19cb5 | |
|
|
d32dfbacaa | |
|
|
9716e5359e | |
|
|
1498872c34 | |
|
|
4997aaa735 | |
|
|
1b3a1e41a4 | |
|
|
0c2e6e7098 | |
|
|
4631ea876e | |
|
|
d1c210cdc0 | |
|
|
1f6e6c2638 | |
|
|
bb0fd6ca83 | |
|
|
d5227f5f65 | |
|
|
6adcc36fc6 | |
|
|
50aee20da9 | |
|
|
631cc42d1e | |
|
|
53395ca206 | |
|
|
5eb44eed53 | |
|
|
78c42f2a25 | |
|
|
3bec247d73 | |
|
|
0a8e37b025 | |
|
|
b8c6463548 | |
|
|
1453860560 | |
|
|
e1b9418050 | |
|
|
e08739048f | |
|
|
d6ed737bc7 | |
|
|
52f0789fb8 | |
|
|
de8703b2fc | |
|
|
903c81598e | |
|
|
23ce4e04b4 | |
|
|
71f3e152a4 | |
|
|
e8f21ffeb1 | |
|
|
4708c83460 | |
|
|
76ee161a69 | |
|
|
f27365b926 | |
|
|
08f2655e39 | |
|
|
3dfa80b335 | |
|
|
fa702eb6c3 | |
|
|
9bb33c2a4b | |
|
|
080c54c9da | |
|
|
561ba0ebcd | |
|
|
a7e92ffd28 | |
|
|
14fc938f54 | |
|
|
d40098a5e2 | |
|
|
34f457d2aa | |
|
|
d470ef5f50 | |
|
|
c1a69126a5 | |
|
|
53480bc2e4 | |
|
|
52f2f17864 | |
|
|
893dc25515 | |
|
|
f3ac0f81ec | |
|
|
ed81aff7ea | |
|
|
74a53a08c2 | |
|
|
fd31bfbba6 | |
|
|
1a20907a0c | |
|
|
34830974d0 | |
|
|
0d1a224b9b | |
|
|
f9ccb7f333 | |
|
|
17198aede1 | |
|
|
0399758403 | |
|
|
1e1deb8ccb | |
|
|
29b6e0ae0b | |
|
|
f973f66c91 | |
|
|
8b911a9ecc | |
|
|
f7c9c74e94 | |
|
|
7dfaa30b61 | |
|
|
da0810db73 | |
|
|
1fcee7bded | |
|
|
8105a88efc | |
|
|
853f28b007 | |
|
|
8fa6f5d266 | |
|
|
530c4f9295 | |
|
|
18b92d0179 | |
|
|
afc8573e0c | |
|
|
cb7199ad10 | |
|
|
08ff95ceac | |
|
|
2cb242dea4 | |
|
|
07cf79cd4c | |
|
|
ae0bba2497 | |
|
|
b270c85d0d | |
|
|
e929c3d736 | |
|
|
47a29a6549 | |
|
|
e16bcf5447 | |
|
|
a9b1ed440b | |
|
|
2f0096bbf4 | |
|
|
bf913706f4 | |
|
|
01aa74162a | |
|
|
47c987f3ab | |
|
|
597e454f8e | |
|
|
3ec8df390c | |
|
|
2f1e988b6f | |
|
|
b8b38213df | |
|
|
c5661c88a9 | |
|
|
a189abd40e | |
|
|
c6b1e6dd61 | |
|
|
6a6d31e033 | |
|
|
9daeecabab | |
|
|
fa1c39017d | |
|
|
7825074686 | |
|
|
4cae2a598f | |
|
|
af29fcb32c | |
|
|
be3daf9735 | |
|
|
ee41b69791 | |
|
|
be03869079 | |
|
|
009f101444 | |
|
|
6c642dfb0f | |
|
|
cf68d6850f | |
|
|
48a1e97eb6 | |
|
|
1e38a0e8ac | |
|
|
ba1300e7bb | |
|
|
71eae51f51 | |
|
|
217801b8e6 | |
|
|
7f68b9106d | |
|
|
942963ce99 | |
|
|
eb8a201dd8 | |
|
|
137f9e27da | |
|
|
8145a970b8 | |
|
|
8908b5b686 | |
|
|
e55fe34bd1 | |
|
|
934ede745f | |
|
|
a0b573df19 | |
|
|
132ecf4dfb | |
|
|
de938b0876 | |
|
|
ffa89332fd | |
|
|
71dc7a8d23 | |
|
|
65f0c17ba0 | |
|
|
75b48e5d5d | |
|
|
0cd2b0be96 | |
|
|
830c7b65c5 | |
|
|
df7ce14ac5 | |
|
|
5833a6ade8 | |
|
|
186ec1e3d6 | |
|
|
9e08c03365 | |
|
|
9b22bbca66 | |
|
|
e7466a0ba5 | |
|
|
161392ce01 | |
|
|
fc0bd72f7c | |
|
|
4d9e5c3995 | |
|
|
1de15e5767 | |
|
|
2f6663e0a8 | |
|
|
d7db88e63c | |
|
|
ed0ed87142 | |
|
|
68bb7f6db4 | |
|
|
e16a7dc8e6 | |
|
|
f571ec39a4 | |
|
|
14575e716e | |
|
|
5801e94cb5 | |
|
|
ea09eb38b3 | |
|
|
06a67d97c8 | |
|
|
8c0b5d2d25 | |
|
|
fe108e5081 | |
|
|
6bf1fb2f9c | |
|
|
d2cc245629 | |
|
|
54c9ee660f | |
|
|
86c7b50454 | |
|
|
974d93ac1a | |
|
|
d97c0e8a59 | |
|
|
2ed6eb7e73 | |
|
|
cfb2309a2f | |
|
|
f60dd06e4e | |
|
|
eda1e7a059 | |
|
|
ae9a04a7d7 | |
|
|
1512d8c2b2 | |
|
|
8aa97848db | |
|
|
37ce2f004c | |
|
|
e8cfcb6913 | |
|
|
29cda19e0a | |
|
|
6f90fd61ef | |
|
|
ef48e48294 | |
|
|
7d89cf9b71 | |
|
|
e2a9abadf0 | |
|
|
9037554735 | |
|
|
ea6cb7bc85 | |
|
|
0ef7e16c01 | |
|
|
255f2f088d | |
|
|
873d312766 | |
|
|
b0cf1b5a71 | |
|
|
dde0db6e41 | |
|
|
6884947f92 | |
|
|
4038da4073 | |
|
|
76d06ea404 | |
|
|
93ffe79fdf | |
|
|
35a33b0477 | |
|
|
65328fecc4 | |
|
|
38cbb219a4 | |
|
|
91fa7c590a | |
|
|
66aab91c24 | |
|
|
9ce2d71763 | |
|
|
3571af9264 | |
|
|
710b91df67 | |
|
|
1eb23621ba | |
|
|
6b600011ef | |
|
|
335ad7ab79 | |
|
|
d30a31dc44 | |
|
|
9302324edf | |
|
|
aa802913dc | |
|
|
98ea2c0c6d | |
|
|
79eb60ec65 | |
|
|
2cc54fcbe0 | |
|
|
926e3140a4 | |
|
|
3f9b68d3b5 | |
|
|
9ffe07c287 | |
|
|
3da699c225 | |
|
|
5cf37d09a8 | |
|
|
03f5c450a7 | |
|
|
c8ed01893a | |
|
|
9d98a96424 | |
|
|
beb58498ea | |
|
|
7147032489 | |
|
|
a6bca8da91 | |
|
|
dd0d35fed5 | |
|
|
e7bdddbfb7 | |
|
|
20c720785c | |
|
|
6b05f10be4 | |
|
|
114c58d19f | |
|
|
0010c147ba | |
|
|
9d63994ad9 | |
|
|
f03c3fb372 | |
|
|
bc4795bde0 | |
|
|
32dfafd391 | |
|
|
a13cbeea2a | |
|
|
8549fe7257 | |
|
|
e33dec6c43 | |
|
|
c2e37342f7 | |
|
|
dcdd71384b | |
|
|
b071fe9f99 | |
|
|
360d281ceb | |
|
|
bf32e4ae36 | |
|
|
d2de98cea1 | |
|
|
a8e142f0cb | |
|
|
08f2a403fa | |
|
|
30e066555e | |
|
|
43fd81e96a | |
|
|
7674a2a9eb | |
|
|
2e6258fde4 | |
|
|
440355076f | |
|
|
b872b011ea | |
|
|
78f38bb9cb | |
|
|
e6c44f068b | |
|
|
46e97fe6f8 | |
|
|
4d60233c3b | |
|
|
90274f363e | |
|
|
e85e79a09e | |
|
|
1c05419296 | |
|
|
896bdd99d9 | |
|
|
6a283ac83e | |
|
|
a6e46957f5 |
|
|
@ -881,6 +881,9 @@ function install_gaussdb()
|
|||
fi
|
||||
fi
|
||||
|
||||
# copy gs_plan_simulator.sh to /bin dir. it's used in gs_collector tool.
|
||||
cp ${ROOT_DIR}/src/bin/gs_plan_simulator/gs_plan_simulator.sh ${BUILD_DIR}/bin/
|
||||
|
||||
chmod 444 ${BUILD_DIR}/bin/cluster_guc.conf
|
||||
dos2unix ${BUILD_DIR}/bin/cluster_guc.conf > /dev/null 2>&1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
PRODUCT=openGauss
|
||||
VERSION=2.0.0
|
||||
VERSION=2.0.3
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
./bin/transfer.py
|
||||
./bin/bind_net_irq.sh
|
||||
./bin/setArmOptimization.sh
|
||||
./bin/gs_plan_simulator.sh
|
||||
./bin/krb5kdc
|
||||
./bin/klist
|
||||
./bin/kinit
|
||||
|
|
@ -877,6 +878,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
./bin/transfer.py
|
||||
./bin/bind_net_irq.sh
|
||||
./bin/setArmOptimization.sh
|
||||
./bin/gs_plan_simulator.sh
|
||||
./bin/krb5kdc
|
||||
./bin/klist
|
||||
./bin/kinit
|
||||
|
|
@ -877,6 +878,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
./bin/transfer.py
|
||||
./bin/bind_net_irq.sh
|
||||
./bin/setArmOptimization.sh
|
||||
./bin/gs_plan_simulator.sh
|
||||
./bin/krb5kdc
|
||||
./bin/klist
|
||||
./bin/kinit
|
||||
|
|
@ -877,6 +878,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -900,7 +900,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
./bin/transfer.py
|
||||
./bin/bind_net_irq.sh
|
||||
./bin/setArmOptimization.sh
|
||||
./bin/gs_plan_simulator.sh
|
||||
./bin/krb5kdc
|
||||
./bin/klist
|
||||
./bin/kinit
|
||||
|
|
@ -877,6 +878,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
./bin/transfer.py
|
||||
./bin/bind_net_irq.sh
|
||||
./bin/setArmOptimization.sh
|
||||
./bin/gs_plan_simulator.sh
|
||||
./bin/krb5kdc
|
||||
./bin/klist
|
||||
./bin/kinit
|
||||
|
|
@ -877,6 +878,9 @@
|
|||
./lib/postgresql/latin2_and_win1250.so
|
||||
./lib/postgresql/euc2004_sjis2004.so
|
||||
./lib/libhll.so
|
||||
./lib/libzstd.so
|
||||
./lib/libzstd.so.1
|
||||
./lib/libzstd.so.1.4.4
|
||||
|
||||
./include/postgresql/server/postgres_ext.h
|
||||
./include/postgresql/server/pg_config_os.h
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ function print_help()
|
|||
}
|
||||
|
||||
#######################################################################
|
||||
##version 2.0.0
|
||||
##version 2.0.3
|
||||
#######################################################################
|
||||
function read_srv_version()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1781,7 +1781,7 @@ static char** get_pkey_attnames(Relation rel, int16* indnkeyatts)
|
|||
indexRelation = heap_open(IndexRelationId, AccessShareLock);
|
||||
ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
scan = systable_beginscan(indexRelation, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey);
|
||||
scan = systable_beginscan(indexRelation, IndexIndrelidIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(indexTuple = systable_getnext(scan))) {
|
||||
Form_pg_index index = (Form_pg_index)GETSTRUCT(indexTuple);
|
||||
|
|
|
|||
|
|
@ -775,11 +775,6 @@ void ExceptionalCondition(const char* conditionName, const char* errorType, cons
|
|||
abort();
|
||||
}
|
||||
|
||||
// see to relmappper.cpp
|
||||
//
|
||||
#define MAX_MAPPINGS 62 /* 62 * 8 + 16 = 512 */
|
||||
#define RELMAPPER_FILENAME "pg_filenode.map"
|
||||
#define RELMAPPER_FILEMAGIC 0x592717 /* version ID value */
|
||||
#define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */
|
||||
|
||||
typedef struct PgClass_table {
|
||||
|
|
@ -3179,6 +3174,35 @@ read_failed:
|
|||
return result;
|
||||
}
|
||||
|
||||
static int ReadOldVersionRelmapFile(char *buffer, FILE *fd)
|
||||
{
|
||||
errno_t rc;
|
||||
char oldMapCache[RELMAP_SIZE_OLD];
|
||||
int readByte = fread(oldMapCache, 1, RELMAP_SIZE_OLD, fd);
|
||||
rc = memcpy_s(buffer, sizeof(RelMapFile), oldMapCache, MAPPING_LEN_OLDMAP_HEAD);
|
||||
securec_check(rc, "\0", "\0");
|
||||
rc = memcpy_s(
|
||||
buffer + offsetof(RelMapFile, crc), MAPPING_LEN_TAIL, oldMapCache + MAPPING_LEN_OLDMAP_HEAD, MAPPING_LEN_TAIL);
|
||||
securec_check(rc, "\0", "\0");
|
||||
return readByte;
|
||||
}
|
||||
|
||||
static void DoRelMapCrcCheck(const RelMapFile* mapfile, int32 magicNum)
|
||||
{
|
||||
pg_crc32 crc;
|
||||
/* verify the CRC */
|
||||
INIT_CRC32(crc);
|
||||
if (IS_NEW_RELMAP(magicNum)) {
|
||||
COMP_CRC32(crc, (char*)mapfile, offsetof(RelMapFile, crc));
|
||||
} else {
|
||||
COMP_CRC32(crc, (char*)mapfile, MAPPING_LEN_OLDMAP_HEAD);
|
||||
}
|
||||
FIN_CRC32(crc);
|
||||
if (!EQ_CRC32(crc, (pg_crc32)(mapfile->crc))) {
|
||||
fprintf(stdout, "WARNING: relmap crc check failed!");
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_filenodemap_file(char* filename)
|
||||
{
|
||||
char buffer[sizeof(RelMapFile)];
|
||||
|
|
@ -3189,6 +3213,9 @@ static int parse_filenodemap_file(char* filename)
|
|||
char* pg_class_map[MAX_PG_CLASS_ID];
|
||||
char* pg_class = NULL;
|
||||
int i = 0;
|
||||
int32 magicNum;
|
||||
int32 relmapSize;
|
||||
int32 relmapMaxMappings;
|
||||
|
||||
for (i = 0; i < MAX_PG_CLASS_ID; i++) {
|
||||
pg_class_map[i] = NULL;
|
||||
|
|
@ -3203,17 +3230,34 @@ static int parse_filenodemap_file(char* filename)
|
|||
fseek(fd, 0, SEEK_END);
|
||||
size = ftell(fd);
|
||||
rewind(fd);
|
||||
result = fread(buffer, 1, sizeof(RelMapFile), fd);
|
||||
if (sizeof(RelMapFile) != result) {
|
||||
|
||||
result = fread(&magicNum, 1, sizeof(int32), fd);
|
||||
rewind(fd);
|
||||
if (result != sizeof(int32)) {
|
||||
fprintf(stderr, "Reading magic error");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IS_NEW_RELMAP(magicNum)) {
|
||||
result = fread(buffer, 1, sizeof(RelMapFile), fd);
|
||||
relmapSize = RELMAP_SIZE_NEW;
|
||||
relmapMaxMappings = MAX_MAPPINGS_4K;
|
||||
} else {
|
||||
result = ReadOldVersionRelmapFile(buffer, fd);
|
||||
relmapSize = RELMAP_SIZE_OLD;
|
||||
relmapMaxMappings = MAX_MAPPINGS;
|
||||
}
|
||||
if ((size_t)relmapSize != result) {
|
||||
fprintf(stderr, "Reading error");
|
||||
return false;
|
||||
}
|
||||
|
||||
mapfile = (RelMapFile*)buffer;
|
||||
DoRelMapCrcCheck(mapfile, magicNum);
|
||||
fprintf(stdout, "Magic number: 0x%x\n", mapfile->magic);
|
||||
fprintf(stdout, "Number of mappings: %u\n", mapfile->num_mappings);
|
||||
fprintf(stdout, "Mapping pairs:\n");
|
||||
for (i = 0; i < MAX_MAPPINGS; i++) {
|
||||
for (i = 0; i < relmapMaxMappings; i++) {
|
||||
if (0 == mapfile->mappings[i].mapoid && 0 == mapfile->mappings[i].mapfilenode)
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ Datum pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
|
||||
/* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */
|
||||
fctx->record =
|
||||
(BufferCachePagesRec*)palloc(sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
|
||||
fctx->record = (BufferCachePagesRec *)palloc_huge(CurrentMemoryContext,
|
||||
sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
|
||||
|
||||
/* Set max calls and remember the user function context. */
|
||||
funcctx->max_calls = g_instance.attr.attr_storage.NBuffers;
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ static void exec_object_restorecon(struct selabel_handle* sehnd, Oid catalogId)
|
|||
*/
|
||||
rel = heap_open(catalogId, AccessShareLock);
|
||||
|
||||
sscan = systable_beginscan(rel, InvalidOid, false, SnapshotNow, 0, NULL);
|
||||
sscan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sscan))) {
|
||||
Form_pg_database datForm;
|
||||
Form_pg_namespace nspForm;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ SUBDIRS = \
|
|||
pg_controldata \
|
||||
pg_resetxlog \
|
||||
gs_guc \
|
||||
pgxc_clean \
|
||||
gs_cgroup \
|
||||
gsqlerr \
|
||||
pg_basebackup \
|
||||
pg_probackup
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ enable_compress_hll|bool|0,0|NULL|NULL|
|
|||
enable_fast_numeric|bool|0,0|NULL|Enable numeric optimize.|
|
||||
enable_force_vector_engine|bool|0,0|NULL|NULL|
|
||||
enable_global_plancache|bool|0,0|NULL|NULL|
|
||||
gpc_clean_timeout|int|300,86400|NULL|NULL|
|
||||
enable_twophase_commit|bool|0,0|NULL|NULL|
|
||||
enable_hashagg|bool|0,0|NULL|NULL|
|
||||
enable_hashjoin|bool|0,0|NULL|NULL|
|
||||
|
|
@ -295,6 +296,7 @@ gtm_port4|int|1,65535|NULL|NULL|
|
|||
gtm_port5|int|1,65535|NULL|NULL|
|
||||
gtm_port6|int|1,65535|NULL|NULL|
|
||||
gtm_port7|int|1,65535|NULL|NULL|
|
||||
gs_clean_timeout|int|0,2147483|s|NULL|
|
||||
hashagg_table_size|int|0,1073741823|NULL|NULL|
|
||||
hba_file|string|0,0|NULL|NULL|
|
||||
hot_standby|bool|0,0|NULL|When hot_standby set to on, wal_level must be set to hot_standby. Otherwise it will cause the database can not be started. In the dual-system environments, hot_standby can not be set to off.|
|
||||
|
|
@ -345,6 +347,7 @@ wdr_snapshot_query_timeout|int|100,2147483647|s|NULL|
|
|||
enable_wdr_snapshot|bool|0,0|NULL|NULL|
|
||||
enable_asp|bool|0,0|NULL|NULL|
|
||||
enable_stmt_track|bool|0,0|NULL|NULL|
|
||||
track_stmt_parameter|bool|0,0|NULL|NULL|
|
||||
asp_sample_num|int|10000,100000|NULL|NULL|
|
||||
asp_sample_interval|int|1,10|s|NULL|
|
||||
asp_flush_rate|int|1,10|NULL|NULL|
|
||||
|
|
@ -398,6 +401,7 @@ memorypool_enable|bool|0,0|NULL|NULL|
|
|||
memorypool_size|int|131072,1073741823|kB|NULL|
|
||||
memory_detail_tracking|string|0,0|NULL|This parameter memory_detail_tracking only can be used in debug version. If it is set in the release version, it will lead the cluster does not work properly. Therefore, before making the settings, please make sure that the cluster version is debug.|
|
||||
memory_tracking_mode|enum|none,normal,executor,fullexec|NULL|NULL|
|
||||
min_dynamic_memory|int|-1,2147483647|NULL|NULL|
|
||||
minimum_pool_size|int|1,65535|NULL|NULL|
|
||||
modify_initial_password|bool|0,0|NULL|NULL|
|
||||
most_available_sync|bool|0,0|NULL|NULL|
|
||||
|
|
@ -480,6 +484,7 @@ standard_conforming_strings|bool|0,0|NULL|NULL|
|
|||
standby_shared_buffers_fraction|real|0.1,1|NULL|NULL|
|
||||
statement_timeout|int|0,2147483647|ms|NULL|
|
||||
stats_temp_directory|string|0,0|NULL|NULL|
|
||||
num_internal_lock_partitions|string|0,0|NULL|NULL|
|
||||
stream_multiple|real|0,1.79769e+308|NULL|NULL|
|
||||
string_hash_compatible|bool|0,0|NULL|NULL|
|
||||
enable_slow_query_log|bool|0,0|NULL|NULL|
|
||||
|
|
@ -649,7 +654,7 @@ enable_auto_explain|bool|0,0|NULL|NULL|
|
|||
auto_explain_level|enum|off,log,notice|NULL|NULL|
|
||||
cost_weight_index|real|1e-10,1e+10|NULL|NULL|
|
||||
default_limit_rows|real|-100,1.79769e+308|NULL|NULL|
|
||||
sql_beta_feature|enum|sel_semi_poisson,sel_expr_instr,param_path_gen,rand_cost_opt,param_path_opt,page_est_opt,none|NULL|NULL|
|
||||
sql_beta_feature|enum|join_sel_with_cast_func,no_unique_index_first,sel_semi_poisson,sel_expr_instr,param_path_gen,rand_cost_opt,param_path_opt,page_est_opt,none|NULL|NULL|
|
||||
xlog_idle_flushes_before_sleep|int64|0,576460752303423487|NULL|NULL|
|
||||
wal_writer_cpu|int|-1,2147483647|NULL|NULL|
|
||||
wal_file_init_num|int|1,2147483647|NULL|NULL|
|
||||
|
|
@ -658,6 +663,8 @@ max_concurrent_autonomous_transactions|int|0,262143|NULL|NULL|
|
|||
sync_config_strategy|enum|all_node,only_sync_node,none_node|NULL|Synchronization strategy for configuration files between host and standby.|
|
||||
time_to_target_rpo|int|0,3600|NULL|NULL|
|
||||
disable_memory_protect|bool|0,0|NULL|NULL|
|
||||
unique_sql_clean_ratio|real|0,0.2|NULL|NULL|
|
||||
enable_auto_clean_unique_sql|bool|0,0|NULL|NULL|
|
||||
[cmserver]
|
||||
log_dir|string|0,0|NULL|NULL|
|
||||
log_file_size|int|0,2047|MB|NULL|
|
||||
|
|
|
|||
|
|
@ -1696,74 +1696,6 @@ int get_nodename_number_from_nodelist(const char* namelist)
|
|||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
******************************************************************************
|
||||
Function : check_datanodename_value
|
||||
Description : check the input datanode Name.
|
||||
Input :nodeName data node name
|
||||
return :true input datanode name is correct
|
||||
false input datanode name is incorrect
|
||||
******************************************************************************
|
||||
*/
|
||||
bool CheckDataNameValue(const char *datanodeName, const char *dataDir)
|
||||
{
|
||||
int nRet;
|
||||
uint32 nodeIdx = 0;
|
||||
uint32 datanodeIdx = 0;
|
||||
int dnIdMaxLen = 64;
|
||||
char dnId[dnIdMaxLen];
|
||||
|
||||
if ((datanodeName == NULL) || (*datanodeName == '\0')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dataNodeInfo *dnI = NULL;
|
||||
|
||||
for (datanodeIdx = 0; datanodeIdx < g_currentNode->datanodeCount; datanodeIdx++) {
|
||||
dataNodeInfo *dniTmp = &(g_currentNode->datanode[datanodeIdx]);
|
||||
if (strcmp(dniTmp->datanodeLocalDataPath, dataDir) == 0) {
|
||||
dnI = dniTmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dnI == NULL) {
|
||||
write_stderr("Failed: cannot find the expected data dir\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (nodeIdx = 0; nodeIdx < g_node_num; ++nodeIdx) {
|
||||
staticNodeConfig *dest = &(g_node[nodeIdx]);
|
||||
for (datanodeIdx = 0; datanodeIdx < dest->datanodeCount; ++datanodeIdx) {
|
||||
dataNodeInfo *dn = &(dest->datanode[datanodeIdx]);
|
||||
if (dn->datanodeId == 0 || dn->datanodeId == dnI->datanodeId) {
|
||||
continue;
|
||||
}
|
||||
nRet = memset_s(dnId, sizeof(dnId), '\0', sizeof(dnId));
|
||||
securec_check_c(nRet, "\0", "\0");
|
||||
nRet = snprintf_s(
|
||||
dnId, sizeof(dnId) / sizeof(char), sizeof(dnId) / sizeof(char) - 1, "dn_%4d", dn->datanodeId);
|
||||
securec_check_ss_c(nRet, "\0", "\0");
|
||||
if (strncmp(dnId, datanodeName,
|
||||
((strlen(dnId) > strlen(datanodeName)) ? strlen(dnId) : strlen(datanodeName))) != 0) {
|
||||
continue;
|
||||
}
|
||||
for (int peerIndex = 0; peerIndex < CM_MAX_DATANODE_STANDBY_NUM; ++peerIndex) {
|
||||
peerDatanodeInfo *peerDatanode = &(dnI->peerDatanodes[peerIndex]);
|
||||
if (strlen(peerDatanode->datanodePeerHAIP[0]) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(peerDatanode->datanodePeerHAIP[0], dn->datanodeLocalHAIP[0]) == 0 &&
|
||||
peerDatanode->datanodePeerHAPort == dn->datanodeLocalHAPort) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
Function : parse_datanodename_result
|
||||
|
|
@ -1846,7 +1778,6 @@ char* get_AZ_value(const char* value, const char* data_dir)
|
|||
char delims[] = ",";
|
||||
char* vptr = NULL;
|
||||
char emptyvalue[] = "''";
|
||||
int resultStatus = 0;
|
||||
bool isNodeName = false;
|
||||
|
||||
if (az1 != NULL) {
|
||||
|
|
@ -1946,11 +1877,6 @@ char* get_AZ_value(const char* value, const char* data_dir)
|
|||
|
||||
if (NULL == nodenameList) {
|
||||
// try dn
|
||||
resultStatus = get_nodename_list_by_AZ(az1, data_dir, &nodenameList);
|
||||
PROCESS_STATUS(resultStatus);
|
||||
if (nodenameList == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
len = strlen(q) + 1;
|
||||
s = (char *)pg_malloc_zero(len * sizeof(char));
|
||||
|
|
@ -1961,15 +1887,15 @@ char* get_AZ_value(const char* value, const char* data_dir)
|
|||
while (vptr != NULL) {
|
||||
p = vptr;
|
||||
|
||||
if (!contain_nodename(nodenameList, p)) {
|
||||
if (CheckDataNameValue(p, data_dir) == false) {
|
||||
goto failed;
|
||||
}
|
||||
vptr = strtok_r(NULL, delims, &vouter_ptr);
|
||||
}
|
||||
|
||||
GS_FREE(s);
|
||||
len = strlen(nodenameList);
|
||||
nRet = snprintf_s(nodenameList, len + 1, len, "%s", q);
|
||||
nodenameList = (char *)pg_malloc_zero(len * sizeof(char));
|
||||
nRet = snprintf_s(nodenameList, len, len - 1, "%s", q);
|
||||
securec_check_ss_c(nRet, nodenameList, "\0");
|
||||
} else if ('\0' == nodenameList[0]) {
|
||||
(void)write_stderr("ERROR: There is no standby node name. Please make sure the value of "
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ const int EQUAL_MARK_LEN = 3;
|
|||
#define ADDPOINTER_SIZE 2
|
||||
#define MAX_HOST_NAME_LENGTH 255
|
||||
|
||||
#define TEMP_PGCONF_FILE "postgresql.conf.bak"
|
||||
#define TEMP_PGCONF_FILE "postgresql.conf.guc.bak"
|
||||
#define TEMP_CMAGENTCONF_FILE "cm_agent.conf.bak"
|
||||
#define TEMP_CMSERVERCONF_FILE "cm_server.conf.bak"
|
||||
#define TEMP_GTMCONF_FILE "gtm.conf.bak"
|
||||
|
|
@ -1033,6 +1033,72 @@ append_string_info(char **optLines, const char *newContext)
|
|||
return optLinesResult;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_next_sync_groups(char **pgroup, char *result)
|
||||
{
|
||||
if (**pgroup == '\0') {
|
||||
result[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
char *this_group = *pgroup;
|
||||
char *p = *pgroup;
|
||||
while (*p != '\0' && *p != ')') p++;
|
||||
while (*p != '\0' && *p != ',') p++;
|
||||
if (*p == ',') {
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
*pgroup = p;
|
||||
errno_t rc = snprintf_s(result, MAX_VALUE_LEN, MAX_VALUE_LEN - 1, "'%s'", this_group);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
transform_az_name(char *config_value, char *allAZString, int allAZStringBufLen, const char *data_dir)
|
||||
{
|
||||
if (strcmp(config_value, "''") == 0) {
|
||||
errno_t rc = strncpy_s(allAZString, allAZStringBufLen, config_value, strlen(config_value));
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
char *azString = NULL;
|
||||
char *buf = allAZString;
|
||||
int buflen = allAZStringBufLen;
|
||||
|
||||
char *allgroup = xstrdup(config_value);
|
||||
char *pgrp = allgroup + 1; // trim first "'"
|
||||
char this_group[MAX_VALUE_LEN] = {0x00};
|
||||
|
||||
allgroup[strlen(allgroup) - 1] = '\0'; // trim last "'"
|
||||
parse_next_sync_groups(&pgrp, this_group);
|
||||
while (this_group[0] != '\0') {
|
||||
azString = get_AZ_value(this_group, data_dir);
|
||||
if (NULL == azString) {
|
||||
GS_FREE(allgroup);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
int azStringLen = strlen(azString);
|
||||
azString[0] = ' ';
|
||||
azString[azStringLen - 1] = ',';
|
||||
errno_t rc = strncpy_s(buf, buflen, azString, azStringLen);
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
buf += azStringLen;
|
||||
buflen -= azStringLen;
|
||||
GS_FREE(azString);
|
||||
|
||||
parse_next_sync_groups(&pgrp, this_group);
|
||||
}
|
||||
GS_FREE(allgroup);
|
||||
allAZString[0] = allAZString[strlen(allAZString) - 1] = '\'';
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
/*******************************************************************************
|
||||
Function : IsLastNotNullReplconninfo
|
||||
|
|
@ -1194,17 +1260,16 @@ do_gucset(const char *action_type, const char *data_dir)
|
|||
|
||||
// get AZ string
|
||||
if (NULL != config_value[i]) {
|
||||
char *azString = NULL;
|
||||
azString = get_AZ_value(config_value[i], data_dir);
|
||||
if (NULL == azString) {
|
||||
result_status = FAILURE;
|
||||
char allAZString[MAX_VALUE_LEN] = {0x00};
|
||||
|
||||
result_status = transform_az_name(config_value[i], allAZString, MAX_VALUE_LEN, data_dir);
|
||||
if (result_status == FAILURE) {
|
||||
continue;
|
||||
}
|
||||
tmpAZStr = xstrdup(config_value[i]);
|
||||
|
||||
GS_FREE(config_value[i]);
|
||||
config_value[i] = xstrdup(azString);
|
||||
GS_FREE(azString);
|
||||
config_value[i] = xstrdup(allAZString);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -708,6 +708,7 @@ static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
|
|||
}
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
while (true) {
|
||||
if (copybuf != NULL) {
|
||||
|
|
@ -886,6 +887,7 @@ static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
|
|||
* Get the COPY data
|
||||
*/
|
||||
res = backup_get_result(conn);
|
||||
PQclear(res);
|
||||
|
||||
while (1) {
|
||||
int r;
|
||||
|
|
@ -938,7 +940,7 @@ static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
|
|||
/*
|
||||
* All files are padded up to 512 bytes
|
||||
*/
|
||||
if (current_len_left < 0 || current_len_left > LLONG_MAX - 511) {
|
||||
if (current_len_left < 0 || current_len_left > INT_MAX - 511) {
|
||||
pg_log(stderr, _("%s: the file '%s' is too big or file size is invalid\n"), progname, copybuf);
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -669,9 +669,9 @@ static int getOptions(const int argc, char* const* argv)
|
|||
break;
|
||||
case 'p':
|
||||
check_env_value_c(optarg);
|
||||
if (atoi(optarg) <= 0) {
|
||||
if (checkIsDigit(optarg) == 0) {
|
||||
fprintf(stderr, _("%s: invalid port number \"%s\"\n"), progname, optarg);
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
dbport = pg_strdup(optarg);
|
||||
break;
|
||||
|
|
@ -736,8 +736,7 @@ static int getOptions(const int argc, char* const* argv)
|
|||
|
||||
fsync_interval = atoi(optarg) * 1000;
|
||||
if (fsync_interval < 0) {
|
||||
fprintf(stderr, _("%s: invalid fsync interval \"%s\"\n"), progname, optarg);
|
||||
return -1;
|
||||
fsync_interval = 0;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
|
|
|
|||
|
|
@ -709,10 +709,10 @@ bool ReceiveXlogStream(PGconn* conn, XLogRecPtr startpos, uint32 timeline, const
|
|||
if (standby_message_timeout_local) {
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
timeout.tv_sec = CalculateCopyStreamSleeptime(local_now,
|
||||
standby_message_timeout_local,
|
||||
standby_message_timeout_local / 2,
|
||||
last_status);
|
||||
#else
|
||||
timeout.tv_sec = last_status + standby_message_timeout_local - local_now - 1;
|
||||
timeout.tv_sec = last_status + (standby_message_timeout_local / 2) - local_now - 1;
|
||||
#endif
|
||||
if (timeout.tv_sec <= 0)
|
||||
timeout.tv_sec = 1; /* Always sleep at least 1 sec */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "knl/knl_variable.h"
|
||||
#include "utils/timestamp.h"
|
||||
#include "streamutil.h"
|
||||
#include "libpq/libpq-int.h"
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -138,6 +139,17 @@ static void CalculateArgCount(int *argcount)
|
|||
return;
|
||||
}
|
||||
|
||||
static void CheckConnectionHost(PGconn* tmpconn)
|
||||
{
|
||||
if (tmpconn == NULL || tmpconn->sock < 0) {
|
||||
fprintf(stderr, "failed to connect %s:%s.\n",
|
||||
(dbhost == NULL) ? "Unknown" : dbhost,
|
||||
(dbport == NULL) ? "Unknown" : dbport);
|
||||
PQfinish(tmpconn);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to the server. Returns a valid PGconn pointer if connected,
|
||||
* or NULL on non-permanent error. On permanent error, the function will
|
||||
|
|
@ -212,10 +224,7 @@ PGconn* GetConnection(void)
|
|||
* If there is too little memory even to allocate the PGconn object
|
||||
* and PQconnectdbParams returns NULL, we call exit(1) directly.
|
||||
*/
|
||||
if (tmpconn == NULL) {
|
||||
fprintf(stderr, _("%s: could not connect to server\n"), progname);
|
||||
exit(1);
|
||||
}
|
||||
CheckConnectionHost(tmpconn);
|
||||
|
||||
if (PQstatus(tmpconn) == CONNECTION_BAD && PQconnectionNeedsPassword(tmpconn) && dbgetpassword != -1) {
|
||||
dbgetpassword = 1; /* ask for password next time */
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ static void show_version(int alls)
|
|||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
printf("PostgreSQL 9.2.4\n");
|
||||
#else
|
||||
printf("openGauss 2.0.0\n");
|
||||
printf("openGauss 2.0.3\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
|
||||
/* Global options */
|
||||
char* basedir = NULL;
|
||||
bool isBuildFromStandby = false;
|
||||
char format = 'p'; /* p(lain)/t(ar) */
|
||||
char* label = "gs_ctl full build";
|
||||
bool showprogress = true;
|
||||
|
|
@ -132,6 +133,8 @@ static int replace_node_name(char* sSrc, const char* sMatchStr, const char* sRep
|
|||
static void show_full_build_process(const char* errmg);
|
||||
static void backup_dw_file(const char* target_dir);
|
||||
void get_xlog_location(char (&xlog_location)[MAXPGPATH]);
|
||||
static void DeleteAlreadyDropedFile(const char* path, bool is_table_space);
|
||||
static int DeleteUnusedFile(const char* path, unsigned int SegNo, unsigned int fileNode);
|
||||
|
||||
/*
|
||||
* tblspaceDirectory is used for saving the table space directory created by
|
||||
|
|
@ -450,6 +453,7 @@ typedef struct {
|
|||
char* sysidentifier;
|
||||
int timeline;
|
||||
uint32 term;
|
||||
bool isBuildFromStandby;
|
||||
} logstreamer_param;
|
||||
|
||||
static int LogStreamerMain(logstreamer_param* param)
|
||||
|
|
@ -457,7 +461,11 @@ static int LogStreamerMain(logstreamer_param* param)
|
|||
int ret = 0;
|
||||
|
||||
/* get second connection info in child process for the sake of memmory leak */
|
||||
param->bgconn = check_and_conn(standby_connect_timeout, standby_recv_timeout, param->term);
|
||||
if (param->isBuildFromStandby) {
|
||||
param->bgconn = check_and_conn_for_standby(standby_connect_timeout, standby_recv_timeout, param->term);
|
||||
} else {
|
||||
param->bgconn = check_and_conn(standby_connect_timeout, standby_recv_timeout, param->term);
|
||||
}
|
||||
if (param->bgconn == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -501,6 +509,7 @@ void StartLogStreamer(
|
|||
param->timeline = timeline;
|
||||
param->sysidentifier = sysidentifier;
|
||||
param->term = primaryTerm;
|
||||
param->isBuildFromStandby = isBuildFromStandby;
|
||||
|
||||
/* Convert the starting position */
|
||||
if (sscanf_s(startpos, "%X/%X", &hi, &lo) != 2) {
|
||||
|
|
@ -814,7 +823,7 @@ static void ReceiveAndUnpackTarFile(PGconn* conn, PGresult* res, int rownum)
|
|||
/*
|
||||
* All files are padded up to 512 bytes
|
||||
*/
|
||||
if (current_len_left < 0 || current_len_left > LLONG_MAX - 511) {
|
||||
if (current_len_left < 0 || current_len_left > INT_MAX - 511) {
|
||||
pg_log(PG_WARNING, _("current_len_left is invalid\n"));
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
|
|
@ -1017,6 +1026,62 @@ bool CreateBuildtagFile(const char* fulltagname)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ModifyControlFile(const char* dirname)
|
||||
{
|
||||
ControlFileData controlFileNew;
|
||||
char controlFilePath[MAXPGPATH] = {0};
|
||||
size_t size = 0;
|
||||
int writelen;
|
||||
int fd = -1;
|
||||
int ss = 0;
|
||||
char* buffer = NULL;
|
||||
char writeBuf[PG_CONTROL_SIZE];
|
||||
errno_t errorNo = EOK;
|
||||
|
||||
buffer = slurpFile(dirname, "global/pg_control", &size);
|
||||
if (buffer == NULL) {
|
||||
pg_log(PG_WARNING, _("could not read anything from file pg_control. \n"));
|
||||
disconnect_and_exit(1);
|
||||
return false;
|
||||
}
|
||||
errorNo = memcpy_s(&controlFileNew, sizeof(ControlFileData), buffer, sizeof(ControlFileData));
|
||||
securec_check_c(errorNo, "\0", "\0");
|
||||
controlFileNew.state = DB_IN_ARCHIVE_RECOVERY;
|
||||
INIT_CRC32C(controlFileNew.crc);
|
||||
COMP_CRC32C(controlFileNew.crc, (char*)&controlFileNew, offsetof(ControlFileData, crc));
|
||||
FIN_CRC32C(controlFileNew.crc);
|
||||
errorNo = memset_s(writeBuf, PG_CONTROL_SIZE, 0, PG_CONTROL_SIZE);
|
||||
securec_check_c(errorNo, "", "");
|
||||
errorNo = memcpy_s(writeBuf, PG_CONTROL_SIZE, &controlFileNew, sizeof(ControlFileData));
|
||||
securec_check_c(errorNo, "", "");
|
||||
ss = snprintf_s(controlFilePath, MAXPGPATH, MAXPGPATH - 1, "%s/global/pg_control", dirname);
|
||||
securec_check_ss_c(ss, "\0", "\0");
|
||||
|
||||
int mode = O_WRONLY | O_CREAT | PG_BINARY;
|
||||
int flags = 0600;
|
||||
fd = open(controlFilePath, mode, flags);
|
||||
if (fd < 0) {
|
||||
pg_log(PG_WARNING, ("could not open pg_control file. \n"));
|
||||
disconnect_and_exit(1);
|
||||
return false;
|
||||
}
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
(void)close(fd);
|
||||
fd = -1;
|
||||
pg_log(PG_WARNING, "could not seek in target file \"%s\"\n", controlFilePath);
|
||||
disconnect_and_exit(1);
|
||||
return false;
|
||||
}
|
||||
writelen = write(fd, writeBuf, PG_CONTROL_SIZE);
|
||||
if (writelen != PG_CONTROL_SIZE) {
|
||||
pg_log(PG_WARNING, "could not write in target file \"%s\"\n", controlFilePath);
|
||||
disconnect_and_exit(1);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void BaseBackup(const char* dirname, uint32 term)
|
||||
{
|
||||
PGresult* res = NULL;
|
||||
|
|
@ -1027,6 +1092,8 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
char nodetablespacepath[MAXPGPATH] = {0};
|
||||
char nodetablespaceparentpath[MAXPGPATH] = {0};
|
||||
char escaped_label[MAXPGPATH] = {0};
|
||||
char basePath[MAXPGPATH] = {0};
|
||||
char tblspcPath[MAXPGPATH] = {0};
|
||||
int i;
|
||||
char xlogstart[MAXFNAMELEN] = {0};
|
||||
char xlogend[MAXFNAMELEN] = {0};
|
||||
|
|
@ -1056,7 +1123,11 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
get_conninfo(conf_file);
|
||||
|
||||
/* find a available conn */
|
||||
streamConn = check_and_conn(standby_connect_timeout, standby_recv_timeout, term);
|
||||
if (isBuildFromStandby) {
|
||||
streamConn = check_and_conn_for_standby(standby_connect_timeout, standby_recv_timeout, term);
|
||||
} else {
|
||||
streamConn = check_and_conn(standby_connect_timeout, standby_recv_timeout, term);
|
||||
}
|
||||
if (streamConn == NULL) {
|
||||
show_full_build_process("could not connect to server.");
|
||||
disconnect_and_exit(1);
|
||||
|
|
@ -1123,15 +1194,19 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
*/
|
||||
(void)PQsetRwTimeout(streamConn, Max(BUILD_RW_TIMEOUT, standby_recv_timeout));
|
||||
(void)PQescapeStringConn(streamConn, escaped_label, label, sizeof(escaped_label), &i);
|
||||
if (isBuildFromStandby) {
|
||||
fastcheckpoint = false;
|
||||
}
|
||||
nRet = snprintf_s(current_path,
|
||||
MAXPGPATH,
|
||||
sizeof(current_path) - 1,
|
||||
"BASE_BACKUP LABEL '%s' %s %s %s %s",
|
||||
"BASE_BACKUP LABEL '%s' %s %s %s %s %s",
|
||||
escaped_label,
|
||||
showprogress ? "PROGRESS" : "",
|
||||
includewal && !streamwal ? "WAL" : "",
|
||||
fastcheckpoint ? "FAST" : "",
|
||||
includewal ? "NOWAIT" : "");
|
||||
includewal ? "NOWAIT" : "",
|
||||
isBuildFromStandby ? "BUILDSTANDBY" : "");
|
||||
securec_check_ss_c(nRet, "", "");
|
||||
|
||||
if (PQsendQuery(streamConn, current_path) == 0) {
|
||||
|
|
@ -1436,6 +1511,13 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
PQfinish(streamConn);
|
||||
streamConn = NULL;
|
||||
|
||||
/* fsync all data come from source */
|
||||
if (!no_need_fsync) {
|
||||
show_full_build_process("starting fsync all files come from source.");
|
||||
(void) fsync_pgdata(basedir);
|
||||
show_full_build_process("finish fsync all files.");
|
||||
}
|
||||
|
||||
/* delete dw file if exists, recreate it and write a page of zero */
|
||||
backup_dw_file(dirname);
|
||||
show_full_build_process("build dummy dw file success");
|
||||
|
|
@ -1444,6 +1526,19 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
RENAME_BUILD_FILE(buildstart_file, builddone_file);
|
||||
|
||||
show_full_build_process("rename build status file success");
|
||||
|
||||
nRet = snprintf_s(basePath, MAXPGPATH, MAXPGPATH, "%s/base", dirname);
|
||||
securec_check_ss_c(nRet, "\0", "\0");
|
||||
DeleteAlreadyDropedFile(basePath, false);
|
||||
|
||||
nRet = snprintf_s(tblspcPath, MAXPGPATH, MAXPGPATH, "%s/pg_tblspc", dirname);
|
||||
securec_check_ss_c(nRet, "\0", "\0");
|
||||
DeleteAlreadyDropedFile(tblspcPath, true);
|
||||
|
||||
if (isBuildFromStandby) {
|
||||
(void)ModifyControlFile(dirname);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1452,13 +1547,14 @@ static void BaseBackup(const char* dirname, uint32 term)
|
|||
* Description :
|
||||
* Notes :
|
||||
*/
|
||||
void backup_main(char* dir, uint32 term)
|
||||
void backup_main(char* dir, uint32 term, bool isFromStandby)
|
||||
{
|
||||
if (dir == NULL) {
|
||||
pg_log(PG_PRINT, "%s: parameters dir is NULL.\n", progname);
|
||||
exit(1);
|
||||
} else {
|
||||
basedir = dir;
|
||||
isBuildFromStandby = isFromStandby;
|
||||
}
|
||||
/* program name */
|
||||
progname = "gs_ctl";
|
||||
|
|
@ -1949,3 +2045,110 @@ void get_xlog_location(char (&xlog_location)[MAXPGPATH])
|
|||
}
|
||||
xlog_location[MAXPGPATH - 1] = '\0';
|
||||
}
|
||||
|
||||
static void DeleteAlreadyDropedFile(const char* path, bool is_table_space)
|
||||
{
|
||||
char* fileName = NULL;
|
||||
char pathbuf[MAXPGPATH] = {0};
|
||||
unsigned int fileNode = 0;
|
||||
unsigned int spaceNode = 0;
|
||||
unsigned int SegNo = 0;
|
||||
unsigned int dbNode = 0;
|
||||
struct stat statbuf;
|
||||
struct dirent *de = NULL;
|
||||
int nmatch = 0;
|
||||
int res = -1;
|
||||
int rc = 0;
|
||||
|
||||
DIR *dir = opendir(path);
|
||||
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
/* skip entries point current dir or parent dir */
|
||||
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
|
||||
continue;
|
||||
rc = snprintf_s(pathbuf, MAXPGPATH, MAXPGPATH - 1, "%s/%s", path, de->d_name);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
if (lstat(pathbuf, &statbuf) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
pg_log(PG_WARNING, _("could not lstat file or directory : %s!\n"), de->d_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
DeleteAlreadyDropedFile(pathbuf, is_table_space);
|
||||
} else if (S_ISREG(statbuf.st_mode)) {
|
||||
if (is_table_space) {
|
||||
if ((fileName = strstr(pathbuf, "pg_tblspc/")) != NULL) {
|
||||
nmatch = sscanf_s(fileName, "pg_tblspc/%u/%*[^/]/%u/%u.%u", &spaceNode,
|
||||
&dbNode, &fileNode, &SegNo);
|
||||
if (nmatch == 4) {
|
||||
res = DeleteUnusedFile(path, SegNo, fileNode);
|
||||
if (res < 0) {
|
||||
(void)closedir(dir);
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((fileName = strstr(pathbuf, "base/")) != NULL) {
|
||||
nmatch = sscanf_s(fileName, "base/%u/%u.%u", &dbNode, &fileNode, &SegNo);
|
||||
if (nmatch == 3) {
|
||||
res = DeleteUnusedFile(path, SegNo, fileNode);
|
||||
if (res < 0) {
|
||||
(void)closedir(dir);
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)closedir(dir);
|
||||
}
|
||||
|
||||
static int DeleteUnusedFile(const char* path, unsigned int SegNo, unsigned int fileNode)
|
||||
{
|
||||
char firstFileName[MAXPGPATH] = {0};
|
||||
char beforeFileName[MAXPGPATH] = {0};
|
||||
char currentFileName[MAXPGPATH] = {0};
|
||||
struct stat statbuf;
|
||||
struct stat tmpStatBuf;
|
||||
int rc = 0;
|
||||
|
||||
rc = snprintf_s(currentFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
rc = snprintf_s(firstFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u", path, fileNode);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
if (lstat(firstFileName, &statbuf) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
pg_log(PG_WARNING, _("could not lstat file: %s!\n"), firstFileName);
|
||||
return -1;
|
||||
} else {
|
||||
while (SegNo >= 1) {
|
||||
rc = snprintf_s(currentFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
if (lstat(currentFileName, &tmpStatBuf) == 0) {
|
||||
pg_log(PG_DEBUG, _("the file %s should be unlink without origin file\n"), currentFileName);
|
||||
unlink(currentFileName);
|
||||
}
|
||||
SegNo--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (statbuf.st_size == 0) {
|
||||
while (SegNo > 1) {
|
||||
SegNo -= 1;
|
||||
rc = snprintf_s(beforeFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
if (lstat(beforeFileName, &tmpStatBuf) != 0) {
|
||||
if (errno == ENOENT) {
|
||||
pg_log(PG_DEBUG, _("the file %s before file does not exist\n"), currentFileName);
|
||||
unlink(currentFileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ extern int standby_connect_timeout;
|
|||
extern int standby_message_timeout;
|
||||
|
||||
extern char* conn_str;
|
||||
extern bool no_need_fsync;
|
||||
extern pid_t process_id;
|
||||
extern char* basedir;
|
||||
extern int bgpipe[2];
|
||||
extern pid_t bgchild;
|
||||
|
||||
extern char* formatLogTime();
|
||||
void backup_main(char* dir, uint32 term);
|
||||
void backup_main(char* dir, uint32 term, bool isFromStandby);
|
||||
void backup_incremental_xlog(char* dir);
|
||||
void get_xlog_location(char (&xlog_location)[MAXPGPATH]);
|
||||
bool CreateBuildtagFile(const char* fulltagname);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ int g_replication_type = -1;
|
|||
#define RT_WITH_DUMMY_STANDBY 0
|
||||
#define RT_WITH_MULTI_STANDBY 1
|
||||
|
||||
static void walkdir(const char *path, int (*action) (const char *fname, bool isdir), bool process_symlinks);
|
||||
|
||||
int32 pg_atoi(const char* s, int size, int c)
|
||||
{
|
||||
long l;
|
||||
|
|
@ -873,6 +875,74 @@ PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term)
|
|||
return con_get;
|
||||
}
|
||||
|
||||
/* check connection for standby build standby */
|
||||
PGconn* check_and_conn_for_standby(int conn_timeout, int recv_timeout, uint32 term)
|
||||
{
|
||||
PGconn* con_get = NULL;
|
||||
char repl_conninfo_str[MAXPGPATH];
|
||||
ServerMode remote_mode = UNKNOWN_MODE;
|
||||
int tnRet = 0;
|
||||
int repl_arr_length;
|
||||
int i = 0;
|
||||
int parse_failed_num = 0;
|
||||
|
||||
for (i = 1; i < MAX_REPLNODE_NUM; i++) {
|
||||
ReplConnInfo* repl_conn_info = ParseReplConnInfo(conninfo_global[i - 1], &repl_arr_length);
|
||||
if (repl_conn_info == NULL) {
|
||||
parse_failed_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
tnRet = memset_s(repl_conninfo_str, MAXPGPATH, 0, MAXPGPATH);
|
||||
securec_check_ss_c(tnRet, "", "");
|
||||
|
||||
tnRet = snprintf_s(repl_conninfo_str,
|
||||
sizeof(repl_conninfo_str),
|
||||
sizeof(repl_conninfo_str) - 1,
|
||||
"localhost=%s localport=%d host=%s port=%d "
|
||||
"dbname=replication replication=true "
|
||||
"fallback_application_name=gs_ctl "
|
||||
"connect_timeout=%d rw_timeout=%d "
|
||||
"options='-c remotetype=application'",
|
||||
repl_conn_info->localhost,
|
||||
repl_conn_info->localport,
|
||||
repl_conn_info->remotehost,
|
||||
repl_conn_info->remoteport,
|
||||
conn_timeout,
|
||||
recv_timeout);
|
||||
securec_check_ss_c(tnRet, "", "");
|
||||
|
||||
free(repl_conn_info);
|
||||
repl_conn_info = NULL;
|
||||
con_get = PQconnectdb(repl_conninfo_str);
|
||||
if (con_get != NULL && PQstatus(con_get) == CONNECTION_OK && check_remote_version(con_get, term)) {
|
||||
remote_mode = get_remote_mode(con_get);
|
||||
if (remote_mode == STANDBY_MODE && (g_replconn_idx == -1 || i == g_replconn_idx)) {
|
||||
g_replconn_idx = i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (conn_str != NULL) {
|
||||
pg_log(PG_WARNING, "The given address can not been access.\n");
|
||||
if (con_get != NULL) {
|
||||
PQfinish(con_get);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_failed_num == MAX_REPLNODE_NUM - 1) {
|
||||
pg_log(PG_WARNING, "Invalid value for parameter \"replconninfo\" in postgresql.conf or no correct standby.\n");
|
||||
if (con_get != NULL) {
|
||||
PQfinish(con_get);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return con_get;
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief : @@GaussDB@@
|
||||
* Description : find the value of guc para according to name
|
||||
|
|
@ -1452,3 +1522,178 @@ bool libpqRotateCbmFile(PGconn* connObj, XLogRecPtr lsn)
|
|||
return ec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue fsync recursively on PGDATA and all its contents.
|
||||
*
|
||||
* We fsync regular files and directories wherever they are, but we follow
|
||||
* symlinks only for pg_wal (or pg_xlog) and immediately under pg_tblspc.
|
||||
* Other symlinks are presumed to point at files we're not responsible for
|
||||
* fsyncing, and might not have privileges to write at all.
|
||||
*
|
||||
*/
|
||||
void fsync_pgdata(const char *pg_data)
|
||||
{
|
||||
bool xlog_is_symlink = false;
|
||||
char pg_xlog[MAXPGPATH] = {0};
|
||||
char pg_tblspc[MAXPGPATH] = {0};
|
||||
errno_t errorno = EOK;
|
||||
|
||||
errorno = snprintf_s(pg_xlog, MAXPGPATH, MAXPGPATH - 1, "%s/pg_xlog", pg_data);
|
||||
securec_check_ss_c(errorno, "\0", "\0");
|
||||
errorno = snprintf_s(pg_tblspc, MAXPGPATH, MAXPGPATH - 1, "%s/pg_tblspc", pg_data);
|
||||
securec_check_ss_c(errorno, "\0", "\0");
|
||||
|
||||
#ifndef WIN32
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (lstat(pg_xlog, &st) < 0) {
|
||||
pg_log(PG_WARNING, _("could not stat file \"%s\": %m\n"), pg_xlog);
|
||||
exit(1);
|
||||
}
|
||||
else if (S_ISLNK(st.st_mode))
|
||||
xlog_is_symlink = true;
|
||||
}
|
||||
#else
|
||||
if (pgwin32_is_junction(pg_xlog))
|
||||
xlog_is_symlink = true;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now we do the fsync()s in the same order.
|
||||
*
|
||||
* The main call ignores symlinks, so in addition to specially processing
|
||||
* pg_wal if it's a symlink, pg_tblspc has to be visited separately with
|
||||
* process_symlinks = true. Note that if there are any plain directories
|
||||
* in pg_tblspc, they'll get fsync'd twice. That's not an expected case
|
||||
* so we don't worry about optimizing it.
|
||||
*/
|
||||
walkdir(pg_data, fsync_fname, false);
|
||||
if (xlog_is_symlink)
|
||||
walkdir(pg_xlog, fsync_fname, false);
|
||||
walkdir(pg_tblspc, fsync_fname, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* walkdir: recursively walk a directory, applying the action to each
|
||||
* regular file and directory (including the named directory itself).
|
||||
*
|
||||
* If process_symlinks is true, the action and recursion are also applied
|
||||
* to regular files and directories that are pointed to by symlinks in the
|
||||
* given directory; otherwise symlinks are ignored. Symlinks are always
|
||||
* ignored in subdirectories, ie we intentionally don't pass down the
|
||||
* process_symlinks flag to recursive calls.
|
||||
*
|
||||
* Errors are reported but not considered fatal.
|
||||
*
|
||||
* See also walkdir in fd.cpp, which is a backend version of this logic.
|
||||
*/
|
||||
static void walkdir(const char *path, int (*action) (const char *fname, bool isdir), bool process_symlinks)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *de = NULL;
|
||||
errno_t errorno = EOK;
|
||||
|
||||
dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
pg_log(PG_WARNING, _("could not open directory \"%s\": %m\n"), path);
|
||||
return;
|
||||
}
|
||||
|
||||
while (errno = 0, (de = readdir(dir)) != NULL) {
|
||||
char subpath[MAXPGPATH * 2] = {0};
|
||||
struct stat fst;
|
||||
int sret;
|
||||
|
||||
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(de->d_name, "pg_ctl.lock") == 0) {
|
||||
continue;
|
||||
}
|
||||
errorno = snprintf_s(subpath, sizeof(subpath), sizeof(subpath) - 1, "%s/%s", path, de->d_name);
|
||||
securec_check_ss_c(errorno, "\0", "\0");
|
||||
|
||||
if (process_symlinks)
|
||||
sret = stat(subpath, &fst);
|
||||
else
|
||||
sret = lstat(subpath, &fst);
|
||||
if (sret < 0) {
|
||||
pg_log(PG_WARNING, _("could not stat file \"%s\": %m\n"), subpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISREG(fst.st_mode))
|
||||
(*action) (subpath, false);
|
||||
else if (S_ISDIR(fst.st_mode))
|
||||
walkdir(subpath, action, false);
|
||||
}
|
||||
|
||||
if (errno)
|
||||
pg_log(PG_WARNING, _("could not read directory \"%s\": %m\n"), path);
|
||||
|
||||
(void)closedir(dir);
|
||||
|
||||
/*
|
||||
* It's important to fsync the destination directory itself as individual
|
||||
* file fsyncs don't guarantee that the directory entry for the file is
|
||||
* synced. Recent versions of ext4 have made the window much wider but
|
||||
* it's been an issue for ext3 and other filesystems in the past.
|
||||
*/
|
||||
(*action) (path, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* fsync_fname -- Try to fsync a file or directory
|
||||
*
|
||||
* Ignores errors trying to open unreadable files, or trying to fsync
|
||||
* directories on systems where that isn't allowed/required. All other errors
|
||||
* are fatal.
|
||||
*/
|
||||
int fsync_fname(const char *fname, bool isdir)
|
||||
{
|
||||
int fd = -1;
|
||||
int flags;
|
||||
int returncode;
|
||||
|
||||
/*
|
||||
* Some OSs require directories to be opened read-only whereas other
|
||||
* systems don't allow us to fsync files opened read-only; so we need both
|
||||
* cases here. Using O_RDWR will cause us to fail to fsync files that are
|
||||
* not writable by our userid, but we assume that's OK.
|
||||
*/
|
||||
flags = PG_BINARY;
|
||||
if (!isdir)
|
||||
flags |= O_RDWR;
|
||||
else
|
||||
flags |= O_RDONLY;
|
||||
|
||||
/*
|
||||
* Open the file, silently ignoring errors about unreadable files (or
|
||||
* unsupported operations, e.g. opening a directory under Windows), and
|
||||
* logging others.
|
||||
*/
|
||||
fd = open(fname, flags, 0);
|
||||
if (fd < 0) {
|
||||
if (errno == EACCES || (isdir && errno == EISDIR))
|
||||
return 0;
|
||||
pg_log(PG_WARNING, _("could not open file \"%s\": %m\n"), fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
returncode = fsync(fd);
|
||||
|
||||
/*
|
||||
* Some OSes don't allow us to fsync directories at all, so we can ignore
|
||||
* those errors. Anything else needs to be reported.
|
||||
*/
|
||||
if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL))) {
|
||||
pg_log(PG_WARNING, _("could not fsync file \"%s\": %m\n"), fname);
|
||||
(void) close(fd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ int find_gucoption(
|
|||
void get_conninfo(const char* filename);
|
||||
|
||||
extern PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term = 0);
|
||||
extern PGconn* check_and_conn_for_standby(int conn_timeout, int recv_timeout, uint32 term = 0);
|
||||
int GetLengthAndCheckReplConn(const char* ConnInfoList);
|
||||
|
||||
extern int replconn_num;
|
||||
|
|
@ -60,5 +61,7 @@ extern char* pg_strdup(const char* in);
|
|||
extern void pg_free(void* ptr);
|
||||
extern void get_slot_name(char* slotname, size_t len);
|
||||
extern bool libpqRotateCbmFile(PGconn* connObj, XLogRecPtr lsn);
|
||||
extern int fsync_fname(const char *fname, bool isdir);
|
||||
extern void fsync_pgdata(const char *pg_data);
|
||||
|
||||
#endif /* PG_BUILD_H */
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ static char switchover_file[MAXPGPATH];
|
|||
static char promote_file[MAXPGPATH];
|
||||
static char primary_file[MAXPGPATH];
|
||||
static char standby_file[MAXPGPATH];
|
||||
static char cascade_standby_file[MAXPGPATH];
|
||||
static char pg_ctl_lockfile[MAXPGPATH];
|
||||
static char pg_conf_file[MAXPGPATH];
|
||||
static FILE* lockfile = NULL;
|
||||
|
|
@ -184,6 +185,7 @@ char gaussdb_state_file[MAXPGPATH] = {0};
|
|||
|
||||
static char postport_lock_file[MAXPGPATH];
|
||||
static PGconn* dbConn = NULL;
|
||||
bool no_need_fsync = false;
|
||||
pid_t process_id = 0;
|
||||
|
||||
const int g_length_stop_char = 2;
|
||||
|
|
@ -2146,6 +2148,10 @@ static void do_notify(uint32 term)
|
|||
pgha_str[strlen("primary")] == '\0') {
|
||||
notify_file = xstrdup(primary_file);
|
||||
notify_mode = PRIMARY_MODE;
|
||||
} else if ((pgha_str != NULL) && 0 == strncmp(pgha_str, "cascade_standby", strlen("cascade_standby")) &&
|
||||
pgha_str[strlen("cascade_standby")] == '\0') {
|
||||
notify_file = xstrdup(cascade_standby_file);
|
||||
notify_mode = CASCADE_STANDBY_MODE;
|
||||
} else {
|
||||
pg_log(PG_WARNING, _(" the parameter of notify is not recognized\n"));
|
||||
exit(1);
|
||||
|
|
@ -3498,8 +3504,9 @@ static void do_help(void)
|
|||
(void)printf(_(" %s hotpatch [-D DATADIR] [-a ACTION] [-n NAME]\n"), progname);
|
||||
#endif
|
||||
printf(_("\nCommon options:\n"));
|
||||
printf(_(" -b, --mode=MODE the mode of building the datanode.MODE can be \"full\", \"incremental\", "
|
||||
"\"auto\"\n"));
|
||||
printf(_(" -b, --mode=MODE the mode of building the datanode or coordinator."
|
||||
"MODE can be \"full\", \"incremental\", "
|
||||
"\"auto\", \"standby_full\"\n"));
|
||||
printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
|
||||
printf(_(" -s, --silent only print errors, no informational messages\n"));
|
||||
printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
|
||||
|
|
@ -3576,7 +3583,7 @@ static void do_help(void)
|
|||
#endif
|
||||
printf(_("\nBuild connection option:\n"));
|
||||
printf(_(" -r, --recvtimeout=INTERVAL time that receiver waits for communication from server (in seconds)\n"));
|
||||
printf(_(" -C, connector CN/DN connect to CN for build\n"));
|
||||
printf(_(" -C, connector CN/DN connect to specified CN/DN for build\n"));
|
||||
|
||||
#if ((defined(ENABLE_MULTIPLE_NODES)) || (defined(ENABLE_PRIVATEGAUSS)))
|
||||
printf("\nReport bugs to GaussDB support.\n");
|
||||
|
|
@ -3785,6 +3792,8 @@ static char* get_localrole_string(ServerMode mode)
|
|||
return "Primary";
|
||||
case STANDBY_MODE:
|
||||
return "Standby";
|
||||
case CASCADE_STANDBY_MODE:
|
||||
return "Cascade Standby";
|
||||
case PENDING_MODE:
|
||||
return "Pending";
|
||||
default:
|
||||
|
|
@ -3833,7 +3842,7 @@ static void do_build_stop(pgpid_t pid)
|
|||
}
|
||||
|
||||
do_wait = true;
|
||||
if (build_mode == FULL_BUILD) {
|
||||
if (build_mode == FULL_BUILD || build_mode == STANDBY_FULL_BUILD) {
|
||||
shutdown_mode = IMMEDIATE_MODE;
|
||||
sig = SIGQUIT;
|
||||
do_stop(true);
|
||||
|
|
@ -3918,6 +3927,11 @@ static void do_build(uint32 term)
|
|||
createRewindFile(pg_data);
|
||||
do_incremental_build_xlog();
|
||||
}
|
||||
/* standby DN full build from standby DN */
|
||||
else if (build_mode == STANDBY_FULL_BUILD) {
|
||||
createRewindFile(pg_data);
|
||||
do_actual_build(term);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_restore(void)
|
||||
|
|
@ -3980,7 +3994,7 @@ static void do_incremental_build(uint32 term)
|
|||
/* Concate connection str to primary host for performing rewind. */
|
||||
errorno = sprintf_s(connstrSource,
|
||||
sizeof(connstrSource),
|
||||
"host=%s port=%s dbname=postgres application_name=gs_rewind connect_timeout=5",
|
||||
"host=%s port=%s dbname=postgres application_name=gs_rewind connect_timeout=5 rw_timeout=600",
|
||||
(streamConn->pghost != NULL) ? streamConn->pghost : streamConn->pghostaddr,
|
||||
streamConn->pgport);
|
||||
securec_check_ss_c(errorno, "\0", "\0");
|
||||
|
|
@ -4165,7 +4179,11 @@ static void do_actual_build(uint32 term)
|
|||
|
||||
read_ssl_confval();
|
||||
|
||||
backup_main(pg_data, term);
|
||||
if (build_mode == STANDBY_FULL_BUILD) {
|
||||
backup_main(pg_data, term, true);
|
||||
} else {
|
||||
backup_main(pg_data, term, false);
|
||||
}
|
||||
|
||||
pg_log(PG_WARNING, _("build completed(%s).\n"), pg_data);
|
||||
|
||||
|
|
@ -4174,7 +4192,7 @@ static void do_actual_build(uint32 term)
|
|||
* Standby DN incremental build from Primary DN auto start.
|
||||
* If connect string is not empty,CN/DN will be started by caller.
|
||||
*/
|
||||
if (conn_str == NULL) {
|
||||
if (conn_str == NULL || (build_mode == STANDBY_FULL_BUILD && conn_str != NULL)) {
|
||||
/* cascade standby will use use pgha_opt directly */
|
||||
if (pgha_opt == NULL || strstr(pgha_opt, "cascade_standby") == NULL) {
|
||||
/* pg_ctl start -M standby */
|
||||
|
|
@ -4637,6 +4655,7 @@ int main(int argc, char** argv)
|
|||
{"connect-string", required_argument, NULL, 'C'},
|
||||
{"remove-backup", no_argument, NULL, 1},
|
||||
{"action", required_argument, NULL, 'a'},
|
||||
{"no-fsync", no_argument, NULL, 3},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
int option_index;
|
||||
|
|
@ -4711,16 +4730,19 @@ int main(int argc, char** argv)
|
|||
argc, argv, "a:b:cD:l:m:M:N:n:o:p:P:r:sS:t:U:wWZ:dqL:T:", long_options, &option_index)) != -1)
|
||||
#else
|
||||
while ((c = getopt_long(
|
||||
argc, argv, "b:cD:l:m:M:N:o:p:P:r:sS:t:U:wWZ:dqL:T:", long_options, &option_index)) != -1)
|
||||
argc, argv, "b:cD:l:m:M:N:o:p:P:r:sS:t:U:wWZ:C:dqL:T:", long_options, &option_index)) != -1)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
switch (c) {
|
||||
case 'b': {
|
||||
if (strcmp(optarg, "full") == 0)
|
||||
if (strcmp(optarg, "full") == 0) {
|
||||
build_mode = FULL_BUILD;
|
||||
else if (strcmp(optarg, "incremental") == 0)
|
||||
} else if (strcmp(optarg, "incremental") == 0) {
|
||||
build_mode = INC_BUILD;
|
||||
} else if (strcmp(optarg, "standby_full") == 0) {
|
||||
build_mode = STANDBY_FULL_BUILD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'D': {
|
||||
|
|
@ -4923,6 +4945,9 @@ int main(int argc, char** argv)
|
|||
case 1:
|
||||
clear_backup_dir = true;
|
||||
break;
|
||||
case 3:
|
||||
no_need_fsync = true;
|
||||
break;
|
||||
default:
|
||||
/* getopt_long already issued a suitable error message */
|
||||
do_advice();
|
||||
|
|
@ -5094,6 +5119,8 @@ int main(int argc, char** argv)
|
|||
securec_check_ss_c(ret, "\0", "\0");
|
||||
ret = snprintf_s(standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/standby", pg_data);
|
||||
securec_check_ss_c(ret, "\0", "\0");
|
||||
ret = snprintf_s(cascade_standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/cascade_standby", pg_data);
|
||||
securec_check_ss_c(ret, "\0", "\0");
|
||||
ret = snprintf_s(pg_ctl_lockfile, MAXPGPATH, MAXPGPATH - 1, "%s/pg_ctl.lock", pg_data);
|
||||
securec_check_ss_c(ret, "\0", "\0");
|
||||
ret = snprintf_s(pg_conf_file, MAXPGPATH, MAXPGPATH - 1, "%s/postgresql.conf", pg_data);
|
||||
|
|
@ -5208,17 +5235,38 @@ int main(int argc, char** argv)
|
|||
break;
|
||||
#endif
|
||||
case BUILD_COMMAND:
|
||||
if (conn_str != NULL)
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl %s build ,datadir is %s,conn_str is \'%s\'\n"),
|
||||
build_mode == FULL_BUILD ? "full" : "incremental",
|
||||
pg_data,
|
||||
conn_str);
|
||||
else
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl %s build ,datadir is %s\n"),
|
||||
build_mode == FULL_BUILD ? "full" : "incremental",
|
||||
pg_data);
|
||||
if (conn_str != NULL) {
|
||||
if (build_mode == FULL_BUILD) {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl full build ,datadir is %s,conn_str is \'%s\'\n"),
|
||||
pg_data,
|
||||
conn_str);
|
||||
} else if (build_mode == STANDBY_FULL_BUILD) {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl standby full build ,datadir is %s,conn_str is \'%s\'\n"),
|
||||
pg_data,
|
||||
conn_str);
|
||||
} else {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl incremental build ,datadir is %s,conn_str is \'%s\'\n"),
|
||||
pg_data,
|
||||
conn_str);
|
||||
}
|
||||
} else {
|
||||
if (build_mode == FULL_BUILD) {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl full build ,datadir is %s\n"),
|
||||
pg_data);
|
||||
} else if (build_mode == STANDBY_FULL_BUILD) {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl standby full build ,datadir is %s\n"),
|
||||
pg_data);
|
||||
} else {
|
||||
pg_log(PG_PROGRESS,
|
||||
_("gs_ctl incremental build ,datadir is %s\n"),
|
||||
pg_data);
|
||||
}
|
||||
}
|
||||
if (-1 != pg_ctl_lock(pg_ctl_lockfile, &lockfile)) {
|
||||
do_build(term);
|
||||
(void)pg_ctl_unlock(lockfile);
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ bool ReceiveXlogStream(PGconn* conn, XLogRecPtr startpos, uint32 timeline, const
|
|||
FD_ZERO(&input_mask);
|
||||
FD_SET(PQsocket(conn), &input_mask);
|
||||
if (standby_message_timeout) {
|
||||
timeout.tv_sec = last_status + standby_message_timeout - local_now - 1;
|
||||
timeout.tv_sec = last_status + (standby_message_timeout / 2) - local_now - 1;
|
||||
if (timeout.tv_sec <= 0)
|
||||
timeout.tv_sec = 1; /* Always sleep at least 1 sec */
|
||||
timeout.tv_usec = 0;
|
||||
|
|
|
|||
|
|
@ -728,7 +728,7 @@ int main(int argc, char** argv)
|
|||
errorMessages = ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password, false);
|
||||
if (errorMessages != NULL) {
|
||||
(void)remove(filename);
|
||||
filename = NULL;
|
||||
GS_FREE(filename);
|
||||
exit_horribly(NULL, "connection to database \"%s\" failed: %s ",
|
||||
((dbname != NULL) ? dbname : ""), errorMessages);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
#include "file.h"
|
||||
#include "common/fe_memutils.h"
|
||||
|
||||
/* list of dirs which will not to be backuped
|
||||
it will be backuped up in external dirs */
|
||||
parray *pgdata_nobackup_dir = NULL;
|
||||
|
||||
static int standby_message_timeout_local = 10 ; /* 10 sec = default */
|
||||
static XLogRecPtr stop_backup_lsn = InvalidXLogRecPtr;
|
||||
static XLogRecPtr stop_stream_lsn = InvalidXLogRecPtr;
|
||||
|
|
@ -740,6 +744,11 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
|
|||
if (external_dirs)
|
||||
free_dir_list(external_dirs);
|
||||
|
||||
if (pgdata_nobackup_dir) {
|
||||
free_dir_list(pgdata_nobackup_dir);
|
||||
}
|
||||
pgdata_nobackup_dir = NULL;
|
||||
|
||||
/* Cleanup */
|
||||
if (backup_list)
|
||||
{
|
||||
|
|
@ -786,7 +795,7 @@ pgdata_basic_setup(const ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
|
|||
exclusive_backup = true;
|
||||
}
|
||||
|
||||
current.checksum_version = 0;
|
||||
current.checksum_version = 1;
|
||||
|
||||
nodeInfo->checksum_version = current.checksum_version;
|
||||
|
||||
|
|
@ -1223,10 +1232,20 @@ void tryToFindCompressedWALFile(bool *file_exists, char *gz_wal_segment_path, ch
|
|||
#ifdef HAVE_LIBZ
|
||||
*file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST);
|
||||
if (*file_exists)
|
||||
{
|
||||
elog(LOG, "Found compressed WAL segment: %s", wal_segment_path);
|
||||
if (current.from_replica)
|
||||
{
|
||||
elog(INFO, "Wait a few minutes to get the target LSN or the last valid record prior to the target LSN");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
elog(LOG, "Found WAL segment: %s", wal_segment_path);
|
||||
if (current.from_replica)
|
||||
{
|
||||
elog(INFO, "Wait a few minutes to get the target LSN or the last valid record prior to the target LSN");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1263,11 +1282,13 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
XLogSegNo targetSegNo;
|
||||
char pg_wal_dir[MAXPGPATH];
|
||||
char wal_segment_path[MAXPGPATH],
|
||||
partial_file[MAXPGPATH],
|
||||
*wal_segment_dir,
|
||||
wal_segment[MAXFNAMELEN];
|
||||
bool file_exists = false;
|
||||
uint32 try_count = 0,
|
||||
timeout;
|
||||
int rc = 0;
|
||||
const char *wal_delivery_str = (const char *)(in_stream_dir ? "streamed":"archived");
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
|
|
@ -1301,6 +1322,8 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
join_path_components(wal_segment_path, arclog_path, wal_segment);
|
||||
wal_segment_dir = arclog_path;
|
||||
}
|
||||
rc = sprintf_s(partial_file, MAXPGPATH, "%s.partial", wal_segment_path);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
|
||||
/* TODO: remove this in 3.0 (it is a cludge against some old bug with archive_timeout) */
|
||||
timeout = (instance_config.archive_timeout > 0) ? instance_config.archive_timeout : ARCHIVE_TIMEOUT_DEFAULT;
|
||||
|
|
@ -1323,6 +1346,10 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
if (!file_exists)
|
||||
{
|
||||
file_exists = fileExists(wal_segment_path, FIO_BACKUP_HOST);
|
||||
if(!file_exists)
|
||||
{
|
||||
file_exists = fileExists(partial_file, FIO_BACKUP_HOST);
|
||||
}
|
||||
tryToFindCompressedWALFile(&file_exists, gz_wal_segment_path, wal_segment_path);
|
||||
}
|
||||
|
||||
|
|
@ -2391,6 +2418,7 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
|
|||
int i = 0;
|
||||
int j = 0;
|
||||
char *tablespace_path = NULL;
|
||||
bool in_pgdata = false;
|
||||
const char *query = (const char *)"SELECT pg_catalog.pg_tablespace_location(oid) "
|
||||
"FROM pg_catalog.pg_tablespace;";
|
||||
|
||||
|
|
@ -2400,13 +2428,23 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
|
|||
if (!res)
|
||||
elog(ERROR, "Failed to get list of tablespaces");
|
||||
|
||||
pgdata_nobackup_dir = parray_new();
|
||||
|
||||
for (i = 0; i < res->ntups; i++)
|
||||
{
|
||||
char full_path[MAXPGPATH] = {0};
|
||||
char rel_path[MAXPGPATH] = {0};
|
||||
tablespace_path = PQgetvalue(res, i, 0);
|
||||
if (strlen(tablespace_path) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_absolute_path(tablespace_path)) {
|
||||
join_path_components(rel_path, PG_RELATIVE_TBLSPC_DIR, tablespace_path);
|
||||
join_path_components(full_path, instance_config.pgdata, rel_path);
|
||||
tablespace_path = full_path;
|
||||
}
|
||||
|
||||
canonicalize_path(tablespace_path);
|
||||
|
||||
for (j = 0; j < (int)parray_num(external_list); j++)
|
||||
|
|
@ -2421,6 +2459,13 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
|
|||
elog(WARNING, "External directory path (-E option) \"%s\" "
|
||||
"is in tablespace directory \"%s\"",
|
||||
tablespace_path, external_path);
|
||||
|
||||
in_pgdata = path_is_prefix_of_path(instance_config.pgdata, external_path);
|
||||
if (in_pgdata &&
|
||||
strcmp(external_path, tablespace_path) == 0) {
|
||||
char *no_backup_dir = pg_strdup(rel_path);
|
||||
parray_append(pgdata_nobackup_dir, no_backup_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
PQclear(res);
|
||||
|
|
@ -2507,9 +2552,9 @@ static bool PathContainPath(const char* path1, const char* path2)
|
|||
size_t path2Len = strlen(path2);
|
||||
if (path1Len == path2Len) {
|
||||
return false;
|
||||
} else if ((path2Len == (path1Len + 1)) && !IS_DIR_SEP(path2[path1Len - 1])) {
|
||||
} else if ((path2Len >= (path1Len + 1)) && !IS_DIR_SEP(path2[path1Len])) {
|
||||
return false;
|
||||
} else if ((path2Len == (path1Len + 1)) && IS_DIR_SEP(path2[path1Len - 1])) {
|
||||
} else if ((path2Len >= (path1Len + 1)) && IS_DIR_SEP(path2[path1Len])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -215,6 +215,11 @@ ConfigOption instance_options[] =
|
|||
&instance_config.remote.ssh_config, SOURCE_CMD, (OptionSource)0,
|
||||
OPTION_REMOTE_GROUP, 0, option_get_value
|
||||
},
|
||||
{
|
||||
's', 231, "remote-libpath",
|
||||
&instance_config.remote.libpath, SOURCE_CMD, (OptionSource)0,
|
||||
OPTION_REMOTE_GROUP, 0, option_get_value
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
|
@ -506,6 +511,10 @@ readInstanceConfigFile(const char *instance_name)
|
|||
's', 230, "ssh-config", &instance->remote.ssh_config, SOURCE_CMD, (OptionSource)0,
|
||||
OPTION_REMOTE_GROUP, 0, option_get_value
|
||||
},
|
||||
{
|
||||
's', 231, "remote-libpath", &instance->remote.libpath, SOURCE_CMD, (OptionSource)0,
|
||||
OPTION_REMOTE_GROUP, 0, option_get_value
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,90 @@ typedef struct DataPage
|
|||
char data[BLCKSZ];
|
||||
} DataPage;
|
||||
|
||||
uint32 CHECK_STEP = 2;
|
||||
static bool get_page_header(FILE *in, const char *fullpath, BackupPageHeader* bph,
|
||||
pg_crc32 *crc, bool use_crc32c);
|
||||
|
||||
static inline uint32 pg_checksum_init(uint32 seed, uint32 value)
|
||||
{
|
||||
CHECKSUM_COMP(seed, value);
|
||||
return seed;
|
||||
}
|
||||
|
||||
uint32 pg_checksum_block(char* data, uint32 size)
|
||||
{
|
||||
uint32 sums[N_SUMS];
|
||||
uint32* dataArr = (uint32*)data;
|
||||
uint32 result = 0;
|
||||
uint32 i, j;
|
||||
|
||||
/* ensure that the size is compatible with the algorithm */
|
||||
Assert((size % (sizeof(uint32) * N_SUMS)) == 0);
|
||||
|
||||
/* initialize partial checksums to their corresponding offsets */
|
||||
for (j = 0; j < N_SUMS; j += CHECK_STEP) {
|
||||
sums[j] = pg_checksum_init(g_checksumBaseOffsets[j], dataArr[j]);
|
||||
sums[j + 1] = pg_checksum_init(g_checksumBaseOffsets[j + 1], dataArr[j + 1]);
|
||||
}
|
||||
dataArr += N_SUMS;
|
||||
|
||||
/* main checksum calculation */
|
||||
for (i = 1; i < size / (sizeof(uint32) * N_SUMS); i++) {
|
||||
for (j = 0; j < N_SUMS; j += CHECK_STEP) {
|
||||
CHECKSUM_COMP(sums[j], dataArr[j]);
|
||||
CHECKSUM_COMP(sums[j + 1], dataArr[j + 1]);
|
||||
}
|
||||
dataArr += N_SUMS;
|
||||
}
|
||||
|
||||
/* finally add in two rounds of zeroes for additional mixing */
|
||||
for (j = 0; j < N_SUMS; j++) {
|
||||
CHECKSUM_COMP(sums[j], 0);
|
||||
CHECKSUM_COMP(sums[j], 0);
|
||||
|
||||
/* xor fold partial checksums together */
|
||||
result ^= sums[j];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the checksum for a openGauss page. The page must be aligned on a
|
||||
* 4-byte boundary.
|
||||
*
|
||||
* The checksum includes the block number (to detect the case where a page is
|
||||
* somehow moved to a different location), the page header (excluding the
|
||||
* checksum itself), and the page data.
|
||||
*/
|
||||
uint16 pg_checksum_page(char* page, BlockNumber blkno)
|
||||
{
|
||||
PageHeader phdr = (PageHeader)page;
|
||||
uint16 save_checksum;
|
||||
uint32 checksum;
|
||||
|
||||
/*
|
||||
* Save pd_checksum and temporarily set it to zero, so that the checksum
|
||||
* calculation isn't affected by the old checksum stored on the page.
|
||||
* Restore it after, because actually updating the checksum is NOT part of
|
||||
* the API of this function.
|
||||
*/
|
||||
save_checksum = phdr->pd_checksum;
|
||||
phdr->pd_checksum = 0;
|
||||
checksum = pg_checksum_block(page, BLCKSZ);
|
||||
phdr->pd_checksum = save_checksum;
|
||||
|
||||
/* Mix in the block number to detect transposed pages */
|
||||
checksum ^= blkno;
|
||||
|
||||
/*
|
||||
* Reduce to a uint16 (to fit in the pd_checksum field) with an offset of
|
||||
* one. That avoids checksums of zero, which seems like a good idea.
|
||||
*/
|
||||
return (checksum % UINT16_MAX) + 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
/* Implementation of zlib compression method */
|
||||
static int32
|
||||
|
|
@ -270,7 +351,7 @@ get_checksum_errormsg(Page page, char **errormsg, BlockNumber absolute_blkno)
|
|||
"page verification failed, "
|
||||
"calculated checksum %u but expected %u",
|
||||
phdr->pd_checksum,
|
||||
/*pg_checksum_page(page, absolute_blkno)*/0);
|
||||
pg_checksum_page(page, absolute_blkno));
|
||||
securec_check_ss_c(nRet, "\0", "\0");
|
||||
}
|
||||
|
||||
|
|
@ -1428,7 +1509,7 @@ validate_one_page(Page page, BlockNumber absolute_blkno,
|
|||
}
|
||||
|
||||
/* Verify checksum */
|
||||
page_st->checksum = 0;//pg_checksum_page(page, absolute_blkno);
|
||||
page_st->checksum = pg_checksum_page(page, absolute_blkno);
|
||||
|
||||
if (checksum_version)
|
||||
{
|
||||
|
|
@ -1734,7 +1815,7 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
|
|||
{
|
||||
elog(WARNING, "Invalid CRC of backup file \"%s\": %X. Expected %X",
|
||||
fullpath, crc, file->crc);
|
||||
//is_valid = false;
|
||||
is_valid = false;
|
||||
}
|
||||
|
||||
pg_free(headers);
|
||||
|
|
@ -1789,8 +1870,10 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
|
|||
|
||||
if (rc == PAGE_IS_VALID)
|
||||
{
|
||||
|
||||
checksum_map[blknum].checksum = page_st.checksum;
|
||||
if (checksum_version)
|
||||
checksum_map[blknum].checksum = ((PageHeader) read_buffer)->pd_checksum;
|
||||
else
|
||||
checksum_map[blknum].checksum = page_st.checksum;
|
||||
checksum_map[blknum].lsn = page_st.lsn;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ static char dir_check_file(pgFile *file, bool backup_logs);
|
|||
static char check_in_tablespace(pgFile *file, bool in_tablespace);
|
||||
static char check_db_dir(pgFile *file);
|
||||
static char check_digit_file(pgFile *file);
|
||||
static char check_nobackup_dir(pgFile *file);
|
||||
static void dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
|
||||
bool exclude, bool follow_symlink, bool backup_logs,
|
||||
bool skip_hidden, int external_dir_num, fio_location location);
|
||||
|
|
@ -479,8 +480,8 @@ pgFileCompareLinked(const void *f1, const void *f2)
|
|||
int
|
||||
pgFileCompareSize(const void *f1, const void *f2)
|
||||
{
|
||||
pgFile *f1p = (pgFile *)const_cast<void*>(f1);
|
||||
pgFile *f2p = (pgFile *)const_cast<void*>(f2);
|
||||
pgFile *f1p = *(pgFile **)f1;
|
||||
pgFile *f2p = *(pgFile **)f2;
|
||||
|
||||
if (f1p->size > f2p->size)
|
||||
return 1;
|
||||
|
|
@ -493,7 +494,7 @@ pgFileCompareSize(const void *f1, const void *f2)
|
|||
static int
|
||||
pgCompareString(const void *str1, const void *str2)
|
||||
{
|
||||
return strcmp((char *)const_cast<void*>( str1), (char *)const_cast<void*>(str2));
|
||||
return strcmp(*(char **) str1, *(char **) str2);
|
||||
}
|
||||
|
||||
/* Compare two Oids */
|
||||
|
|
@ -644,6 +645,12 @@ dir_check_file(pgFile *file, bool backup_logs)
|
|||
return CHECK_EXCLUDE_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = check_nobackup_dir(file);
|
||||
if (ret != -1) { /* -1 means need backup */
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -719,6 +726,23 @@ if (in_tablespace)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static char check_nobackup_dir(pgFile *file)
|
||||
{
|
||||
char ret = -1; /* -1 means need backup */
|
||||
int i = 0;
|
||||
if (pgdata_nobackup_dir) {
|
||||
for (i = 0; i < (int)parray_num(pgdata_nobackup_dir); i++) {
|
||||
char *file_path = (char *)parray_get(pgdata_nobackup_dir, i);
|
||||
/* relative tablespace path exclude */
|
||||
if (strcmp(file->rel_path, file_path) == 0) {
|
||||
elog(VERBOSE, "Excluding external directory content: %s", file->rel_path);
|
||||
return CHECK_EXCLUDE_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char check_db_dir(pgFile *file)
|
||||
{
|
||||
char ret = -1;
|
||||
|
|
@ -1037,7 +1061,7 @@ opt_externaldir_map(ConfigOption *opt, const char *arg)
|
|||
* Enforce permissions from backup_content.control. The only
|
||||
* problem now is with PGDATA itself.
|
||||
* TODO: we must preserve PGDATA permissions somewhere. Is it actually a problem?
|
||||
* Shouldn`t starting postgres force correct permissions on PGDATA?
|
||||
* Shouldn`t starting openGauss force correct permissions on PGDATA?
|
||||
*
|
||||
* TODO: symlink handling. If user located symlink in PG_TBLSPC_DIR, it will
|
||||
* be restored as directory.
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ do_add_instance(InstanceConfig *instance)
|
|||
SOURCE_DEFAULT);
|
||||
config_set_opt(instance_options, &instance_config.remote.path,
|
||||
SOURCE_DEFAULT);
|
||||
config_set_opt(instance_options, &instance_config.remote.libpath,
|
||||
SOURCE_DEFAULT);
|
||||
config_set_opt(instance_options, &instance_config.remote.user,
|
||||
SOURCE_DEFAULT);
|
||||
config_set_opt(instance_options, &instance_config.remote.ssh_options,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include "parray.h"
|
||||
#include "pgut.h"
|
||||
|
||||
static size_t qsort_size = 100000; /* 100000 = default size */
|
||||
|
||||
/* members of struct parray are hidden from client. */
|
||||
struct parray
|
||||
{
|
||||
|
|
@ -191,10 +193,60 @@ parray_num(const parray *array)
|
|||
return array->used;
|
||||
}
|
||||
|
||||
static void HeapAdjust(void **array, size_t size, size_t index,
|
||||
int(*compare)(const void *, const void *))
|
||||
{
|
||||
size_t parent = index;
|
||||
size_t child = 2 * parent + 1; /* 2 * n + 1 :left child */
|
||||
while (child < size) {
|
||||
if (child + 1 < size && compare(&array[child + 1], &array[child]) > 0) {
|
||||
child = child + 1;
|
||||
}
|
||||
|
||||
if (compare(&array[child], &array[parent]) > 0) {
|
||||
void *tmp = array[child];
|
||||
array[child] = array[parent];
|
||||
array[parent] = tmp;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
parent = child;
|
||||
child = 2 * parent + 1; /* 2 * n + 1 :left child */
|
||||
}
|
||||
}
|
||||
|
||||
static void HeapPop(void **array, size_t size,
|
||||
int(*compare)(const void *, const void *))
|
||||
{
|
||||
void *tmp = array[0];
|
||||
array[0] = array[size - 1];
|
||||
array[size - 1] = tmp;
|
||||
|
||||
HeapAdjust(array, size - 1, 0, compare);
|
||||
}
|
||||
|
||||
static void HeapSort(void **array, size_t size,
|
||||
int(*compare)(const void *, const void *))
|
||||
{
|
||||
for (int64 i = (size - 2) / 2; i >= 0; i--) { /* parent node:(size -2) / 2 */
|
||||
HeapAdjust(array, size, i, compare);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
HeapPop(array, size - i, compare);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parray_qsort(parray *array, int(*compare)(const void *, const void *))
|
||||
{
|
||||
qsort(array->data, array->used, sizeof(void *), compare);
|
||||
Assert(array->used < (PG_UINT64_MAX / 1024));
|
||||
if (array->used <= qsort_size) {
|
||||
qsort(array->data, array->used, sizeof(void *), compare);
|
||||
} else {
|
||||
HeapSort(array->data, array->used, compare);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1054,8 +1054,9 @@ static int switch_next_wal_segment(XLogReaderData *reader_data, bool *isreturn)
|
|||
|
||||
if (fileExists(reader_data->xlogpath, FIO_LOCAL_HOST))
|
||||
{
|
||||
elog(LOG, "Thread [%d]: Opening WAL segment \"%s\"",
|
||||
reader_data->thread_num, reader_data->xlogpath);
|
||||
if (!current.from_replica)
|
||||
elog(LOG, "Thread [%d]: Opening WAL segment \"%s\"",
|
||||
reader_data->thread_num, reader_data->xlogpath);
|
||||
|
||||
reader_data->xlogexists = true;
|
||||
reader_data->xlogfile = fio_open(reader_data->xlogpath,
|
||||
|
|
|
|||
|
|
@ -804,6 +804,8 @@ int main(int argc, char *argv[])
|
|||
*/
|
||||
parse_backup_option_to_params(command, command_name);
|
||||
|
||||
pfree(command_name);
|
||||
|
||||
compress_init();
|
||||
|
||||
/* do actual operation */
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ extern const char *PROGRAM_FULL_PATH;
|
|||
#define DATABASE_MAP "database_map"
|
||||
#define HEADER_MAP "page_header_map"
|
||||
#define HEADER_MAP_TMP "page_header_map_tmp"
|
||||
#define PG_RELATIVE_TBLSPC_DIR "pg_location"
|
||||
|
||||
/* Timeout defaults */
|
||||
#define ARCHIVE_TIMEOUT_DEFAULT 300
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ extern int rw_timeout;
|
|||
/* backup options */
|
||||
extern bool smooth_checkpoint;
|
||||
|
||||
/* list of dirs which will not to be backuped
|
||||
it will be backuped up in external dirs */
|
||||
extern parray *pgdata_nobackup_dir;
|
||||
|
||||
/* remote probackup options */
|
||||
extern char* remote_agent;
|
||||
|
||||
|
|
|
|||
|
|
@ -613,6 +613,7 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
|
|||
const char **values;
|
||||
errno_t rc = EOK;
|
||||
char rwtimeoutStr[12] = {0};
|
||||
const char *malloc_port = NULL;
|
||||
|
||||
if (interrupted && !in_cleanup)
|
||||
elog(ERROR, "interrupted");
|
||||
|
|
@ -659,6 +660,7 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
|
|||
{
|
||||
keywords[i] = "port";
|
||||
values[i] = inc_dbport(port);
|
||||
malloc_port = values[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -683,6 +685,10 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
|
|||
{
|
||||
free(values);
|
||||
free(keywords);
|
||||
if (malloc_port)
|
||||
{
|
||||
free((void *)malloc_port);
|
||||
}
|
||||
return tmpconn;
|
||||
}
|
||||
|
||||
|
|
@ -700,6 +706,10 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
|
|||
PQfinish(tmpconn);
|
||||
free(values);
|
||||
free(keywords);
|
||||
if (malloc_port)
|
||||
{
|
||||
free((void *)malloc_port);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
|
|||
{
|
||||
PGresult *res;
|
||||
char start_lsn[17 + 1];
|
||||
uint32 lsn_hi;
|
||||
uint32 lsn_lo;
|
||||
XLogRecPtr cur_track_lsn;
|
||||
char *params[2];
|
||||
char *saved = NULL;
|
||||
char *blocknum_str = NULL;
|
||||
|
|
@ -63,23 +66,37 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
|
|||
int blkcnt = 0;
|
||||
BlockNumber blknum = 0;
|
||||
datapagemap_t pagemap;
|
||||
int segno = -1;
|
||||
char relpath[MAXPGPATH] = {0};
|
||||
page_map_entry **segarrary = (page_map_entry **)pgut_malloc(sizeof(page_map_entry *) * 32000);
|
||||
page_map_entry *pm_entry_seg = NULL;
|
||||
|
||||
errno_t rc = snprintf_s(start_lsn, sizeof(start_lsn), sizeof(start_lsn) - 1, "%X/%X",
|
||||
(uint32) (lsn >> 32), (uint32) lsn);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
params[0] = gs_pstrdup(start_lsn);
|
||||
elog(INFO, "change bitmap start lsn location is %s", params[0]);
|
||||
|
||||
if (!current.from_replica) {
|
||||
res = pgut_execute(backup_conn, "CHECKPOINT;", 0, NULL);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
res = pgut_execute(backup_conn, "SELECT pg_cbm_tracked_location()", 0, NULL);
|
||||
if (PQnfields(res) != 1) {
|
||||
elog(ERROR, "cannot get cbm tracked lsn location");
|
||||
for (;;) {
|
||||
char *temp_lsn = NULL;
|
||||
res = pgut_execute(backup_conn, "SELECT pg_cbm_tracked_location()", 0, NULL);
|
||||
if (PQnfields(res) != 1) {
|
||||
elog(ERROR, "cannot get cbm tracked lsn location");
|
||||
}
|
||||
temp_lsn = pg_strdup(PQgetvalue(res, 0, 0));
|
||||
ret = sscanf_s(temp_lsn, "%X/%X", &lsn_hi, &lsn_lo);
|
||||
securec_check_for_sscanf_s(ret, 2, "\0", "\0");
|
||||
pfree(temp_lsn);
|
||||
cur_track_lsn = ((uint64) lsn_hi) << 32 | lsn_lo;
|
||||
if (cur_track_lsn >= current.start_lsn) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
PQclear(res);
|
||||
}
|
||||
params[1] = gs_pstrdup(PQgetvalue(res, 0, 0));
|
||||
PQclear(res);
|
||||
elog(INFO, "change bitmap end lsn location is %s", params[1]);
|
||||
|
||||
res = pgut_execute(backup_conn,
|
||||
"SELECT path,changed_block_number,changed_block_list "
|
||||
|
|
@ -92,45 +109,74 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
|
|||
elog(ERROR, "cannot get ptrack pagemapset");
|
||||
|
||||
/* Initialize bitmap */
|
||||
pagemap.bitmap = NULL;
|
||||
pagemap.bitmapsize = 0;
|
||||
|
||||
/* Construct database map */
|
||||
for (i = 0; i < PQntuples(res); i++) {
|
||||
page_map_entry *pm_entry = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
|
||||
|
||||
/* get path */
|
||||
pm_entry->path = pgut_strdup(PQgetvalue(res, i, 0));
|
||||
|
||||
ret = sscanf_s(PQgetvalue(res, i, 1), "%d", &blkcnt);
|
||||
securec_check_for_sscanf_s(ret, 1, "\0", "\0");
|
||||
|
||||
if (blkcnt == 1) {
|
||||
pagemap.bitmap = NULL;
|
||||
pagemap.bitmapsize = 0;
|
||||
page_map_entry *pm_entry = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
|
||||
ret = sscanf_s(PQgetvalue(res, i, 2), "%u", &blknum);
|
||||
securec_check_for_sscanf_s(ret, 1, "\0", "\0");
|
||||
datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE));
|
||||
} else {
|
||||
pm_entry->pagemap = (char *)pagemap.bitmap;
|
||||
pm_entry->pagemapsize = pagemap.bitmapsize;
|
||||
segno = blknum / ((BlockNumber) RELSEG_SIZE);
|
||||
if (segno > 0 ) {
|
||||
ret = snprintf_s(relpath, MAXPGPATH, MAXPGPATH - 1, "%s.%u",
|
||||
PQgetvalue(res, i, 0), segno);
|
||||
securec_check_ss_c(ret, "\0", "\0");
|
||||
pm_entry->path = pgut_strdup(relpath);
|
||||
} else {
|
||||
pm_entry->path = pgut_strdup(PQgetvalue(res, i, 0));
|
||||
}
|
||||
if (pagemapset == NULL) {
|
||||
pagemapset = parray_new();
|
||||
}
|
||||
parray_append(pagemapset, pm_entry);
|
||||
} else if (blkcnt > 1) {
|
||||
if (pagemapset == NULL) {
|
||||
pagemapset = parray_new();
|
||||
}
|
||||
rc = memset_s(segarrary, sizeof(page_map_entry *) * 32000, 0, sizeof(page_map_entry *) * 32000);
|
||||
securec_check(rc, "\0", "\0");
|
||||
blocknum_str = strtok_r(PQgetvalue(res, i, 2), ", ", &saved);
|
||||
while (blocknum_str != NULL) {
|
||||
ret = sscanf_s(blocknum_str, "%u", &blknum);
|
||||
securec_check_for_sscanf_s(ret, 1, "\0", "\0");
|
||||
segno = blknum / ((BlockNumber) RELSEG_SIZE);
|
||||
if (segarrary[segno] == NULL) {
|
||||
pm_entry_seg = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
|
||||
segarrary[segno] = pm_entry_seg;
|
||||
pagemap.bitmap = NULL;
|
||||
pagemap.bitmapsize = 0;
|
||||
if (segno > 0 ) {
|
||||
ret = snprintf_s(relpath, MAXPGPATH, MAXPGPATH - 1, "%s.%u",
|
||||
PQgetvalue(res, i, 0), segno);
|
||||
securec_check_ss_c(ret, "\0", "\0");
|
||||
pm_entry_seg->path = pgut_strdup(relpath);
|
||||
} else {
|
||||
pm_entry_seg->path = pgut_strdup(PQgetvalue(res, i, 0));
|
||||
}
|
||||
parray_append(pagemapset, pm_entry_seg);
|
||||
} else {
|
||||
pm_entry_seg = segarrary[segno];
|
||||
pagemap.bitmap = (unsigned char*)pm_entry_seg->pagemap;
|
||||
pagemap.bitmapsize = pm_entry_seg->pagemapsize;
|
||||
}
|
||||
datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE));
|
||||
pm_entry_seg->pagemap = (char *)pagemap.bitmap;
|
||||
pm_entry_seg->pagemapsize = pagemap.bitmapsize;
|
||||
blocknum_str = strtok_r(NULL, ", ", &saved);
|
||||
}
|
||||
}
|
||||
|
||||
pm_entry->pagemap = (char *)pagemap.bitmap;
|
||||
pm_entry->pagemapsize = pagemap.bitmapsize;
|
||||
|
||||
pagemap.bitmap = NULL;
|
||||
pagemap.bitmapsize = 0;
|
||||
|
||||
if (pagemapset == NULL)
|
||||
pagemapset = parray_new();
|
||||
|
||||
parray_append(pagemapset, pm_entry);
|
||||
}
|
||||
|
||||
free(segarrary);
|
||||
PQclear(res);
|
||||
|
||||
return pagemapset;
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ bool launch_agent(void)
|
|||
{
|
||||
char cmd[MAX_CMDLINE_LENGTH];
|
||||
char* ssh_argv[MAX_CMDLINE_OPTIONS];
|
||||
char libenv[MAX_CMDLINE_LENGTH] = {0};
|
||||
int ssh_argc;
|
||||
int outfd[2];
|
||||
int infd[2];
|
||||
|
|
@ -156,6 +157,19 @@ bool launch_agent(void)
|
|||
ssh_argv[ssh_argc++] = (char *)cmd;
|
||||
ssh_argv[ssh_argc] = NULL;
|
||||
|
||||
if (instance_config.remote.libpath)
|
||||
{
|
||||
#ifdef WIN32
|
||||
rc = snprintf_s(libenv, sizeof(libenv), sizeof(libenv) - 1, "set LD_LIBRARY_PATH=%s &&",
|
||||
instance_config.remote.libpath);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
#else
|
||||
rc = snprintf_s(libenv, sizeof(libenv), sizeof(libenv) - 1, "export LD_LIBRARY_PATH=%s &&",
|
||||
instance_config.remote.libpath);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (instance_config.remote.path)
|
||||
{
|
||||
char const* probackup = PROGRAM_NAME_FULL;
|
||||
|
|
@ -172,27 +186,27 @@ bool launch_agent(void)
|
|||
}
|
||||
if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL))
|
||||
{
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s\\%s\" agent",
|
||||
instance_config.remote.path, probackup);
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s %s\\%s\" agent",
|
||||
libenv, instance_config.remote.path, probackup);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s\\%s agent",
|
||||
instance_config.remote.path, probackup);
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s %s\\%s agent",
|
||||
libenv, instance_config.remote.path, probackup);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
}
|
||||
#else
|
||||
if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL))
|
||||
{
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s/%s\" agent",
|
||||
instance_config.remote.path, probackup);
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s %s/%s\" agent",
|
||||
libenv, instance_config.remote.path, probackup);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s/%s agent",
|
||||
instance_config.remote.path, probackup);
|
||||
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s %s/%s agent",
|
||||
libenv, instance_config.remote.path, probackup);
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ typedef struct RemoteConfig
|
|||
char* host;
|
||||
char* port;
|
||||
char* path;
|
||||
char* libpath;
|
||||
char* user;
|
||||
char *ssh_config;
|
||||
char *ssh_options;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "thread.h"
|
||||
#include "common/fe_memutils.h"
|
||||
|
||||
#define RESTORE_ARRAY_LEN 100
|
||||
|
||||
typedef struct
|
||||
{
|
||||
parray *pgdata_files;
|
||||
|
|
@ -1379,7 +1381,15 @@ create_recovery_conf(time_t backup_id,
|
|||
/* construct restore_command */
|
||||
if (pitr_requested)
|
||||
{
|
||||
char *timestamp = NULL;
|
||||
const char *oldtime = NULL;
|
||||
timestamp = (char *)pg_malloc(RESTORE_ARRAY_LEN);
|
||||
time2iso(timestamp, RESTORE_ARRAY_LEN, backup->end_time);
|
||||
oldtime = rt->time_string;
|
||||
rt->time_string = timestamp;
|
||||
construct_restore_cmd(fp, rt, restore_command_provided, target_immediate);
|
||||
rt->time_string = oldtime;
|
||||
free(timestamp);
|
||||
}
|
||||
|
||||
if (fio_fflush(fp) != 0 ||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ static const char *statusName[] =
|
|||
"CORRUPT"
|
||||
};
|
||||
|
||||
uint32 NUM_65536 = 65536;
|
||||
uint32 NUM_10000 = 10000;
|
||||
|
||||
const char *
|
||||
base36enc(long unsigned int value)
|
||||
{
|
||||
|
|
@ -53,7 +56,7 @@ base36enc(long unsigned int value)
|
|||
}
|
||||
|
||||
/*
|
||||
* Same as base36enc(), but the result must be released by the user.
|
||||
* Same as base36enc(), but the results must be released by the user.
|
||||
*/
|
||||
char *
|
||||
base36enc_dup(long unsigned int value)
|
||||
|
|
@ -77,6 +80,30 @@ base36dec(const char *text)
|
|||
return strtoul(text, NULL, 36);
|
||||
}
|
||||
|
||||
static void
|
||||
checkControlFile(ControlFileData *ControlFile)
|
||||
{
|
||||
pg_crc32c crc;
|
||||
|
||||
/* Calculate CRC */
|
||||
INIT_CRC32C(crc);
|
||||
COMP_CRC32C(crc, (char *) ControlFile, offsetof(ControlFileData, crc));
|
||||
FIN_CRC32C(crc);
|
||||
|
||||
/* Then compare it */
|
||||
if (!EQ_CRC32C(crc, ControlFile->crc))
|
||||
elog(ERROR, "Calculated CRC checksum does not match value stored in file.\n"
|
||||
"Either the file is corrupt, or it has a different layout than this program\n"
|
||||
"is expecting. The results below are untrustworthy.");
|
||||
|
||||
if ((ControlFile->pg_control_version % NUM_65536 == 0 || ControlFile->pg_control_version % NUM_65536 > NUM_10000) &&
|
||||
ControlFile->pg_control_version / NUM_65536 != 0)
|
||||
elog(ERROR, "possible byte ordering mismatch\n"
|
||||
"The byte ordering used to store the pg_control file might not match the one\n"
|
||||
"used by this program. In that case the results below would be incorrect, and\n"
|
||||
"the PostgreSQL installation would be incompatible with this data directory.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify control file contents in the buffer src, and copy it to *ControlFile.
|
||||
*/
|
||||
|
|
@ -89,6 +116,9 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
|
|||
|
||||
errno_t rc = memcpy_s(ControlFile, sizeof(ControlFileData), src, sizeof(ControlFileData));
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
|
||||
/* Additional checks on control file */
|
||||
checkControlFile(ControlFile);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "common/fe_memutils.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
PGconn* conn = NULL;
|
||||
char source_slot_name[NAMEDATALEN] = {0};
|
||||
|
|
@ -315,7 +314,7 @@ BuildErrorCode fetchSourceFileList()
|
|||
* the received parts. The result set is expected to be of format:
|
||||
*
|
||||
* path text -- path in the data directory, e.g "base/1/123"
|
||||
* begin int8 -- offset within the file
|
||||
* begin int4 -- offset within the file
|
||||
* chunk bytea -- file content
|
||||
* ----
|
||||
*/
|
||||
|
|
@ -339,7 +338,7 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
|
|||
while ((res = PQgetResult(conn)) != NULL) {
|
||||
char* filename = NULL;
|
||||
int filenamelen;
|
||||
int64 chunkoff;
|
||||
int chunkoff;
|
||||
int chunksize;
|
||||
int chunkspace;
|
||||
char* chunk = NULL;
|
||||
|
|
@ -363,7 +362,7 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
|
|||
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
|
||||
}
|
||||
|
||||
if (PQftype(res, 0) != TEXTOID && PQftype(res, 1) != INT8OID && PQftype(res, 2) != BYTEAOID &&
|
||||
if (PQftype(res, 0) != TEXTOID && PQftype(res, 1) != INT4OID && PQftype(res, 2) != BYTEAOID &&
|
||||
PQftype(res, 3) != INT4OID) {
|
||||
pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u %u\n",
|
||||
PQftype(res, 0),
|
||||
|
|
@ -383,15 +382,15 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
|
|||
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
|
||||
}
|
||||
|
||||
if (PQgetlength(res, 0, 1) != sizeof(int64)) {
|
||||
if (PQgetlength(res, 0, 1) != sizeof(int32)) {
|
||||
pg_fatal("unexpected result length while fetching remote files\n");
|
||||
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
|
||||
}
|
||||
|
||||
/* Read result set to local variables */
|
||||
errorno = memcpy_s(&chunkoff, sizeof(int64), PQgetvalue(res, 0, 1), sizeof(int64));
|
||||
errorno = memcpy_s(&chunkoff, sizeof(int32), PQgetvalue(res, 0, 1), sizeof(int32));
|
||||
securec_check_c(errorno, "\0", "\0");
|
||||
chunkoff = (int64)ntohl64((uint64)chunkoff);
|
||||
chunkoff = ntohl(chunkoff);
|
||||
chunksize = PQgetlength(res, 0, 2);
|
||||
|
||||
filenamelen = PQgetlength(res, 0, 0);
|
||||
|
|
@ -422,9 +421,9 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
|
|||
continue;
|
||||
}
|
||||
|
||||
pg_log(PG_DEBUG, "received chunk for file \"%s\", offset " INT64_FORMAT ", size %d\n",
|
||||
pg_log(PG_DEBUG, "received chunk for file \"%s\", offset %d, size %d\n",
|
||||
filename, chunkoff, chunksize);
|
||||
fprintf(file, "received chunk for file \"%s\", offset " INT64_FORMAT ", size %d\n",
|
||||
fprintf(file, "received chunk for file \"%s\", offset %d, size %d\n",
|
||||
filename, chunkoff, chunksize);
|
||||
|
||||
open_target_file(filename, false);
|
||||
|
|
@ -536,7 +535,7 @@ BuildErrorCode executeFileMap(filemap_t* map, FILE* file)
|
|||
* First create a temporary table, and load it with the blocks that we
|
||||
* need to fetch.
|
||||
*/
|
||||
sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int8, len int4);";
|
||||
sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int4, len int4);";
|
||||
res = PQexec(conn, sql);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
|
||||
pg_fatal("could not create temporary table: %s", PQresultErrorMessage(res));
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ const char *excludeFiles[] = {
|
|||
"postgresql.conf.bak",
|
||||
"postgresql.conf.old",
|
||||
"pg_ctl.lock",
|
||||
"build_completed.start"
|
||||
"build_completed.start",
|
||||
"backup_label",
|
||||
"client.crt",
|
||||
"client.key",
|
||||
|
|
|
|||
|
|
@ -305,14 +305,15 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char*
|
|||
delete_all_file(bkup_file, true);
|
||||
PG_CHECKBUILD_AND_RETURN();
|
||||
}
|
||||
if (replication_type == RT_WITH_DUMMY_STANDBY) {
|
||||
/* Backup local data into pg_rewind_bak dir */
|
||||
rv = backupFileMap(filemap);
|
||||
PG_CHECKRETURN_AND_RETURN(rv);
|
||||
pg_log(PG_PROGRESS, "backup target files success\n");
|
||||
|
||||
/* Backup local data into pg_rewind_bak dir */
|
||||
rv = backupFileMap(filemap);
|
||||
PG_CHECKRETURN_AND_RETURN(rv);
|
||||
pg_log(PG_PROGRESS, "backup target files success\n");
|
||||
|
||||
MoveOldXlogFiles(checkSeg, movedXlogPath);
|
||||
PG_CHECKBUILD_AND_RETURN();
|
||||
MoveOldXlogFiles(checkSeg, movedXlogPath);
|
||||
PG_CHECKBUILD_AND_RETURN();
|
||||
}
|
||||
pg_log(PG_WARNING, _("starting background WAL receiver\n"));
|
||||
nRet = snprintf_s(xlog_start, MAXFNAMELEN, MAXFNAMELEN - 1, "%X/%X", (uint32)(chkptredo >> 32), (uint32)chkptredo);
|
||||
securec_check_ss_c(nRet, "", "");
|
||||
|
|
@ -460,8 +461,10 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char*
|
|||
}
|
||||
|
||||
/* Remove pg_rewind_bak dir */
|
||||
delete_all_file(bkup_file, true);
|
||||
PG_CHECKBUILD_AND_RETURN();
|
||||
if (access(bkup_file, F_OK) == 0) {
|
||||
delete_all_file(bkup_file, true);
|
||||
PG_CHECKBUILD_AND_RETURN();
|
||||
}
|
||||
|
||||
if (datadir_target != NULL) {
|
||||
free(datadir_target);
|
||||
|
|
|
|||
|
|
@ -145,16 +145,12 @@ static void usage(void);
|
|||
static void showVersion(void);
|
||||
static PGconn* loginDatabase(char* host, int port, char* user, char* password, char* dbname, const char* progname,
|
||||
char* encoding, const char* password_prompt);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void getMyNodename(PGconn* conn);
|
||||
static void getMyGtmMode(PGconn* conn);
|
||||
#endif
|
||||
static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo);
|
||||
static void recover2PC(PGconn* conn, txn_info* txn, int num);
|
||||
static void getDatabaseList(PGconn* conn);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void getNodeList(PGconn* conn);
|
||||
#endif
|
||||
static void getPreparedTxnList(PGconn* conn);
|
||||
static void getTxnInfoOnOtherNodesAll(CleanWorkerInfo* wkinfo);
|
||||
static void do_commit(PGconn* conn, txn_info* txn, int num);
|
||||
|
|
@ -170,10 +166,8 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok);
|
|||
static void dropTempSchema(PGconn* conn, char* nspname, bool missing_ok);
|
||||
|
||||
static void getTempSchemaListOnCN(PGconn* conn);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void getTempSchemaOnOneDN(PGconn* conn, int no);
|
||||
static int getTempSchemaListOnDN(PGconn* conn);
|
||||
#endif
|
||||
static void checkAllocMem(void* p);
|
||||
static void cleanTempSchemaList();
|
||||
static void cleanBackendList();
|
||||
|
|
@ -670,7 +664,6 @@ int main(int argc, char* argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/*
|
||||
* Get my nodename (connected Coordinator) and gtm_mode
|
||||
*/
|
||||
|
|
@ -684,7 +677,6 @@ int main(int argc, char* argv[])
|
|||
transfor_gtm_optoin(gtm_option, gtm_mode),
|
||||
gtm_option_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get available databases
|
||||
|
|
@ -712,7 +704,6 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/*
|
||||
* Get list of Nodes
|
||||
*
|
||||
|
|
@ -737,7 +728,6 @@ int main(int argc, char* argv[])
|
|||
pgxc_clean_node_info[ii].type == NODE_TYPE_COORD ? "coordinator" : "datanode");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only clean temp schema if clean_temp_schema_only == true,
|
||||
|
|
@ -751,15 +741,6 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
exit(0);
|
||||
}
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
else {
|
||||
PQfinish(coord_conn);
|
||||
coord_conn = NULL;
|
||||
write_stderr("%s %s: We only clean temp schema in openGauss, please specify '-e' option.\n",
|
||||
formatLogTime(), progname);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only clean plan_table if clean_plan_table_only == true,
|
||||
|
|
@ -1133,9 +1114,7 @@ static void cleanPlanTableSessidList()
|
|||
static void dropTempNamespace()
|
||||
{
|
||||
database_info* cur_database = NULL;
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
int datanode_no = -1;
|
||||
#endif
|
||||
|
||||
if (head_database_info != NULL) {
|
||||
for (cur_database = head_database_info; cur_database != NULL; cur_database = cur_database->next) {
|
||||
|
|
@ -1187,12 +1166,11 @@ static void dropTempNamespace()
|
|||
(void)dropTempSchemas(coord_conn, true);
|
||||
(void)cleanBackendList();
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
datanode_no = getTempSchemaListOnDN(coord_conn);
|
||||
(void)getActiveBackendListOnCN(coord_conn, datanode_no);
|
||||
(void)dropTempSchemas(coord_conn, true);
|
||||
(void)cleanBackendList();
|
||||
#endif
|
||||
|
||||
|
||||
if (verbose_opt)
|
||||
write_stderr("%s %s: drop temp namespace for database \"%s\" finished\n",
|
||||
|
|
@ -1209,12 +1187,10 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
|
|||
{
|
||||
tempschema_info* cell1 = temp_schema_info;
|
||||
activebackend_info* cell2 = NULL;
|
||||
char node_name[NAMEDATALEN];
|
||||
char temp_buffer[NAMEDATALEN] = {0};
|
||||
char temp_buffer2[NAMEDATALEN] = {0};
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
char node_name[NAMEDATALEN];
|
||||
bool onOtherCNNode = false;
|
||||
#endif
|
||||
errno_t rc;
|
||||
|
||||
if (temp_schema_info == NULL || active_backend_info == NULL)
|
||||
|
|
@ -1254,7 +1230,6 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
|
|||
}
|
||||
|
||||
if (cell2 == NULL) {
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/*
|
||||
* now it is not the active backend, furthermore, we need to
|
||||
* check whether the schema on the other node:
|
||||
|
|
@ -1329,9 +1304,6 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
|
|||
if (!onOtherCNNode)
|
||||
dropTempSchema(conn, cell1->tempschema_name, missing_ok);
|
||||
}
|
||||
#else
|
||||
dropTempSchema(conn, cell1->tempschema_name, missing_ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
cell1 = cell1->next;
|
||||
|
|
@ -1443,7 +1415,6 @@ static char* pg_strdup(const char* string)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void getMyNodename(PGconn* conn)
|
||||
{
|
||||
static const char* stmt = "SELECT pgxc_node_str()";
|
||||
|
|
@ -1487,7 +1458,6 @@ static void getMyGtmMode(PGconn* conn)
|
|||
}
|
||||
PQclear(res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo)
|
||||
{
|
||||
|
|
@ -2352,7 +2322,6 @@ static void add_active_backend_info(int64 sessionID, uint32 tempID, uint32 timeL
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/*
|
||||
* @Description: get temp schema list of a random DN.
|
||||
* @param[IN] conn: node connection handle
|
||||
|
|
@ -2446,7 +2415,6 @@ static void getTempSchemaOnOneDN(PGconn* conn, int no)
|
|||
|
||||
PQclear(res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void getTempSchemaListOnCN(PGconn* conn)
|
||||
{
|
||||
|
|
@ -2458,18 +2426,11 @@ static void getTempSchemaListOnCN(PGconn* conn)
|
|||
|
||||
char STMT_GET_TEMP_SCHEMA_LIST[NAMEDATALEN + 128] = {0};
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
rc = snprintf_s(STMT_GET_TEMP_SCHEMA_LIST,
|
||||
sizeof(STMT_GET_TEMP_SCHEMA_LIST),
|
||||
sizeof(STMT_GET_TEMP_SCHEMA_LIST) - 1,
|
||||
"SELECT NSPNAME FROM PG_NAMESPACE WHERE NSPNAME LIKE 'pg_temp_%s_%%'",
|
||||
my_nodename);
|
||||
#else
|
||||
rc = snprintf_s(STMT_GET_TEMP_SCHEMA_LIST,
|
||||
sizeof(STMT_GET_TEMP_SCHEMA_LIST),
|
||||
sizeof(STMT_GET_TEMP_SCHEMA_LIST) - 1,
|
||||
"SELECT NSPNAME FROM PG_NAMESPACE WHERE NSPNAME LIKE 'pg_temp_%%'");
|
||||
#endif
|
||||
securec_check_ss_c(rc, "\0", "\0");
|
||||
|
||||
if (verbose_opt)
|
||||
|
|
@ -2589,7 +2550,6 @@ static void checkAllocMem(void* p)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void getNodeList(PGconn* conn)
|
||||
{
|
||||
int ii;
|
||||
|
|
@ -2672,7 +2632,6 @@ error_exit:
|
|||
PQclear(res);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char* transfor_gtm_optoin(const char* option, const char* gtm_free_mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1526,7 +1526,7 @@ void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
|
|||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid));
|
||||
|
||||
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
|
||||
|
|
@ -1623,7 +1623,7 @@ void RemoveDefaultACLById(Oid defaclOid)
|
|||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(defaclOid));
|
||||
|
||||
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
|
||||
|
|
@ -2987,7 +2987,7 @@ static void ExecGrant_Largeobject(InternalGrant* istmt)
|
|||
/* There's no syscache for pg_largeobject_metadata */
|
||||
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
|
||||
|
||||
scan = systable_beginscan(relation, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, entry);
|
||||
scan = systable_beginscan(relation, LargeObjectMetadataOidIndexId, true, NULL, 1, entry);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -6153,7 +6153,7 @@ bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
|
|||
|
||||
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid));
|
||||
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, entry);
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, entry);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -6483,7 +6483,7 @@ bool pg_extension_ownercheck(Oid ext_oid, Oid roleid)
|
|||
|
||||
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid));
|
||||
|
||||
scan = systable_beginscan(pg_extension, ExtensionOidIndexId, true, SnapshotNow, 1, entry);
|
||||
scan = systable_beginscan(pg_extension, ExtensionOidIndexId, true, NULL, 1, entry);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
|
|||
|
|
@ -3191,6 +3191,10 @@
|
|||
"gs_fault_inject", 1,
|
||||
AddBuiltinFunc(_0(4000), _1("gs_fault_inject"), _2(6), _3(true), _4(false), _5(gs_fault_inject), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 20, 25, 25, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_fault_inject"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_get_archive_status", 1,
|
||||
AddBuiltinFunc(_0(3796), _1("gs_get_archive_status"), _2(0), _3(true), _4(true), _5(gs_get_archive_status), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(4, 25, 25, 1184, 25), _22(4, 'o', 'o', 'o', 'o'), _23(4, "archive_standby", "archive_lsn", "last_arch_time", "archive_path"), _24(NULL), _25("gs_get_archive_status"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_get_global_barrier_status", 1,
|
||||
AddBuiltinFunc(_0(9032), _1("gs_get_global_barrier_status"), _2(0), _3(true), _4(false), _5(gs_get_global_barrier_status), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(2, 25, 25), _22(2, 'o', 'o'), _23(2, "global_barrier_id", "global_achive_barrier_id"), _24(NULL), _25("gs_get_global_barrier_status"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
|
|
|
|||
|
|
@ -909,7 +909,7 @@ static void drop_delta_rel(Oid deltataRelId)
|
|||
Relation depRel = relation_open(DependRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(deltataRelId));
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
simple_heap_delete(depRel, &tup->t_self);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ static void findDependentObjects(const ObjectAddress* object, int flags, ObjectA
|
|||
} else
|
||||
nkeys = 2;
|
||||
|
||||
scan = systable_beginscan(*depRel, DependDependerIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(*depRel, DependDependerIndexId, true, NULL, nkeys, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -718,7 +718,7 @@ static void findDependentObjects(const ObjectAddress* object, int flags, ObjectA
|
|||
} else
|
||||
nkeys = 2;
|
||||
|
||||
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, NULL, nkeys, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -1076,7 +1076,7 @@ static void deleteOneObject(const ObjectAddress* object, Relation* depRel, int f
|
|||
} else
|
||||
nkeys = 2;
|
||||
|
||||
scan = systable_beginscan(*depRel, DependDependerIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(*depRel, DependDependerIndexId, true, NULL, nkeys, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
simple_heap_delete(*depRel, &tup->t_self);
|
||||
|
|
@ -1100,7 +1100,7 @@ static void deleteOneObject(const ObjectAddress* object, Relation* depRel, int f
|
|||
} else
|
||||
nkeys = 2;
|
||||
|
||||
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, NULL, nkeys, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend Pinnedobj = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -2419,7 +2419,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
rcscan = systable_beginscan(castDesc, CastOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(castDesc, CastOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(rcscan);
|
||||
|
||||
|
|
@ -2503,7 +2503,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, SnapshotNow, 1, skey);
|
||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(adscan);
|
||||
|
||||
|
|
@ -2595,7 +2595,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, SnapshotNow, 1, skey);
|
||||
amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(amscan);
|
||||
|
||||
|
|
@ -2642,7 +2642,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, SnapshotNow, 1, skey);
|
||||
amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(amscan);
|
||||
|
||||
|
|
@ -2687,7 +2687,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(rcscan);
|
||||
|
||||
|
|
@ -2717,7 +2717,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true, SnapshotNow, 1, skey);
|
||||
tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(tgscan);
|
||||
|
||||
|
|
@ -2885,7 +2885,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
ScanKeyInit(
|
||||
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tup = systable_getnext(rcscan);
|
||||
|
||||
|
|
@ -2984,7 +2984,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(object->objectId));
|
||||
|
||||
SysScanDesc scanDesc = systable_beginscan(pg_rlspolicy, PgRlspolicyOidIndex, true, SnapshotNow, 1, scanKey);
|
||||
SysScanDesc scanDesc = systable_beginscan(pg_rlspolicy, PgRlspolicyOidIndex, true, NULL, 1, scanKey);
|
||||
|
||||
HeapTuple tuple = systable_getnext(scanDesc);
|
||||
if (HeapTupleIsValid(tuple) == false) {
|
||||
|
|
@ -3160,7 +3160,7 @@ bool TSConfigurationHasDependentObjects(Oid tsconfoid)
|
|||
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tsconfoid));
|
||||
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_depend pg_depend = (Form_pg_depend)GETSTRUCT(tuple);
|
||||
|
||||
|
|
@ -3227,7 +3227,7 @@ static void findTsDependentObjects(ObjectAddresses* targetObjects, Relation depR
|
|||
|
||||
ScanKeyInit(&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->objectId));
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
|
||||
while(HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
|
||||
otherObj.classId = foundDep->classid;
|
||||
|
|
|
|||
|
|
@ -2905,7 +2905,7 @@ static void RelationRemoveInheritance(Oid relid)
|
|||
|
||||
ScanKeyInit(&key, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, &key);
|
||||
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true, NULL, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
|
||||
simple_heap_delete(catalogRelation, &tuple->t_self);
|
||||
|
|
@ -2963,7 +2963,7 @@ void DeleteAttributeTuples(Oid relid)
|
|||
/* Use the index to scan only attributes of the target relation */
|
||||
ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, NULL, 1, key);
|
||||
|
||||
/* Delete all the matching tuples */
|
||||
while ((atttup = systable_getnext(scan)) != NULL)
|
||||
|
|
@ -2996,7 +2996,7 @@ void DeleteSystemAttributeTuples(Oid relid)
|
|||
ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
ScanKeyInit(&key[1], Anum_pg_attribute_attnum, BTLessEqualStrategyNumber, F_INT2LE, Int16GetDatum(0));
|
||||
|
||||
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, NULL, 2, key);
|
||||
|
||||
/* Delete all the matching tuples */
|
||||
while ((atttup = systable_getnext(scan)) != NULL)
|
||||
|
|
@ -3156,7 +3156,7 @@ void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool
|
|||
ScanKeyInit(&scankeys[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
ScanKeyInit(&scankeys[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(attnum));
|
||||
|
||||
scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true, SnapshotNow, 2, scankeys);
|
||||
scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true, NULL, 2, scankeys);
|
||||
|
||||
/* There should be at most one matching tuple, but we loop anyway */
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
|
|
@ -3204,7 +3204,7 @@ void RemoveAttrDefaultById(Oid attrdefId)
|
|||
/* Find the pg_attrdef tuple */
|
||||
ScanKeyInit(&scankeys[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(attrdefId));
|
||||
|
||||
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true, SnapshotNow, 1, scankeys);
|
||||
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true, NULL, 1, scankeys);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -3945,7 +3945,7 @@ static bool MergeWithExistingConstraint(
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(RelationGetNamespace(rel)));
|
||||
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey);
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
|
||||
|
|
@ -4060,6 +4060,9 @@ Node* parseParamRef(ParseState* pstate, ParamRef* pref)
|
|||
pfree_ext(val);
|
||||
if (pref->number == params_info->numParams && u_sess->parser_cxt.ddl_pbe_context != NULL) {
|
||||
MemoryContextDelete(u_sess->parser_cxt.ddl_pbe_context);
|
||||
if (((IS_PGXC_COORDINATOR || IS_PGXC_DATANODE) && IsConnFromCoord())) {
|
||||
u_sess->parser_cxt.param_info = NULL;
|
||||
}
|
||||
u_sess->parser_cxt.ddl_pbe_context = NULL;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4251,7 +4254,7 @@ void RemoveStatistics(Oid relid, AttrNumber attnum)
|
|||
}
|
||||
|
||||
pgstatistic = heap_open(StatisticRelationId, RowExclusiveLock);
|
||||
scan = systable_beginscan(pgstatistic, StatisticRelidKindAttnumInhIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(pgstatistic, StatisticRelidKindAttnumInhIndexId, true, NULL, nkeys, key);
|
||||
|
||||
/* we must loop even when attnum != 0, in case of inherited stats */
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
|
||||
|
|
@ -4266,7 +4269,7 @@ void RemoveStatistics(Oid relid, AttrNumber attnum)
|
|||
*/
|
||||
nkeys = 2;
|
||||
pgstatistic = heap_open(StatisticExtRelationId, RowExclusiveLock);
|
||||
scan = systable_beginscan(pgstatistic, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(pgstatistic, StatisticExtRelidKindInhKeyIndexId, true, NULL, nkeys, key);
|
||||
|
||||
/* we must loop here, in case of inherited stats and extended stats */
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
|
|
@ -4663,7 +4666,7 @@ List* heap_truncate_find_FKs(List* relationIds)
|
|||
*/
|
||||
fkeyRel = heap_open(ConstraintRelationId, AccessShareLock);
|
||||
|
||||
fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, SnapshotNow, 0, NULL);
|
||||
fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, NULL, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -6747,7 +6750,7 @@ bool FindExistingConstraint(const char* ccname, Relation rel)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(RelationGetNamespace(rel)));
|
||||
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey);
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
|
||||
|
|
|
|||
|
|
@ -3904,6 +3904,24 @@ static void MotFdwReindex(Relation heapRelation, Relation iRel)
|
|||
}
|
||||
#endif
|
||||
|
||||
void PartRelSetHasIndexState(Oid relid)
|
||||
{
|
||||
Relation pg_class = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
HeapTuple tup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("cache lookup failed for relation %u", relid)));
|
||||
}
|
||||
Form_pg_class pgcform = (Form_pg_class)GETSTRUCT(tup);
|
||||
|
||||
/* modify pg_class hasindex is true when reindex and it is false. */
|
||||
if (!pgcform->relhasindex) {
|
||||
pgcform->relhasindex = true;
|
||||
heap_inplace_update(pg_class, tup);
|
||||
}
|
||||
heap_freetuple(tup);
|
||||
heap_close(pg_class, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* reindex_index - This routine is used to recreate a single index
|
||||
*/
|
||||
|
|
@ -4036,6 +4054,7 @@ void reindex_index(Oid indexId, Oid indexPartId, bool skip_constraint_checks,
|
|||
}
|
||||
releasePartitionOidList(&indexPartOidList);
|
||||
|
||||
PartRelSetHasIndexState(heapRelation->rd_id);
|
||||
// call the internal function, update pg_index system table
|
||||
ATExecSetIndexUsableState(IndexRelationId, iRel->rd_id, true);
|
||||
CacheInvalidateRelcache(heapRelation);
|
||||
|
|
@ -4697,7 +4716,7 @@ static void reindexPartIndex(Oid indexId, Oid partOid, bool skip_constraint_chec
|
|||
|
||||
ScanKeyInit(&partKey, Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(partOid));
|
||||
|
||||
partScan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, &partKey);
|
||||
partScan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, NULL, 1, &partKey);
|
||||
|
||||
while ((partTuple = systable_getnext(partScan)) != NULL) {
|
||||
partForm = (Form_pg_partition)GETSTRUCT(partTuple);
|
||||
|
|
|
|||
|
|
@ -4737,7 +4737,7 @@ bool checkGroup(Oid relid, bool missing_ok)
|
|||
*/
|
||||
pgxc_group = heap_open(PgxcGroupRelationId, AccessShareLock);
|
||||
|
||||
scan = systable_beginscan(pgxc_group, PgxcGroupGroupNameIndexId, true, SnapshotNow, 0, NULL);
|
||||
scan = systable_beginscan(pgxc_group, PgxcGroupGroupNameIndexId, true, NULL, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple1 = systable_getnext(scan))) {
|
||||
Form_pgxc_group groupForm = (Form_pgxc_group)GETSTRUCT(tuple1);
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ void RemoveCollationById(Oid collationOid)
|
|||
|
||||
ScanKeyInit(&scanKeyData, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(collationOid));
|
||||
|
||||
scandesc = systable_beginscan(rel, CollationOidIndexId, true, SnapshotNow, 1, &scanKeyData);
|
||||
scandesc = systable_beginscan(rel, CollationOidIndexId, true, NULL, 1, &scanKeyData);
|
||||
|
||||
tuple = systable_getnext(scandesc);
|
||||
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, Oid objNamespace
|
|||
ScanKeyInit(
|
||||
&skey[1], Anum_pg_constraint_connamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objNamespace));
|
||||
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey);
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
|
||||
|
|
@ -464,7 +464,7 @@ char* ChooseConstraintName(const char* name1, const char* name2, const char* lab
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(namespaceid));
|
||||
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey);
|
||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
|
||||
|
||||
found = (HeapTupleIsValid(systable_getnext(conscan)));
|
||||
|
||||
|
|
@ -635,11 +635,11 @@ void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isT
|
|||
if (isType) {
|
||||
ScanKeyInit(&key[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId));
|
||||
|
||||
scan = systable_beginscan(conRel, ConstraintTypidIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(conRel, ConstraintTypidIndexId, true, NULL, 1, key);
|
||||
} else {
|
||||
ScanKeyInit(&key[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId));
|
||||
|
||||
scan = systable_beginscan(conRel, ConstraintRelidIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(conRel, ConstraintRelidIndexId, true, NULL, 1, key);
|
||||
}
|
||||
|
||||
while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
|
||||
|
|
@ -721,7 +721,7 @@ Oid get_relation_constraint_oid(Oid relid, const char* conname, bool missing_ok)
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -770,7 +770,7 @@ Oid get_domain_constraint_oid(Oid typid, const char* conname, bool missing_ok)
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -824,7 +824,7 @@ bool check_functional_grouping(Oid relid, Index varno, Index varlevelsup, List*
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -914,7 +914,7 @@ List* get_parse_dependency_rel_list(List* conids)
|
|||
Oid conid = lfirst_oid(lc);
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, conid);
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
/* Only one record should be qualified, and get the relid */
|
||||
if (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt* setstmt)
|
|||
ScanKeyInit(
|
||||
&scankey[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid));
|
||||
ScanKeyInit(&scankey[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid));
|
||||
scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true, SnapshotNow, 2, scankey);
|
||||
scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true, NULL, 2, scankey);
|
||||
tuple = systable_getnext(scan);
|
||||
|
||||
/*
|
||||
|
|
@ -238,7 +238,7 @@ void ApplySetting(Oid databaseid, Oid roleid, Relation relsetting, GucSource sou
|
|||
&keys[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid));
|
||||
ScanKeyInit(&keys[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid));
|
||||
|
||||
scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true, SnapshotNow, 2, keys);
|
||||
scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true, NULL, 2, keys);
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
bool isnull = false;
|
||||
Datum datum;
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDep
|
|||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
if (skipExtensionDeps && ((Form_pg_depend)GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
|
||||
|
|
@ -291,7 +291,7 @@ long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId,
|
|||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -361,7 +361,7 @@ long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefOb
|
|||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
|
||||
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -420,7 +420,7 @@ static bool isObjectPinned(const ObjectAddress* object, Relation rel)
|
|||
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
|
||||
scan = systable_beginscan(rel, DependReferenceIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(rel, DependReferenceIndexId, true, NULL, 2, key);
|
||||
|
||||
/*
|
||||
* Since we won't generate additional pg_depend entries for pinned
|
||||
|
|
@ -469,7 +469,7 @@ Oid getExtensionOfObject(Oid classId, Oid objectId)
|
|||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
|
||||
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -511,7 +511,7 @@ bool sequenceIsOwned(Oid seqId, Oid* tableId, int32* colId)
|
|||
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(seqId));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
|
||||
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -559,7 +559,7 @@ List* getOwnedSequences(Oid relid, List* attrList)
|
|||
&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
|
||||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -612,7 +612,7 @@ Oid get_constraint_index(Oid constraintId)
|
|||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(constraintId));
|
||||
ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0));
|
||||
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 3, key);
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 3, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -657,7 +657,7 @@ Oid get_index_constraint(Oid indexId)
|
|||
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(indexId));
|
||||
ScanKeyInit(&key[2], Anum_pg_depend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0));
|
||||
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 3, key);
|
||||
scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 3, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ void EnumValuesDelete(Oid enumTypeOid)
|
|||
|
||||
ScanKeyInit(&key[0], Anum_pg_enum_enumtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(enumTypeOid));
|
||||
|
||||
scan = systable_beginscan(pg_enum, EnumTypIdLabelIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(pg_enum, EnumTypIdLabelIndexId, true, NULL, 1, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
simple_heap_delete(pg_enum, &tup->t_self);
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ Oid searchHashBucketByBucketid(oidvector *bucketlist, Oid bucketid)
|
|||
BTEqualStrategyNumber, F_INT4EQ,
|
||||
Int32GetDatum(bucketlist->dim1));
|
||||
|
||||
scan = systable_beginscan(pg_hashbucket, HashBucketBidIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(pg_hashbucket, HashBucketBidIndexId, true, NULL, 3, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Datum bucketDatum;
|
||||
bool isnull = false;
|
||||
|
|
@ -440,7 +440,7 @@ text* searchMergeListByRelid(Oid reloid, bool *find, bool retresult)
|
|||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(reloid));
|
||||
|
||||
scan = systable_beginscan(pgxc_class_rel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(pgxc_class_rel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Datum pgxcDatum;
|
||||
bool isnull = false;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ List* find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
|
|||
|
||||
ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentrelId));
|
||||
|
||||
scan = systable_beginscan(relation, InheritsParentIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(relation, InheritsParentIndexId, true, NULL, 1, key);
|
||||
|
||||
while ((inheritsTuple = systable_getnext(scan)) != NULL) {
|
||||
inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid;
|
||||
|
|
@ -297,7 +297,7 @@ bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
|
|||
|
||||
ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(this_relid));
|
||||
|
||||
inhscan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, &skey);
|
||||
inhscan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while ((inhtup = systable_getnext(inhscan)) != NULL) {
|
||||
Form_pg_inherits inh = (Form_pg_inherits)GETSTRUCT(inhtup);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void LargeObjectDrop(Oid loid)
|
|||
*/
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
|
||||
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -110,7 +110,7 @@ void LargeObjectDrop(Oid loid)
|
|||
*/
|
||||
ScanKeyInit(&skey[0], Anum_pg_largeobject_loid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
|
||||
|
||||
scan = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndexId, true, NULL, 1, skey);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
simple_heap_delete(pg_largeobject, &tuple->t_self);
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ void LargeObjectAlterOwner(Oid loid, Oid newOwnerId)
|
|||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
|
||||
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
oldtup = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(oldtup))
|
||||
|
|
@ -232,7 +232,7 @@ bool LargeObjectExists(Oid loid)
|
|||
|
||||
pg_lo_meta = heap_open(LargeObjectMetadataRelationId, AccessShareLock);
|
||||
|
||||
sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey);
|
||||
sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
tuple = systable_getnext(sd);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
|
|
|
|||
|
|
@ -694,7 +694,7 @@ List* getPartitionObjectIdList(Oid relid, char relkind)
|
|||
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind));
|
||||
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
|
||||
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, NULL, 2, key);
|
||||
while (HeapTupleIsValid((tuple = systable_getnext(scan)))) {
|
||||
partitionid = HeapTupleGetOid(tuple);
|
||||
|
||||
|
|
@ -728,7 +728,7 @@ List* searchPartitionIndexesByblid(Oid blid)
|
|||
|
||||
ScanKeyInit(&key[0], Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(blid));
|
||||
|
||||
scan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, NULL, 1, key);
|
||||
while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
|
||||
dtp = heap_copytuple(tup);
|
||||
l = lappend(l, dtp);
|
||||
|
|
@ -761,7 +761,7 @@ List* searchPgPartitionByParentId(char parttype, Oid parentId)
|
|||
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(parttype));
|
||||
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentId));
|
||||
|
||||
scan = systable_beginscan(pg_partition, PartitionParentOidIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(pg_partition, PartitionParentOidIndexId, true, NULL, 2, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
dtuple = heap_copytuple(tuple);
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ void RangeDelete(Oid rangeTypeOid)
|
|||
|
||||
ScanKeyInit(&key[0], Anum_pg_range_rngtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(rangeTypeOid));
|
||||
|
||||
scan = systable_beginscan(pg_range, RangeTypidIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(pg_range, RangeTypidIndexId, true, NULL, 1, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
simple_heap_delete(pg_range, &tup->t_self);
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ static void shdepChangeDep(Relation sdepRel, Oid classid, Oid objid, int32 objsu
|
|||
ScanKeyInit(&key[2], Anum_pg_shdepend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid));
|
||||
ScanKeyInit(&key[3], Anum_pg_shdepend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(objsubid));
|
||||
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 4, key);
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 4, key);
|
||||
|
||||
while ((scantup = systable_getnext(scan)) != NULL) {
|
||||
/* Ignore if not of the target dependency type */
|
||||
|
|
@ -478,7 +478,7 @@ SysScanDesc initAndGetScanByRefId(Relation sdepRel, Oid classId, Oid objectId)
|
|||
ScanKeyInit(&key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
|
||||
ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
|
||||
|
||||
return systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, SnapshotNow, NumberOfReferenceKey, key);
|
||||
return systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, NULL, NumberOfReferenceKey, key);
|
||||
}
|
||||
|
||||
SysScanDesc initAndGetScanByDependerIndexId(
|
||||
|
|
@ -511,7 +511,7 @@ SysScanDesc initAndGetScanByDependerIndexId(
|
|||
}
|
||||
}
|
||||
|
||||
return systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, maxAttributeId, key);
|
||||
return systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, maxAttributeId, key);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -708,7 +708,7 @@ void copyTemplateDependencies(Oid templateDbId, Oid newDbId)
|
|||
/* Scan all entries with dbid = templateDbId */
|
||||
ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(templateDbId));
|
||||
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 1, key);
|
||||
|
||||
/* Set up to copy the tuples except for inserting newDbId */
|
||||
rc = memset_s(values, sizeof(values), 0, sizeof(values));
|
||||
|
|
@ -788,7 +788,7 @@ void dropDatabaseDependencies(Oid databaseId)
|
|||
*/
|
||||
ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseId));
|
||||
/* We leave the other index fields unspecified */
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 1, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
#ifdef ENABLE_MOT
|
||||
|
|
@ -918,7 +918,7 @@ static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int
|
|||
nkeys = 4;
|
||||
}
|
||||
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, nkeys, key);
|
||||
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, nkeys, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_shdepend shdepForm = (Form_pg_shdepend)GETSTRUCT(tup);
|
||||
|
|
@ -1410,7 +1410,7 @@ bool CheckDependencyOnRespool(Oid classId, Oid refobjectId, List** foundlist, bo
|
|||
&key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ResourcePoolRelationId));
|
||||
ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(refobjectId));
|
||||
|
||||
scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, NULL, 2, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_shdepend sdepForm = (Form_pg_shdepend)GETSTRUCT(tup);
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ bool RelationRedisCheck(Relation rel)
|
|||
&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
|
||||
htup = systable_getnext(pcscan);
|
||||
if (!HeapTupleIsValid(htup)) {
|
||||
/* Assume local relation only */
|
||||
|
|
|
|||
|
|
@ -687,6 +687,7 @@ void RelationTruncate(Relation rel, BlockNumber nblocks)
|
|||
rel->rd_smgr->smgr_targblock = InvalidBlockNumber;
|
||||
rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber;
|
||||
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
|
||||
rel->rd_smgr->smgr_cached_nblocks = InvalidBlockNumber;
|
||||
|
||||
for (int i = 0; i < rel->rd_smgr->smgr_bcmarry_size; i++)
|
||||
rel->rd_smgr->smgr_bcm_nblocks[i] = InvalidBlockNumber;
|
||||
|
|
|
|||
|
|
@ -3453,3 +3453,4 @@ CREATE unlogged table statement_history(
|
|||
);
|
||||
REVOKE ALL on table pg_catalog.statement_history FROM public;
|
||||
create index statement_history_time_idx on pg_catalog.statement_history USING btree (start_time, is_slow_sql);
|
||||
CREATE OR REPLACE VIEW pg_catalog.gs_archive_status AS SELECT * FROM gs_get_archive_status();
|
||||
|
|
@ -992,7 +992,7 @@ void remove_cmk_args_by_id(Oid id)
|
|||
HeapTuple tuple;
|
||||
|
||||
ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id));
|
||||
scan = systable_beginscan(ce_rel, ClientLogicGlobalSettingsArgsOidIndexId, true, SnapshotNow, 1, &scankey);
|
||||
scan = systable_beginscan(ce_rel, ClientLogicGlobalSettingsArgsOidIndexId, true, NULL, 1, &scankey);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -1010,7 +1010,7 @@ void remove_cek_args_by_id(Oid id)
|
|||
HeapTuple tuple;
|
||||
|
||||
ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id));
|
||||
scan = systable_beginscan(ce_rel, ClientLogicColumnSettingsArgsOidIndexId, true, SnapshotNow, 1, &scankey);
|
||||
scan = systable_beginscan(ce_rel, ClientLogicColumnSettingsArgsOidIndexId, true, NULL, 1, &scankey);
|
||||
|
||||
tuple = systable_getnext(scan);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
|
@ -1032,7 +1032,7 @@ void get_global_setting_description(StringInfo buffer, const ObjectAddress *obje
|
|||
cmKeys = heap_open(ClientLogicGlobalSettingsId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
rcscan = systable_beginscan(cmKeys, ClientLogicGlobalSettingsOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(cmKeys, ClientLogicGlobalSettingsOidIndexId, true, NULL, 1, skey);
|
||||
tup = systable_getnext(rcscan);
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
systable_endscan(rcscan);
|
||||
|
|
@ -1057,7 +1057,7 @@ void get_column_setting_description(StringInfo buffer, const ObjectAddress *obje
|
|||
column_setting_rel = heap_open(ClientLogicColumnSettingsId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
rcscan = systable_beginscan(column_setting_rel, ClientLogicColumnSettingsOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(column_setting_rel, ClientLogicColumnSettingsOidIndexId, true, NULL, 1, skey);
|
||||
tup = systable_getnext(rcscan);
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
systable_endscan(rcscan);
|
||||
|
|
@ -1105,7 +1105,7 @@ void get_global_setting_args_description(StringInfo buffer, const ObjectAddress
|
|||
rel = heap_open(ClientLogicGlobalSettingsArgsId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
rcscan = systable_beginscan(rel, ClientLogicGlobalSettingsArgsOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(rel, ClientLogicGlobalSettingsArgsOidIndexId, true, NULL, 1, skey);
|
||||
tup = systable_getnext(rcscan);
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
systable_endscan(rcscan);
|
||||
|
|
@ -1129,7 +1129,7 @@ void get_column_setting_args_description(StringInfo buffer, const ObjectAddress
|
|||
rel = heap_open(ClientLogicColumnSettingsArgsId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
|
||||
rcscan = systable_beginscan(rel, ClientLogicColumnSettingsArgsOidIndexId, true, SnapshotNow, 1, skey);
|
||||
rcscan = systable_beginscan(rel, ClientLogicColumnSettingsArgsOidIndexId, true, NULL, 1, skey);
|
||||
tup = systable_getnext(rcscan);
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
systable_endscan(rcscan);
|
||||
|
|
|
|||
|
|
@ -288,3 +288,22 @@ bool DllistWithLock::IsEmpty()
|
|||
END_CRIT_SECTION();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Dlelem* DllistWithLock::GetHead()
|
||||
{
|
||||
Dlelem* head = NULL;
|
||||
head = m_list.dll_head;
|
||||
return head;
|
||||
}
|
||||
|
||||
void DllistWithLock::GetLock()
|
||||
{
|
||||
START_CRIT_SECTION();
|
||||
SpinLockAcquire(&(m_lock));
|
||||
}
|
||||
|
||||
void DllistWithLock::ReleaseLock()
|
||||
{
|
||||
SpinLockRelease(&(m_lock));
|
||||
END_CRIT_SECTION();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1384,20 +1384,12 @@ DIRECT_TRUST:
|
|||
*/
|
||||
bool IsLoopBackAddr(Port* port)
|
||||
{
|
||||
struct sockaddr* remote_addr = (struct sockaddr*)&(port->raddr.addr);
|
||||
const SockAddr remote_addr = port->raddr;
|
||||
char remote_ip[IP_LEN] = {0};
|
||||
char* result = NULL;
|
||||
|
||||
/* parse the remote ip address */
|
||||
if (AF_INET6 == remote_addr->sa_family) {
|
||||
result = inet_net_ntop(AF_INET6, &((struct sockaddr_in*)remote_addr)->sin_addr, IPV6_MAXLEN, remote_ip, IP_LEN);
|
||||
} else if (AF_INET == remote_addr->sa_family) {
|
||||
result = inet_net_ntop(AF_INET, &((struct sockaddr_in*)remote_addr)->sin_addr, IPV4_MAXLEN, remote_ip, IP_LEN);
|
||||
}
|
||||
(void)pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen, remote_ip, sizeof(remote_ip), NULL, 0,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
|
||||
if (result == NULL) {
|
||||
ereport(WARNING, (errmsg("inet_net_ntop remote failed, error: %d", EAFNOSUPPORT)));
|
||||
}
|
||||
/* only the remote ip equal to 127.0.0.1 or ::1, return true */
|
||||
if (strlen(remote_ip) != 0 && (strcmp(remote_ip, LOOP_IP_STRING) == 0 || strcmp(remote_ip, LOOP_IPV6_IP) == 0)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1317,6 +1317,21 @@ static int pq_discardbytes(size_t len)
|
|||
{
|
||||
size_t amount;
|
||||
|
||||
ereport(WARNING,
|
||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||
errmsg("incomplete message, client info [Remote IP: %s PORT: %s FD: %d BLOCK: %d], "
|
||||
"packet info [PqRecvLength: %d PqRecvPointer: %d expectedLen: %d].",
|
||||
u_sess->proc_cxt.MyProcPort->remote_host,
|
||||
(u_sess->proc_cxt.MyProcPort->remote_port != NULL &&
|
||||
u_sess->proc_cxt.MyProcPort->remote_port[0] != '\0')
|
||||
? u_sess->proc_cxt.MyProcPort->remote_port : "",
|
||||
u_sess->proc_cxt.MyProcPort->sock,
|
||||
u_sess->proc_cxt.MyProcPort->noblock,
|
||||
t_thrd.libpq_cxt.PqRecvLength,
|
||||
t_thrd.libpq_cxt.PqRecvPointer,
|
||||
(int)len)));
|
||||
PrintUnexpectedBufferContent(t_thrd.libpq_cxt.PqRecvBuffer, t_thrd.libpq_cxt.PqRecvLength);
|
||||
|
||||
while (len > 0) {
|
||||
while (t_thrd.libpq_cxt.PqRecvPointer >= t_thrd.libpq_cxt.PqRecvLength) {
|
||||
if (pq_recvbuf()) { /* If nothing in buffer, then recv some */
|
||||
|
|
@ -2407,3 +2422,55 @@ static size_t pq_disk_read_data_block(
|
|||
|
||||
return read_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* To facilitate fault locating, abnormal packets need to be recorded.
|
||||
* For security purposes, the maximum print length does not exceed the buffer length.
|
||||
*/
|
||||
void PrintUnexpectedBufferContent(const char *buffer, int len)
|
||||
{
|
||||
if (buffer == NULL) {
|
||||
Assert(buffer);
|
||||
ereport(ERROR,
|
||||
(errmodule(MOD_COMM_PARAM),
|
||||
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("PrintUnexpectedPqBufferContent: invalid params[buffer: null len: %d]", len)));
|
||||
}
|
||||
if (len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Line-by-line printing with a width limit of 1024 */
|
||||
const int nBytePrintLine = 1024;
|
||||
const int pqBufferSize = PQ_BUFFER_SIZE;
|
||||
const char defaultNullChar = ' ';
|
||||
char tmp[nBytePrintLine + 1] = {0};
|
||||
int i, idx = 0;
|
||||
len = (len > pqBufferSize) ? pqBufferSize : len;
|
||||
|
||||
ereport(WARNING, (errmsg("--------buffer begin--------")));
|
||||
for (i = 0; i < len; i++) {
|
||||
idx = i % nBytePrintLine;
|
||||
|
||||
if (buffer[i] != '\0') {
|
||||
tmp[idx] = buffer[i];
|
||||
} else {
|
||||
tmp[idx] = defaultNullChar;
|
||||
}
|
||||
if ((i + 1) % nBytePrintLine == 0) {
|
||||
ereport(WARNING, (errmsg("%s", tmp)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Output buffer with the remaining length. */
|
||||
if (len % nBytePrintLine != 0) {
|
||||
/* reset dirty data */
|
||||
if (idx <= nBytePrintLine) {
|
||||
errno_t rc = memset_s(tmp + idx + 1, nBytePrintLine - idx, 0, nBytePrintLine - idx);
|
||||
securec_check(rc, "\0", "\0");
|
||||
}
|
||||
ereport(WARNING, (errmsg("%s", tmp)));
|
||||
}
|
||||
ereport(WARNING, (errmsg("--------buffer end--------")));
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4211,6 +4211,9 @@ static Query* _copyQuery(const Query* from)
|
|||
COPY_SCALAR_FIELD(use_star_targets);
|
||||
COPY_SCALAR_FIELD(is_from_full_join_rewrite);
|
||||
COPY_SCALAR_FIELD(uniqueSQLId);
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
COPY_STRING_FIELD(unique_sql_text);
|
||||
#endif
|
||||
COPY_SCALAR_FIELD(can_push);
|
||||
COPY_SCALAR_FIELD(unique_check);
|
||||
|
||||
|
|
|
|||
|
|
@ -3972,7 +3972,7 @@ static bool is_rel_child_of_rel(RangeTblEntry* child_rte, RangeTblEntry* parent_
|
|||
/* Scan pg_inherits and get all the subclass OIDs one by one. */
|
||||
relation = heap_open(InheritsRelationId, AccessShareLock);
|
||||
ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentOID));
|
||||
scan = systable_beginscan(relation, InheritsParentIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(relation, InheritsParentIndexId, true, NULL, 1, key);
|
||||
|
||||
while ((inheritsTuple = systable_getnext(scan)) != NULL) {
|
||||
inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid;
|
||||
|
|
|
|||
|
|
@ -219,6 +219,8 @@ static void get_rel_partition_info(Relation partTableRel, List** pos, Const** up
|
|||
static void get_src_partition_bound(Relation partTableRel, Oid srcPartOid, Const** lowBound, Const** upBound);
|
||||
static Oid get_split_partition_oid(Relation partTableRel, SplitPartitionState* splitState);
|
||||
static List* add_range_partition_def_state(List* xL, List* boundary, const char* partName, const char* tblSpaceName);
|
||||
static bool CheckStepInRange(ParseState *pstate, Const *startVal, Const *endVal, Const *everyVal,
|
||||
Form_pg_attribute attr);
|
||||
static List* divide_start_end_every_internal(ParseState* pstate, char* partName, Form_pg_attribute attr,
|
||||
Const* startVal, Const* endVal, Node* everyExpr, int* numPart,
|
||||
int maxNum, bool isinterval, bool needCheck, bool isPartition);
|
||||
|
|
@ -1406,6 +1408,15 @@ static void transformTableLikeClause(
|
|||
def->storage = 0;
|
||||
/* copy compression mode from source table */
|
||||
def->cmprs_mode = attribute->attcmprmode;
|
||||
/*
|
||||
* When analyzing a column-oriented table with default_statistics_target < 0, we will create a row-oriented
|
||||
* temp table. In this case, ignore the compression flag.
|
||||
*/
|
||||
if (u_sess->analyze_cxt.is_under_analyze) {
|
||||
if (def->cmprs_mode != ATT_CMPR_UNDEFINED) {
|
||||
def->cmprs_mode = ATT_CMPR_NOCOMPRESS;
|
||||
}
|
||||
}
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->collClause = NULL;
|
||||
|
|
@ -3949,6 +3960,16 @@ List* transformAlterTableStmt(Oid relid, AlterTableStmt* stmt, const char* query
|
|||
break;
|
||||
|
||||
case AT_SplitPartition:
|
||||
if (!RELATION_IS_PARTITIONED(rel))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmodule(MOD_OPT),
|
||||
errmsg("can not split partition against NON-PARTITIONED table")));
|
||||
if (rel->partMap->type == PART_TYPE_LIST || rel->partMap->type == PART_TYPE_HASH) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("can not split LIST/HASH partition table")));
|
||||
}
|
||||
|
||||
/* transform the boundary of range partition: from A_Const into Const */
|
||||
splitDefState = (SplitPartitionState*)cmd->def;
|
||||
if (!PointerIsValid(splitDefState->split_point)) {
|
||||
|
|
@ -3969,12 +3990,6 @@ List* transformAlterTableStmt(Oid relid, AlterTableStmt* stmt, const char* query
|
|||
Const* upBound = NULL;
|
||||
Oid srcPartOid = InvalidOid;
|
||||
|
||||
if (!RELATION_IS_PARTITIONED(rel))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmodule(MOD_OPT),
|
||||
errmsg("can not split partition against NON-PARTITIONED table")));
|
||||
|
||||
/* get partition number */
|
||||
partNum = getNumberOfPartitions(rel);
|
||||
|
||||
|
|
@ -5408,6 +5423,7 @@ static void get_src_partition_bound(Relation partTableRel, Oid srcPartOid, Const
|
|||
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("CAN NOT get detail info from a partitioned relation WITHOUT specified partition.")));
|
||||
|
||||
Assert(partTableRel->partMap->type == PART_TYPE_RANGE || partTableRel->partMap->type == PART_TYPE_INTERVAL);
|
||||
partMap = (RangePartitionMap*)partTableRel->partMap;
|
||||
|
||||
srcPartSeq = partOidGetPartSequence(partTableRel, srcPartOid) - 1;
|
||||
|
|
@ -5727,6 +5743,63 @@ static Oid choose_coerce_type(Oid leftid, Oid rightid)
|
|||
return InvalidOid; /* let make_op decide */
|
||||
}
|
||||
|
||||
/* check if everyVal <= endVal - startVal, but think of overflow, we should be careful */
|
||||
static bool CheckStepInRange(ParseState *pstate, Const *startVal, Const *endVal, Const *everyVal,
|
||||
Form_pg_attribute attr)
|
||||
{
|
||||
List *opr_mi = list_make1(makeString("-"));
|
||||
List *opr_lt = list_make1(makeString("<"));
|
||||
List *opr_le = list_make1(makeString("<="));
|
||||
|
||||
Datum res;
|
||||
Oid targetType = attr->atttypid;
|
||||
Oid targetCollation = attr->attcollation;
|
||||
int16 targetLen = attr->attlen;
|
||||
bool targetByval = attr->attbyval;
|
||||
bool targetIsVarlena = (!targetByval) && (targetLen == -1);
|
||||
int32 targetTypmod;
|
||||
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID) {
|
||||
targetTypmod = -1; /* avoid accuracy-problem of date */
|
||||
} else {
|
||||
targetTypmod = attr->atttypmod;
|
||||
}
|
||||
|
||||
Const *zeroVal = NULL;
|
||||
if (targetType == NUMERICOID) {
|
||||
zeroVal = makeConst(NUMERICOID, targetTypmod, targetCollation, targetLen,
|
||||
(Datum)DirectFunctionCall3(numeric_in, CStringGetDatum("0.0"), ObjectIdGetDatum(0), Int32GetDatum(-1)),
|
||||
false, targetByval);
|
||||
} else if (targetIsVarlena) {
|
||||
zeroVal = makeConst(UNKNOWNOID, targetTypmod, targetCollation, targetLen,
|
||||
(Datum)DirectFunctionCall1(byteain, CStringGetDatum("")), false, targetByval);
|
||||
} else {
|
||||
zeroVal = makeConst(targetType, targetTypmod, targetCollation, targetLen, (Datum)0, false, targetByval);
|
||||
}
|
||||
|
||||
res = evaluate_opexpr(pstate, opr_lt, (Node *)startVal, (Node *)zeroVal, NULL, -1);
|
||||
bool flag1 = DatumGetBool(res); /* whether startVal < 0 */
|
||||
res = evaluate_opexpr(pstate, opr_lt, (Node *)endVal, (Node *)zeroVal, NULL, -1);
|
||||
bool flag2 = DatumGetBool(res); /* whether endVal < 0 */
|
||||
|
||||
/* we've checked startVal < endVal, so if startVal >= 0, make sure endVal >= 0 too,
|
||||
* (!flag1 && flage) can never happen */
|
||||
Assert(flag1 || !flag2);
|
||||
|
||||
if (flag1 && !flag2) { /* startVal < 0 && endVal >= 0 */
|
||||
/* check if startVal <= endVal - everyVal */
|
||||
res = evaluate_opexpr(pstate, opr_mi, (Node *)endVal, (Node *)everyVal, &targetType, -1);
|
||||
Const *secheck = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval);
|
||||
res = evaluate_opexpr(pstate, opr_le, (Node *)startVal, (Node *)secheck, NULL, -1);
|
||||
} else { /* startVal < 0 && endVal < 0, or startVal >= 0 && endVal >= 0 */
|
||||
/* check if everyVal <= endVal - startVal */
|
||||
res = evaluate_opexpr(pstate, opr_mi, (Node *)endVal, (Node *)startVal, &everyVal->consttype, -1);
|
||||
Const *secheck =
|
||||
makeConst(everyVal->consttype, targetTypmod, targetCollation, targetLen, res, false, targetByval);
|
||||
res = evaluate_opexpr(pstate, opr_le, (Node *)everyVal, (Node *)secheck, NULL, -1);
|
||||
}
|
||||
return DatumGetBool(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* divide_start_end_every_internal
|
||||
* internal implementaion for dividing an interval indicated by any-datatype
|
||||
|
|
@ -5756,6 +5829,7 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
|
|||
{
|
||||
List* result = NIL;
|
||||
List* opr_pl = NIL;
|
||||
List* opr_mi = NIL;
|
||||
List* opr_lt = NIL;
|
||||
List* opr_le = NIL;
|
||||
List* opr_mul = NIL;
|
||||
|
|
@ -5765,7 +5839,6 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
|
|||
Oid restypid;
|
||||
Const* curpnt = NULL;
|
||||
int32 nPart;
|
||||
bool isEnd = false;
|
||||
Const* everyVal = NULL;
|
||||
Oid targetType;
|
||||
bool targetByval = false;
|
||||
|
|
@ -5777,11 +5850,23 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
|
|||
Assert(maxNum > 0 && maxNum <= MAX_PARTITION_NUM);
|
||||
|
||||
opr_pl = list_make1(makeString("+"));
|
||||
opr_mi = list_make1(makeString("-"));
|
||||
opr_lt = list_make1(makeString("<"));
|
||||
opr_le = list_make1(makeString("<="));
|
||||
opr_mul = list_make1(makeString("*"));
|
||||
opr_eq = list_make1(makeString("="));
|
||||
|
||||
/* get target type info */
|
||||
targetType = attr->atttypid;
|
||||
targetByval = attr->attbyval;
|
||||
targetCollation = attr->attcollation;
|
||||
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID) {
|
||||
targetTypmod = -1; /* avoid accuracy-problem of date */
|
||||
} else {
|
||||
targetTypmod = attr->atttypmod;
|
||||
}
|
||||
targetLen = attr->attlen;
|
||||
|
||||
/*
|
||||
* cast everyExpr to targetType
|
||||
* Note: everyExpr goes through transformExpr and transformIntoConst already.
|
||||
|
|
@ -5790,31 +5875,43 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
|
|||
|
||||
/* first compare start/end value */
|
||||
res = evaluate_opexpr(pstate, opr_le, (Node*)endVal, (Node*)startVal, NULL, -1);
|
||||
if (DatumGetBool(res))
|
||||
if (DatumGetBool(res)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("start value must be less than end value for %s \"%s\".",
|
||||
partTypeName, partName)));
|
||||
}
|
||||
|
||||
/* get target type info */
|
||||
targetType = attr->atttypid;
|
||||
targetByval = attr->attbyval;
|
||||
targetCollation = attr->attcollation;
|
||||
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID)
|
||||
targetTypmod = -1; /* avoid accuracy-problem of date */
|
||||
else
|
||||
targetTypmod = attr->atttypmod;
|
||||
targetLen = attr->attlen;
|
||||
/* second, we should make sure that everyVal <= endVal - startVal */
|
||||
if (!CheckStepInRange(pstate, startVal, endVal, everyVal, attr)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("%s step is too big for %s \"%s\".", partTypeName, partTypeName, partName)));
|
||||
}
|
||||
|
||||
/* build result */
|
||||
curpnt = startVal;
|
||||
nPart = 0;
|
||||
isEnd = false;
|
||||
while (nPart < maxNum) {
|
||||
/* compute currentPnt + everyval */
|
||||
res = evaluate_opexpr(pstate, opr_pl, (Node*)curpnt, (Node*)everyVal, &targetType, -1);
|
||||
pnt = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval);
|
||||
pnt = (Const*)GetTargetValue(attr, (Const*)pnt, false);
|
||||
while (true) {
|
||||
/* if too many partitions, report error */
|
||||
if (nPart >= maxNum) {
|
||||
pfree_ext(pnt);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("too many %ss after split %s \"%s\".", partTypeName, partTypeName, partName),
|
||||
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not assigned.",
|
||||
partTypeName, MAX_PARTITION_NUM)));
|
||||
}
|
||||
|
||||
/* compute curpnt + everyval, but if curpnt + everyVal > endVal, we use endVal instead,
|
||||
* so we can make sure that pnt <= endVal */
|
||||
if (!CheckStepInRange(pstate, curpnt, endVal, everyVal, attr)) {
|
||||
pnt = (Const*)copyObject(endVal);
|
||||
} else {
|
||||
res = evaluate_opexpr(pstate, opr_pl, (Node*)curpnt, (Node*)everyVal, &targetType, -1);
|
||||
pnt = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval);
|
||||
pnt = (Const*)GetTargetValue(attr, (Const*)pnt, false);
|
||||
}
|
||||
|
||||
/* necessary check in first pass */
|
||||
if (nPart == 0) {
|
||||
|
|
@ -5865,47 +5962,24 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
|
|||
errmsg("%s step is too small for %s \"%s\".", partTypeName, partTypeName, partName)));
|
||||
}
|
||||
|
||||
/* pnt must be less than or equal to endVal */
|
||||
Assert(DatumGetBool(evaluate_opexpr(pstate, opr_le, (Node*)pnt, (Node*)endVal, NULL, -1)));
|
||||
result = lappend(result, pnt);
|
||||
nPart++;
|
||||
|
||||
/* check to determine if it is the final partition */
|
||||
res = evaluate_opexpr(pstate, opr_le, (Node*)pnt, (Node*)endVal, NULL, -1);
|
||||
res = evaluate_opexpr(pstate, opr_eq, (Node*)pnt, (Node*)endVal, NULL, -1);
|
||||
if (DatumGetBool(res)) {
|
||||
result = lappend(result, pnt);
|
||||
nPart++;
|
||||
res = evaluate_opexpr(pstate, opr_lt, (Node*)pnt, (Node*)endVal, NULL, -1);
|
||||
if (!DatumGetBool(res)) {
|
||||
/* case-1: final partition just matches endVal */
|
||||
isEnd = true;
|
||||
break;
|
||||
}
|
||||
} else if (nPart == 0) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("%s step is too big for %s \"%s\".", partTypeName, partTypeName, partName)));
|
||||
} else {
|
||||
/* case-2: final partition is smaller than others */
|
||||
pfree_ext(pnt);
|
||||
pnt = (Const*)copyObject(endVal);
|
||||
result = lappend(result, pnt);
|
||||
nPart++;
|
||||
isEnd = true;
|
||||
break;
|
||||
}
|
||||
|
||||
curpnt = pnt;
|
||||
}
|
||||
|
||||
if (!isEnd) {
|
||||
/* too many partitions, report error */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("too many %ss after split %s \"%s\".", partTypeName, partTypeName, partName),
|
||||
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not assigned.",
|
||||
partTypeName, MAX_PARTITION_NUM)));
|
||||
}
|
||||
|
||||
/* done */
|
||||
Assert(result && result->length == nPart);
|
||||
if (numPart != NULL)
|
||||
if (numPart != NULL) {
|
||||
*numPart = nPart;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -6607,7 +6681,7 @@ List* transformRangePartStartEndStmt(ParseState* pstate, List* partitionList, Li
|
|||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("too many %ss after split %s \"%s\".",
|
||||
partTypeName, defState->partitionName, partTypeName),
|
||||
partTypeName, partTypeName, defState->partitionName),
|
||||
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not "
|
||||
"assigned.",
|
||||
partTypeName, MAX_PARTITION_NUM)));
|
||||
|
|
|
|||
|
|
@ -963,7 +963,7 @@ void RelationBuildLocator(Relation rel)
|
|||
&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
|
||||
htup = systable_getnext(pcscan);
|
||||
if (!HeapTupleIsValid(htup)) {
|
||||
/* Assume local relation only */
|
||||
|
|
|
|||
|
|
@ -3367,7 +3367,7 @@ char* PgxcGroupGetFirstLogicCluster()
|
|||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0));
|
||||
|
||||
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while ((tup = systable_getnext(scan)) != NULL) {
|
||||
group_kind = get_group_kind(tup);
|
||||
|
|
@ -4614,7 +4614,7 @@ List* PgxcGroupGetLogicClusterList(Bitmapset* nodeids)
|
|||
}
|
||||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0));
|
||||
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while ((tup = systable_getnext(scan)) != NULL) {
|
||||
Oid group_oid = HeapTupleGetOid(tup);
|
||||
|
|
|
|||
|
|
@ -1174,7 +1174,7 @@ void PgxcNodeAlter(AlterNodeStmt* stmt)
|
|||
|
||||
HeapTuple tmptup;
|
||||
TupleDesc pg_node_dsc = RelationGetDescr(rel);
|
||||
SysScanDesc scan = systable_beginscan(rel, InvalidOid, false, SnapshotNow, 0, NULL);
|
||||
SysScanDesc scan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL);
|
||||
while (HeapTupleIsValid((tmptup = systable_getnext(scan)))) {
|
||||
bool isnull = true;
|
||||
Oid scanoid = HeapTupleGetOid(tmptup);
|
||||
|
|
|
|||
|
|
@ -8210,7 +8210,7 @@ bool IsInheritor(Oid relid)
|
|||
|
||||
pginherits = heap_open(InheritsRelationId, AccessShareLock);
|
||||
ScanKeyInit(&key[0], Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, relid);
|
||||
scan = systable_beginscan(pginherits, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(pginherits, InheritsRelidSeqnoIndexId, true, NULL, 1, key);
|
||||
if (HeapTupleIsValid(systable_getnext(scan))) {
|
||||
ret = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ OBJS = acl.o arrayfuncs.o array_selfuncs.o array_typanalyze.o \
|
|||
tsquery_op.o tsquery_rewrite.o tsquery_util.o tsrank.o \
|
||||
tsvector.o tsvector_op.o tsvector_parser.o \
|
||||
txid.o uuid.o windowfuncs.o xml.o extended_statistics.o clientlogic_bytea.o clientlogicsettings.o \
|
||||
median_aggs.o
|
||||
median_aggs.o expr_distinct.o
|
||||
|
||||
like.o: like.cpp like_match.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ Datum globalsettingin(PG_FUNCTION_ARGS)
|
|||
CStringGetDatum(key_name_or_oid));
|
||||
|
||||
hdesc = heap_open(ClientLogicGlobalSettingsId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, ClientLogicGlobalSettingsNameIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, ClientLogicGlobalSettingsNameIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
|
||||
result = Oid HeapTupleGetOid(tuple);
|
||||
|
|
@ -166,7 +166,7 @@ Datum columnsettingin(PG_FUNCTION_ARGS)
|
|||
CStringGetDatum(key_name_or_oid));
|
||||
|
||||
hdesc = heap_open(ClientLogicColumnSettingsId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, ClientLogicColumnSettingsNameIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, ClientLogicColumnSettingsNameIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
|
||||
result = Oid HeapTupleGetOid(tuple);
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ static double calculate_source_database_size()
|
|||
/*scan the pg_class to fetch the reltuples of every relation.*/
|
||||
class_rel = heap_open(RelationRelationId, AccessShareLock);
|
||||
pg_class_tuple_desc = class_rel->rd_att;
|
||||
scan = systable_beginscan(class_rel, InvalidOid, false, SnapshotNow, 0, NULL);
|
||||
scan = systable_beginscan(class_rel, InvalidOid, false, NULL, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
tuple_class = (Form_pg_class)GETSTRUCT(tuple);
|
||||
Oid relid = HeapTupleHeaderGetOid(tuple->t_data);
|
||||
|
|
@ -1931,7 +1931,10 @@ Datum pg_filenode_relation(PG_FUNCTION_ARGS)
|
|||
Oid relfilenode = PG_GETARG_OID(1);
|
||||
Oid heaprel = InvalidOid;
|
||||
|
||||
heaprel = RelidByRelfilenode(reltablespace, relfilenode);
|
||||
heaprel = RelidByRelfilenodeCache(reltablespace, relfilenode);
|
||||
if (!OidIsValid(heaprel)) {
|
||||
heaprel = RelidByRelfilenode(reltablespace, relfilenode);
|
||||
}
|
||||
|
||||
if (!OidIsValid(heaprel))
|
||||
PG_RETURN_NULL();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,434 @@
|
|||
/* -------------------------------------------------------------------------
|
||||
*
|
||||
* expr_distinct.cpp
|
||||
* utility functions for get number of distinct of expressions
|
||||
*
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/utils/adt/expr_distinct.cpp
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "access/transam.h"
|
||||
#include "access/sysattr.h"
|
||||
#include "catalog/pg_statistic.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/nodes.h"
|
||||
#include "optimizer/cost.h"
|
||||
#include "optimizer/optimizerdebug.h"
|
||||
#include "optimizer/pathnode.h"
|
||||
#include "optimizer/planner.h"
|
||||
#include "optimizer/prep.h"
|
||||
#include "optimizer/restrictinfo.h"
|
||||
#include "optimizer/streamplan.h"
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_coerce.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "parser/parse_relation.h"
|
||||
#include "storage/buf/bufmgr.h"
|
||||
#include "storage/proc.h"
|
||||
#include "utils/dynahash.h"
|
||||
#include "utils/expr_distinct.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/selfuncs.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
/*
|
||||
* Context for estimate number of distinct of function
|
||||
*/
|
||||
typedef struct {
|
||||
double numDistinct[2]; /* numdistinct of the var */
|
||||
Oid attType; /* attType of current values */
|
||||
int numMcv; /* original number of MCV values in stats */
|
||||
int numHisBounds; /* original number of histogram bounds in stats */
|
||||
/* following data may change during runtime */
|
||||
int numFMcv; /* length of array mcvValues, may be changed at runtime */
|
||||
int numFHisBounds; /* length of array hisValues, simliar to mcvValues */
|
||||
Datum *fMcv; /* "MCV" values or f(..(MCV)), except NULL */
|
||||
Datum *fHisBounds; /* "histogram bounds" or f(..g(histogram bounds)), except NULL */
|
||||
bool needAdjust; /* whether var distinct need adjust */
|
||||
} EstiFuncDistinctContext;
|
||||
|
||||
static char *GetFunctionNameWithDefault(Oid fnOid);
|
||||
static void EstimateExprNumDistinct(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar,
|
||||
bool *isDefault);
|
||||
static void GetNumDistinctFuncExpr(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr, bool isJoinVar);
|
||||
static void GetExprNumDistinctWalker(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar);
|
||||
static void TransferFunctionNumDistinct(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr,
|
||||
bool isJoinVar);
|
||||
static bool CheckFuncArgsForTransferNumDistinct(FuncExpr *funcExpr, Node **varNode);
|
||||
static bool IsFunctionTransferNumDistinct(FuncExpr *funcExpr);
|
||||
|
||||
|
||||
/*
|
||||
* The array collects all of the type-cast functions which can transfer number of distinct from any one of
|
||||
* its arguments, other parameters are viewed as Const.
|
||||
*/
|
||||
static Oid g_typeCastFuncOids[] = {
|
||||
/* type cast from bool */
|
||||
BOOLTOINT1FUNCOID, BOOLTOINT2FUNCOID, BOOLTOINT4FUNCOID, BOOLTOINT8FUNCOID, BOOLTOTEXTFUNCOID,
|
||||
|
||||
/* type cast from int1 */
|
||||
I1TOI2FUNCOID, I1TOI4FUNCOID, I1TOI8FUNCOID, I1TOF4FUNCOID, I1TOF8FUNCOID, INT1TOBPCHARFUNCOID,
|
||||
INT1TOVARCHARFUNCOID, INT1TONVARCHAR2FUNCOID, INT1TOTEXTFUNCOID, INT1TONUMERICFUNCOID, INT1TOINTERVALFUNCOID,
|
||||
|
||||
/* type cast from int2 */
|
||||
I2TOI1FUNCOID, INT2TOINT4FUNCOID, INT2TOFLOAT4FUNCOID, INT2TOFLOAT8FUNCOID, INT2TOBPCHAR, INT2TOTEXTFUNCOID,
|
||||
INT2TOVARCHARFUNCOID, INT2TOINT8FUNCOID, INT2TONUMERICFUNCOID, INT2TOINTERVALFUNCOID,
|
||||
|
||||
/* type cast from int4 */
|
||||
I4TOI1FUNCOID, INT4TOINT2FUNCOID, INT4TOINT8FUNCOID, INT4TOFLOAT8FUNCOID, INTEGER2CASHFUNCOID,
|
||||
INT4TONUMERICFUNCOID, INT4TOINTERVALFUNCOID, INT4TOHEXFUNCOID, INT4TOBPCHARFUNCOID, INT4TOTEXTFUNCOID,
|
||||
INT4TOVARCHARFUNCOID, INT4TOCHARFUNCOID, INT4TOCHRFUNCOID,
|
||||
|
||||
/* type cast from int8 */
|
||||
I8TOI1FUNCOID, INT8TOINT2FUNCOID, INT8TOINT4FUNCOID, INT8TOBPCHARFUNCOID, INT8TOTEXTFUNCOID, INT8TOVARCHARFUNCOID,
|
||||
INT8TONUMERICFUNCOID, INT8TOHEXFUNCOID,
|
||||
|
||||
/* type cast from float4/float8 */
|
||||
FLOAT4TOBPCHARFUNCOID, FLOAT4TOTEXTFUNCOID, FLOAT4TOVARCHARFUNCOID, FLOAT4TOFLOAT8FUNCOID,
|
||||
FLOAT4TONUMERICFUNCOID, FLOAT8TOBPCHARFUNCOID, FLOAT8TOINTERVALFUNCOID, FLOAT8TOTEXTFUNCOID,
|
||||
FLOAT8TOVARCHARFUNCOID, FLOAT8TONUMERICFUNCOID, FLOAT8TOTIMESTAMPFUNCOID,
|
||||
|
||||
/* type cast from numeric */
|
||||
NUMERICTOBPCHARFUNCOID, NUMERICTOTEXTFUNCOID, NUMERICTOVARCHARFUNCOID,
|
||||
|
||||
/* type cast from timestamp/date/time */
|
||||
DEFAULTFORMATTIMESTAMP2CHARFUNCOID, DEFAULTFORMATTIMESTAMPTZ2CHARFUNCOID, TIMESATMPTOTEXTFUNCOID,
|
||||
TIMESTAMPTOVARCHARFUNCOID, TIMESTAMP2TIMESTAMPTZFUNCOID, TIMESTAMPTZ2TIMESTAMPFUNCOID,
|
||||
DATETIMESTAMPTZFUNCOID, DATETOTIMESTAMPFUNCOID, DATETOBPCHARFUNCOID, DATETOVARCHARFUNCOID, DATETOTEXTFUNCOID,
|
||||
DATEANDTIMETOTIMESTAMPFUNCOID, DTAETIME2TIMESTAMPTZFUNCOID, TIMETOINTERVALFUNCOID, TIMESTAMPZONETOTEXTFUNCOID,
|
||||
TIME2TIMETZFUNCOID, RELTIMETOINTERVALFUNCOID,
|
||||
|
||||
/* type cast from text */
|
||||
TODATEDEFAULTFUNCOID, TODATEFUNCOID, TOTIMESTAMPFUNCOID, TOTIMESTAMPDEFAULTFUNCOID,
|
||||
TEXTTOREGCLASSFUNCOID, TEXTTOINT1FUNCOID, TEXTTOINT2FUNCOID, TEXTTOINT4FUNCOID, TEXTTOINT8FUNCOID,
|
||||
TEXTTONUMERICFUNCOID, TEXTTOTIMESTAMP, TIMESTAMPTONEWTIMEZONEFUNCOID, TIMESTAMPTZTONEWTIMEZONEFUNCOID,
|
||||
HEXTORAWFUNCOID,
|
||||
|
||||
/* type cast from char/varchar/bpchar */
|
||||
VARCHARTONUMERICFUNCOID, VARCHARTOINT4FUNCOID, VARCHARTOINT8FUNCOID, VARCHARTOTIMESTAMPFUNCOID,
|
||||
BPCHARTOINT4FUNCOID, BPCHARTOINT8FUNCOID, BPCHARTONUMERICFUNCOID, BPCHARTOTIMESTAMPFUNCOID,
|
||||
RTRIM1FUNCOID, BPCHARTEXTFUNCOID, CHARTOBPCHARFUNCOID, CHARTOTEXTFUNCOID
|
||||
};
|
||||
|
||||
static char *GetFunctionNameWithDefault(Oid fnOid)
|
||||
{
|
||||
char *funcName = get_func_name(fnOid);
|
||||
if (funcName == NULL) {
|
||||
funcName = "unknown-name";
|
||||
}
|
||||
return funcName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entrance of the distinct estimation for expr whose stats is unavailable
|
||||
*
|
||||
* Handle expr-case in get_variable_numdistinct, aim to estimate variable distinct if no stats
|
||||
* (for the variable) are available. Also, GUC 'cost_model_version' controls the behaviour of
|
||||
* the router.
|
||||
*
|
||||
* Note:
|
||||
* - function get_variable_numdistinct and get_variable_numdistinct_router should be called
|
||||
* after examine_variable, otherwise, it may fail to get stats which actually exists.
|
||||
* - This function may fail to estimate expr distinct, returns 0.0 (means unknown).
|
||||
* - adjust ratio will be applied to the raw distinct if needAdjust is true, and
|
||||
* varData->needAdjust is used to transfer the indicators.
|
||||
*/
|
||||
double GetExprNumDistinctRouter(VariableStatData *varData, bool needAdjust, STATS_EST_TYPE eType, bool isJoinVar)
|
||||
{
|
||||
double distinct = 0.0;
|
||||
|
||||
int idx = 0;
|
||||
bool saveNeedAdjust = varData->needAdjust;
|
||||
varData->needAdjust = needAdjust;
|
||||
|
||||
ereport(DEBUG2, (errmodule(MOD_OPT), errmsg(
|
||||
"[Get Expr NumDistinct Router]: -------- <START>: adjust: %s --------", needAdjust ? "true" : "false")));
|
||||
if (IS_PGXC_COORDINATOR && (eType == STATS_TYPE_LOCAL)) {
|
||||
/* for local distinct */
|
||||
idx = 0;
|
||||
} else {
|
||||
/* for global distinct */
|
||||
idx = 1;
|
||||
}
|
||||
if (varData->numDistinct[idx] > 0.0) {
|
||||
distinct = clamp_row_est(varData->numDistinct[idx]);
|
||||
} else if (!varData->isEstimated) {
|
||||
GetExprNumDistinctWalker(varData->root, varData, varData->var, isJoinVar);
|
||||
varData->isEstimated = true;
|
||||
if (varData->numDistinct[idx] > 0.0) {
|
||||
distinct = clamp_row_est(varData->numDistinct[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
varData->needAdjust = saveNeedAdjust;
|
||||
ereport(DEBUG2, (errmodule(MOD_OPT),
|
||||
errmsg("[Get Expr NumDistinct Router]: -------- <END>: distinct: %.0lf --------", distinct)));
|
||||
|
||||
return distinct;
|
||||
}
|
||||
|
||||
/*
|
||||
* implementation of GetExprNumDistinctRouter with "cost_model_version = 1"
|
||||
*
|
||||
* NB: parameters node may be varData->var or other form or sub-node of varData->var
|
||||
*/
|
||||
static void GetExprNumDistinctWalker(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar)
|
||||
{
|
||||
char *exprName = NULL;
|
||||
|
||||
errno_t rc =
|
||||
memset_s(varData->numDistinct, sizeof(varData->numDistinct[0]) * 2, 0, sizeof(varData->numDistinct[0]) * 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
switch (nodeTag(node)) {
|
||||
case T_FuncExpr:
|
||||
exprName = "FuncExpr";
|
||||
GetNumDistinctFuncExpr(root, varData, (FuncExpr *)node, isJoinVar);
|
||||
break;
|
||||
default:
|
||||
exprName = "Unknown-Expr";
|
||||
break;
|
||||
}
|
||||
|
||||
ereport(DEBUG2,
|
||||
(errmodule(MOD_OPT),
|
||||
(errmsg("[%s Distinct Estimation]: local distinct is %.0lf, global distinct is %.0lf",
|
||||
exprName, varData->numDistinct[0], varData->numDistinct[1]))));
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate the number of distinct of function expression.
|
||||
*
|
||||
* Parameters:
|
||||
* @in funcExpr: the function expression to calculate distinct value
|
||||
* @in isJoinVar: is the node used for join?
|
||||
*
|
||||
* @out: vardata: set the distinct value on numdistinct.
|
||||
*/
|
||||
static void GetNumDistinctFuncExpr(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr, bool isJoinVar)
|
||||
{
|
||||
if (funcExpr->funcid >= FirstNormalObjectId) {
|
||||
/* user-defined function, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let p denotes function can transfer distinct, f all other functions, w type-cast functions
|
||||
* which can also transfer distinct. In general, p contains w. Then all possible cases are:
|
||||
* 1. p(p(p(..p(var)))): p include w,
|
||||
* transfer distinct of var to top level
|
||||
* 2. p(p(p(..p(f(var))))): p include w,
|
||||
* transfer distinct of f to top level, distinct of f is estimated from var
|
||||
* 3. f(var):
|
||||
* estimate distinct of f from var
|
||||
* 4. f(w(..w(var))
|
||||
* estimate distinct of f from var
|
||||
* 5. ..f(..(p(..))): p except w
|
||||
* can not estimate, return unknown
|
||||
* 6. ..f(..(f(..))):
|
||||
* can not estimate, return unknown
|
||||
*/
|
||||
|
||||
/* bool-return function */
|
||||
if (get_func_rettype(funcExpr->funcid) == BOOLOID) {
|
||||
varData->numDistinct[0] = 2.0;
|
||||
varData->numDistinct[1] = 2.0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (funcExpr->args == NULL) {
|
||||
ereport(DEBUG2,
|
||||
(errmodule(MOD_OPT),
|
||||
errmsg("[Func Distinct Estimation]:can not get number of distinct of function oid %u with no argument",
|
||||
funcExpr->funcid)));
|
||||
return;
|
||||
}
|
||||
|
||||
/* if failed to transfer, we can not estimate either */
|
||||
if (IsFunctionTransferNumDistinct(funcExpr)) {
|
||||
/* transfer the number of distinct */
|
||||
TransferFunctionNumDistinct(root, varData, funcExpr, isJoinVar);
|
||||
} else {
|
||||
/* estimate the number of distinct */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate the number of distinct of the specifed node, work for get_num_distinct_coalesce,
|
||||
* get_num_distinct_casewhen and so on. The estimated numdistinct are always given, stored in
|
||||
* vardata->numdistinct[2].
|
||||
*
|
||||
* Parameters:
|
||||
* @in varData: the info we need to calculate distinct value, numdistinct is returned in varData
|
||||
* @in node: the node to calculate distinct value
|
||||
* @in isJoinVar: is the node used for join?
|
||||
* @out isDefault: is the numdistinct is a default value ?
|
||||
*/
|
||||
static void EstimateExprNumDistinct(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar,
|
||||
bool *isDefault)
|
||||
{
|
||||
VariableStatData tmpVarData;
|
||||
SpecialJoinInfo sjInfo;
|
||||
errno_t rc = EOK;
|
||||
|
||||
varData->numDistinct[0] = 0.0;
|
||||
varData->numDistinct[1] = 0.0;
|
||||
|
||||
/* return after count it if it's Const. */
|
||||
if (IsA(node, Const)) {
|
||||
varData->numDistinct[0] = 1.0;
|
||||
varData->numDistinct[1] = 1.0;
|
||||
*isDefault = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX should min_lefthand ? */
|
||||
rc = memset_s(&sjInfo, sizeof(sjInfo), 0, sizeof(sjInfo));
|
||||
securec_check(rc, "\0", "\0");
|
||||
sjInfo.min_lefthand = root->all_baserels;
|
||||
sjInfo.min_righthand = NULL;
|
||||
|
||||
examine_variable(root, node, 0, &tmpVarData);
|
||||
tmpVarData.needAdjust = varData->needAdjust;
|
||||
double joinRatio = get_join_ratio(&tmpVarData, &sjInfo);
|
||||
varData->numDistinct[0] =
|
||||
get_variable_numdistinct(&tmpVarData, isDefault, tmpVarData.needAdjust, joinRatio, &sjInfo,
|
||||
STATS_TYPE_LOCAL, isJoinVar);
|
||||
varData->numDistinct[1] =
|
||||
get_variable_numdistinct(&tmpVarData, isDefault, tmpVarData.needAdjust, joinRatio, &sjInfo,
|
||||
STATS_TYPE_GLOBAL, isJoinVar);
|
||||
ReleaseVariableStats(tmpVarData);
|
||||
}
|
||||
|
||||
/*
|
||||
* try to transfer number of distinct of given funcExpr, return unknown if fail
|
||||
*/
|
||||
static void TransferFunctionNumDistinct(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr,
|
||||
bool isJoinVar)
|
||||
{
|
||||
bool isDefault = false;
|
||||
Node *varNode = NULL;
|
||||
|
||||
/* check arguments and find the var-argument */
|
||||
if (!CheckFuncArgsForTransferNumDistinct(funcExpr, &varNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* recursive to the arg, if there is no distinct for the arg, return unknown */
|
||||
EstimateExprNumDistinct(root, varData, varNode, isJoinVar, &isDefault);
|
||||
|
||||
ereport(DEBUG2,
|
||||
(errmodule(MOD_OPT),
|
||||
errmsg("[Func Distinct Estimation]: succeed to transfer number of distinct of function oid: %u",
|
||||
funcExpr->funcid)));
|
||||
}
|
||||
|
||||
/*
|
||||
* check arguments of the func, return true and var-node if ok. Assume there is only one var or expr(var,..) in
|
||||
* its arguments. We allow f(var, const), f(const, var), f(expr(var), const) and f(expr(var1, var2), const)
|
||||
*
|
||||
* return true if ok, and varNode indicates the location of the Var
|
||||
*/
|
||||
static bool CheckFuncArgsForTransferNumDistinct(FuncExpr *funcExpr, Node **varNode)
|
||||
{
|
||||
ListCell *listCell = NULL;
|
||||
int numVars = 0;
|
||||
Node *lastNode = NULL;
|
||||
|
||||
/* find the first "var" */
|
||||
foreach (listCell, funcExpr->args) {
|
||||
Node *node = (Node *)lfirst(listCell);
|
||||
if (IsA(node, Var)) {
|
||||
numVars++;
|
||||
lastNode = node;
|
||||
} else if (IsA(node, Const)) {
|
||||
continue;
|
||||
} else {
|
||||
List *varList =
|
||||
pull_var_clause(node, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_SPECIAL_EXPR);
|
||||
if (varList != NULL) {
|
||||
numVars++;
|
||||
lastNode = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numVars == 0) {
|
||||
*varNode = (Node *)linitial(funcExpr->args);
|
||||
return true;
|
||||
} else if (numVars == 1) {
|
||||
*varNode = lastNode;
|
||||
return true;
|
||||
} else {
|
||||
*varNode = NULL;
|
||||
ereport(DEBUG2, (errmodule(MOD_OPT),
|
||||
errmsg("[Check Args for Transfer]: more than one var-arguments for function oid: %u",
|
||||
funcExpr->funcid)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the function can transfer number of distinct from one of its parameters
|
||||
*/
|
||||
static bool IsFunctionTransferNumDistinct(FuncExpr *funcExpr)
|
||||
{
|
||||
/*
|
||||
* We explicitly allow or disallow functions to transfer number of distinct.
|
||||
*
|
||||
* If a function called in form of COERCE_EXPLICIT_CAST/COERCE_IMPLICIT_CAST, we can not
|
||||
* conclude that this function can transfer number of distinct, e.g.
|
||||
*
|
||||
* create table t1(price text);
|
||||
* values: '20.01',
|
||||
* '20.02',
|
||||
* '20.12',
|
||||
* '20.30',
|
||||
* '20.99',
|
||||
* '20.88'
|
||||
* select price from t1 where int1(price) = 20;
|
||||
* The filter transformed by Optimizer is:
|
||||
* (((numeric_in(textout(price), 0::oid, (-1)))::tinyint)::bigint = 20)
|
||||
*
|
||||
* numeric::tinyint is the function numeric_int1 which is called as COERCE_EXPLICIT_CAST,
|
||||
* and it will make rounding to ensure an integer is assigned to int1. Hence a explicitly
|
||||
* cast function may not transfer number of distinct.
|
||||
*/
|
||||
|
||||
Oid funcId = funcExpr->funcid;
|
||||
char *funcName = GetFunctionNameWithDefault(funcExpr->funcid);
|
||||
|
||||
/* special functions whose oid is not built-in, but we can transfer numdistinct for them */
|
||||
if (strcmp(funcName, "to_text") == 0 || strcmp(funcName, "to_varchar2") == 0 ||
|
||||
strcmp(funcName, "to_nvarchar2") == 0 || strcmp(funcName, "to_ts") == 0 ||
|
||||
(strcmp(funcName, "to_number") == 0 && (funcId != TONUMBERFUNCOID))) {
|
||||
pfree(funcName);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)lengthof(g_typeCastFuncOids); i++) {
|
||||
if (g_typeCastFuncOids[i] == funcId) {
|
||||
pfree(funcName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pfree(funcName);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -921,7 +921,7 @@ List* es_explore_declared_stats(Oid relid, VacuumStmt* vacstmt, bool inh)
|
|||
ScanKeyInit(&key[2], Anum_pg_statistic_ext_stainherit, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(inh));
|
||||
|
||||
Relation relation = heap_open(StatisticExtRelationId, AccessShareLock);
|
||||
SysScanDesc scan = systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, 3, key);
|
||||
SysScanDesc scan = systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, NULL, 3, key);
|
||||
|
||||
List* es_list = NIL;
|
||||
for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) {
|
||||
|
|
@ -1114,7 +1114,7 @@ static List* es_search_extended_statistics(
|
|||
|
||||
Relation relation = heap_open(StatisticExtRelationId, AccessShareLock);
|
||||
SysScanDesc scan =
|
||||
systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, num_key, key);
|
||||
systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, NULL, num_key, key);
|
||||
|
||||
int count = 0;
|
||||
for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) {
|
||||
|
|
|
|||
|
|
@ -5561,7 +5561,7 @@ static void NUM_numpart_from_char(NUMProc* Np, int id, int plen, int& tmp_len)
|
|||
* locale sign expected - last read char was NUM_0/9 or NUM_DEC - and
|
||||
* next char is not digit
|
||||
*/
|
||||
if (IS_LSIGN(Np->Num) && isread && (Np->inout_p + 1) <= Np->inout + plen &&
|
||||
if (IS_LSIGN(Np->Num) && isread && (Np->inout_p + 1) < Np->inout + plen &&
|
||||
!isdigit((unsigned char)*(Np->inout_p + 1))) {
|
||||
int x;
|
||||
char* tmp = Np->inout_p++;
|
||||
|
|
|
|||
|
|
@ -83,9 +83,14 @@ static Point* lseg_interpt_internal(LSEG* l1, LSEG* l2);
|
|||
#define LDELIM_C '<'
|
||||
#define RDELIM_C '>'
|
||||
|
||||
/* Maximum number of characters printed by pair_encode() */
|
||||
/* ...+3+7 : 3 accounts for extra_float_digits max value */
|
||||
#define P_MAXLEN (2 * (DBL_DIG + 3 + 7) + 1)
|
||||
/* Maximum number of characters printed by pair_encode().
|
||||
* The value range of float8 is -1.79E+308 ~ 1.79E+308.
|
||||
* For point(-1.79E+308,-1.79E+308),
|
||||
* (2 * (DBL_DIG + 3 + 7) + 1 + 1) : 3 accounts for extra_float_digits max value,
|
||||
* 7 accounts for "-.E+308", first number 1 accounts for comma in the middle of numbers,
|
||||
* last number 1 accounts for string terminator.
|
||||
*/
|
||||
#define P_MAXLEN (2 * (DBL_DIG + 3 + 7) + 1 + 1)
|
||||
|
||||
/*
|
||||
* Geometric data types are composed of points.
|
||||
|
|
|
|||
|
|
@ -94,11 +94,11 @@ Datum current_query(PG_FUNCTION_ARGS)
|
|||
#define SIGNAL_BACKEND_SUCCESS 0
|
||||
#define SIGNAL_BACKEND_ERROR 1
|
||||
#define SIGNAL_BACKEND_NOPERMISSION 2
|
||||
static int pg_signal_backend(ThreadId pid, int sig)
|
||||
static int pg_signal_backend(ThreadId pid, int sig, bool checkPermission)
|
||||
{
|
||||
PGPROC* proc = NULL;
|
||||
|
||||
if (!superuser()) {
|
||||
if (checkPermission && !superuser()) {
|
||||
/*
|
||||
* Since the user is not superuser, check for matching roles. Trust
|
||||
* that BackendPidGetProc will return NULL if the pid isn't valid,
|
||||
|
|
@ -202,7 +202,7 @@ Datum pg_cancel_backend(PG_FUNCTION_ARGS)
|
|||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion."))));
|
||||
|
||||
r = pg_signal_backend(tid, SIGINT);
|
||||
r = pg_signal_backend(tid, SIGINT, true);
|
||||
|
||||
if (r == SIGNAL_BACKEND_NOPERMISSION)
|
||||
ereport(ERROR,
|
||||
|
|
@ -243,7 +243,7 @@ Datum pg_cancel_invalid_query(PG_FUNCTION_ARGS)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int kill_backend(ThreadId tid)
|
||||
int kill_backend(ThreadId tid, bool checkPermission)
|
||||
{
|
||||
/*
|
||||
* It is forbidden to kill backend in the online expansion to protect
|
||||
|
|
@ -253,17 +253,17 @@ static int kill_backend(ThreadId tid)
|
|||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion."))));
|
||||
|
||||
int r = pg_signal_backend(tid, SIGTERM);
|
||||
int r = pg_signal_backend(tid, SIGTERM, checkPermission);
|
||||
if (r == SIGNAL_BACKEND_NOPERMISSION)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be system admin or have the same role to terminate other backend"))));
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (t_thrd.proc && t_thrd.proc->workingVersionNum >= 92060) {
|
||||
uint64 query_id = get_query_id_beentry(tid);
|
||||
(void)gs_close_all_stream_by_debug_id(query_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ static int kill_backend(ThreadId tid)
|
|||
Datum pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ThreadId tid = PG_GETARG_INT64(0);
|
||||
int r = kill_backend(tid);
|
||||
int r = kill_backend(tid, true);
|
||||
PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ Datum pg_terminate_session(PG_FUNCTION_ARGS)
|
|||
int r = -1;
|
||||
|
||||
if (tid == sid) {
|
||||
r = kill_backend(tid);
|
||||
r = kill_backend(tid, true);
|
||||
} else if (ENABLE_THREAD_POOL) {
|
||||
ThreadPoolSessControl *sess_ctrl = g_threadPoolControler->GetSessionCtrl();
|
||||
int ctrl_idx = sess_ctrl->FindCtrlIdxBySessId(sid);
|
||||
|
|
@ -952,7 +952,7 @@ void cancel_backend(ThreadId pid)
|
|||
{
|
||||
int sig_return = 0;
|
||||
|
||||
sig_return = pg_signal_backend(pid, SIGINT);
|
||||
sig_return = pg_signal_backend(pid, SIGINT, true);
|
||||
|
||||
if (sig_return == SIGNAL_BACKEND_NOPERMISSION) {
|
||||
ereport(ERROR,
|
||||
|
|
@ -961,3 +961,15 @@ void cancel_backend(ThreadId pid)
|
|||
errhint("fail to cancel backend process for privilege")));
|
||||
}
|
||||
}
|
||||
|
||||
Datum gs_clean_connection_by_memory(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int targetMemory = PG_GETARG_INT32(0);
|
||||
if (targetMemory < 0) {
|
||||
targetMemory = 0;
|
||||
}
|
||||
CleanConnectionByMemory(targetMemory);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7663,8 +7663,8 @@ Datum pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
|
||||
/* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */
|
||||
fctx->record =
|
||||
(BufferCachePagesRec*)palloc(sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
|
||||
fctx->record = (BufferCachePagesRec *)palloc_huge(CurrentMemoryContext,
|
||||
sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
|
||||
|
||||
/* Set max calls and remember the user function context. */
|
||||
funcctx->max_calls = g_instance.attr.attr_storage.NBuffers;
|
||||
|
|
@ -8836,10 +8836,11 @@ Datum gs_total_nodegroup_memory_detail(PG_FUNCTION_ARGS)
|
|||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
#define MEMORY_TYPES_CNT 24
|
||||
#define MEMORY_TYPES_CNT 25
|
||||
const char* MemoryTypeName[] = {"max_process_memory",
|
||||
"process_used_memory",
|
||||
"max_dynamic_memory",
|
||||
"min_dynamic_memory",
|
||||
"dynamic_used_memory",
|
||||
"dynamic_peak_memory",
|
||||
"dynamic_used_shrctx",
|
||||
|
|
@ -8933,63 +8934,67 @@ Datum pv_total_memory_detail(PG_FUNCTION_ARGS)
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
mem_size[0] = (int)(g_instance.attr.attr_memory.max_process_memory >> BITS_IN_KB);
|
||||
mem_size[1] = (int)res;
|
||||
mem_size[2] = mctx_max_size;
|
||||
mem_size[3] = mctx_used_size;
|
||||
if (MEMPROT_INIT_SIZE > mem_size[3])
|
||||
mem_size[3] = MEMPROT_INIT_SIZE;
|
||||
mem_size[4] = (int)(peakChunksPerProcess << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[5] = (int)(shareTrackedMemChunks << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[6] = (int)(peakChunksSharedContext << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[7] = (int)(backendReservedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[8] = (int)(backendUsedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
|
||||
if (mem_size[8] < 0) {
|
||||
mem_size[8] = 0;
|
||||
int index = -1;
|
||||
mem_size[++index] = (int)(g_instance.attr.attr_memory.max_process_memory >> BITS_IN_KB);
|
||||
mem_size[++index] = (int)res;
|
||||
mem_size[++index] = mctx_max_size;
|
||||
mem_size[++index] = (int)(u_sess->attr.attr_memory.min_dynamic_memory >> BITS_IN_KB);
|
||||
mem_size[++index] = mctx_used_size;
|
||||
if (MEMPROT_INIT_SIZE > mem_size[index])
|
||||
mem_size[index] = MEMPROT_INIT_SIZE;
|
||||
mem_size[++index] = (int)(peakChunksPerProcess << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[++index] = (int)(shareTrackedMemChunks << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[++index] = (int)(peakChunksSharedContext << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[++index] = (int)(backendReservedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
|
||||
mem_size[++index] = (int)(backendUsedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
|
||||
if (mem_size[index] < 0) {
|
||||
mem_size[index] = 0;
|
||||
}
|
||||
mem_size[9] = maxSharedMemory;
|
||||
mem_size[10] = shared;
|
||||
mem_size[11] = (int)(g_instance.attr.attr_storage.cstore_buffers >> BITS_IN_KB);
|
||||
mem_size[12] = cu_size;
|
||||
mem_size[++index] = maxSharedMemory;
|
||||
mem_size[++index] = shared;
|
||||
mem_size[++index] = (int)(g_instance.attr.attr_storage.cstore_buffers >> BITS_IN_KB);
|
||||
mem_size[++index] = cu_size;
|
||||
if (comm_size)
|
||||
mem_size[13] = comm_original_memory;
|
||||
mem_size[++index] = comm_original_memory;
|
||||
else
|
||||
mem_size[13] = 0;
|
||||
mem_size[14] = comm_size;
|
||||
mem_size[15] = comm_peak_size;
|
||||
mem_size[++index] = 0;
|
||||
mem_size[++index] = comm_size;
|
||||
mem_size[++index] = comm_peak_size;
|
||||
|
||||
/* other used memory */
|
||||
mem_size[++index] = (int)(res - shared - text) - mctx_used_size - cu_size;
|
||||
if (mem_size[index] < 0) // res may be changed
|
||||
mem_size[index] = 0;
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (is_searchserver_api_load()) {
|
||||
void* mem_info = get_searchlet_resource_info(&mem_size[18], &mem_size[19]);
|
||||
void* mem_info = get_searchlet_resource_info(&mem_size[index + 2], &mem_size[index + 3]);
|
||||
if (mem_info != NULL) {
|
||||
mem_size[17] = g_searchserver_memory;
|
||||
mem_size[index + 1] = g_searchserver_memory;
|
||||
pfree_ext(mem_info);
|
||||
}
|
||||
}
|
||||
#else
|
||||
mem_size[17] = 0;
|
||||
#endif
|
||||
|
||||
mem_size[16] = (int)(res - shared - text) - mctx_used_size - cu_size - mem_size[16];
|
||||
if (0 > mem_size[16]) // res may be changed
|
||||
mem_size[16] = 0;
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
index += 3;
|
||||
PoolConnStat conn_stat;
|
||||
pooler_get_connection_statinfo(&conn_stat);
|
||||
mem_size[20] = (int)(conn_stat.memory_size >> BITS_IN_MB);
|
||||
mem_size[21] = (int)(conn_stat.free_memory_size >> BITS_IN_MB);
|
||||
mem_size[++index] = (int)(conn_stat.memory_size >> BITS_IN_MB);
|
||||
mem_size[++index] = (int)(conn_stat.free_memory_size >> BITS_IN_MB);
|
||||
#else
|
||||
mem_size[20] = 0;
|
||||
mem_size[21] = 0;
|
||||
mem_size[++index] = 0;
|
||||
mem_size[++index] = 0;
|
||||
mem_size[++index] = 0;
|
||||
mem_size[++index] = 0;
|
||||
mem_size[++index] = 0;
|
||||
#endif
|
||||
mem_size[22] = (int)(storageTrackedBytes >> BITS_IN_MB);
|
||||
|
||||
mem_size[++index] = (int)(storageTrackedBytes >> BITS_IN_MB);
|
||||
|
||||
Assert(g_instance.attr.attr_sql.udf_memory_limit >= UDF_DEFAULT_MEMORY);
|
||||
mem_size[23] = (int)((g_instance.attr.attr_sql.udf_memory_limit - UDF_DEFAULT_MEMORY) >> BITS_IN_KB);
|
||||
mem_size[++index] = (int)((g_instance.attr.attr_sql.udf_memory_limit - UDF_DEFAULT_MEMORY) >> BITS_IN_KB);
|
||||
ereport(DEBUG2, (errmodule(MOD_LLVM), errmsg("LLVM IR file count is %ld, total memory is %ldKB",
|
||||
g_instance.codegen_IRload_process_count,
|
||||
g_instance.codegen_IRload_process_count * IR_FILE_SIZE / 1024)));
|
||||
Assert(index + 1 == MEMORY_TYPES_CNT);
|
||||
}
|
||||
|
||||
/* stuff done on every call of the function */
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static Datum regprocin_booststrap(char* procname)
|
|||
ScanKeyInit(&skey[0], Anum_pg_proc_proname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(procname));
|
||||
|
||||
hdesc = heap_open(ProcedureRelationId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
|
||||
result = (RegProcedure)HeapTupleGetOid(tuple);
|
||||
|
|
@ -416,7 +416,7 @@ Datum regoperin(PG_FUNCTION_ARGS)
|
|||
&skey[0], Anum_pg_operator_oprname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(opr_name_or_oid));
|
||||
|
||||
hdesc = heap_open(OperatorRelationId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
|
||||
result = HeapTupleGetOid(tuple);
|
||||
|
|
@ -730,7 +730,7 @@ Datum regclassin(PG_FUNCTION_ARGS)
|
|||
&skey[0], Anum_pg_class_relname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(class_name_or_oid));
|
||||
|
||||
hdesc = heap_open(RelationRelationId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, ClassNameNspIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, ClassNameNspIndexId, true, NULL, 1, skey);
|
||||
|
||||
if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
|
||||
result = HeapTupleGetOid(tuple);
|
||||
|
|
@ -877,7 +877,7 @@ Datum regtypein(PG_FUNCTION_ARGS)
|
|||
ScanKeyInit(&skey[0], Anum_pg_type_typname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(typ_name_or_oid));
|
||||
|
||||
hdesc = heap_open(TypeRelationId, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true, SnapshotNow, 1, skey);
|
||||
sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true, NULL, 1, skey);
|
||||
|
||||
if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
|
||||
result = HeapTupleGetOid(tuple);
|
||||
|
|
|
|||
|
|
@ -940,7 +940,7 @@ static void get_table_partitiondef(StringInfo query, StringInfo buf, Oid tableoi
|
|||
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind));
|
||||
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, SnapshotNow, 2, key);
|
||||
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, NULL, 2, key);
|
||||
while (HeapTupleIsValid((tuple = systable_getnext(scan)))) {
|
||||
int2vector* partVec = NULL;
|
||||
Datum datum = SysCacheGetAttr(PARTRELID, tuple, Anum_pg_partition_partkey, &isnull);
|
||||
|
|
@ -1208,7 +1208,7 @@ static int get_table_attribute(
|
|||
ScanKeyInit(
|
||||
&skey[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultIndexId, true, SnapshotNow, 1, skey);
|
||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(adscan))) {
|
||||
attrdef = (Form_pg_attrdef)GETSTRUCT(tup);
|
||||
|
|
@ -1252,7 +1252,7 @@ char* printDistributeKey(Oid relOid)
|
|||
ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid));
|
||||
|
||||
pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
|
||||
htup = systable_getnext(pcscan);
|
||||
|
||||
if (!HeapTupleIsValid(htup)) {
|
||||
|
|
@ -1551,7 +1551,7 @@ static void get_foreign_constraint_info(StringInfo buf, Oid tableoid, const char
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -1606,7 +1606,7 @@ static void get_index_list_info(Oid tableoid, StringInfo buf, const char* relnam
|
|||
ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
indrel = heap_open(IndexRelationId, AccessShareLock);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
|
||||
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
|
||||
|
|
@ -1899,7 +1899,7 @@ static void get_table_alter_info(
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -2187,7 +2187,7 @@ static char* pg_get_tabledef_worker(Oid tableoid)
|
|||
|
||||
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
|
||||
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
|
||||
|
|
@ -2319,7 +2319,7 @@ static char* pg_get_triggerdef_worker(Oid trigid, bool pretty)
|
|||
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigid));
|
||||
|
||||
tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true, SnapshotNow, 1, skey);
|
||||
tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true, NULL, 1, skey);
|
||||
|
||||
ht_trig = systable_getnext(tgscan);
|
||||
|
||||
|
|
@ -3441,7 +3441,7 @@ Datum pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
|||
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableOid));
|
||||
ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(attnum));
|
||||
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 3, key);
|
||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 3, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan))) {
|
||||
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
|
||||
|
|
@ -11136,7 +11136,7 @@ Datum getDistributeKey(PG_FUNCTION_ARGS)
|
|||
ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid));
|
||||
|
||||
pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey);
|
||||
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
|
||||
htup = systable_getnext(pcscan);
|
||||
|
||||
if (!HeapTupleIsValid(htup)) {
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
#include "utils/bytea.h"
|
||||
#include "utils/date.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/expr_distinct.h"
|
||||
#include "utils/extended_statistics.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
|
@ -193,7 +194,7 @@ static Const* string_to_bytea_const(const char* str, size_t str_len);
|
|||
static List* specialExpr_group_num(PlannerInfo* root, List* nodeList, double* numdistinct, double rows);
|
||||
static List* add_unique_group_var(
|
||||
PlannerInfo* root, List* varinfos, Node* var, VariableStatData* vardata, STATS_EST_TYPE eType = STATS_TYPE_LOCAL);
|
||||
static double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo);
|
||||
extern double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo);
|
||||
bool can_use_possion(VariableStatData* vardata, SpecialJoinInfo* sjinfo, double* ratio);
|
||||
extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
|
||||
extern List* find_skew_join_distribute_keys(Plan* plan);
|
||||
|
|
@ -2275,9 +2276,9 @@ static double eqjoinsel_inner(
|
|||
double relfrac1 = 1.0, relfrac2 = 1.0, relfrac;
|
||||
|
||||
nd1 = get_variable_numdistinct(
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
nd2 = get_variable_numdistinct(
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
opfuncoid = get_opcode(opera);
|
||||
|
||||
if (HeapTupleIsValid(vardata1->statsTuple)) {
|
||||
|
|
@ -2655,9 +2656,9 @@ static double eqjoinsel_semi(
|
|||
|
||||
Oid opfuncoid = OidIsValid(opera) ? get_opcode(opera) : InvalidOid;
|
||||
nd1 = get_variable_numdistinct(
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
nd2 = get_variable_numdistinct(
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
/*
|
||||
* We clamp nd2 to be not more than what we estimate the inner relation's
|
||||
* size to be. This is intuitively somewhat reasonable since obviously
|
||||
|
|
@ -2861,9 +2862,9 @@ static double neqjoinsel_semi(
|
|||
|
||||
nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
|
||||
nd1 = get_variable_numdistinct(
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
nd2 = get_variable_numdistinct(
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL);
|
||||
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
|
||||
|
||||
/*
|
||||
* When one of the sides contains zero distinct values, the selectivity is zero;
|
||||
|
|
@ -4550,6 +4551,8 @@ void examine_variable(PlannerInfo* root, Node* node, int varRelid, VariableStatD
|
|||
errno_t rc = memset_s(vardata, sizeof(VariableStatData), 0, sizeof(VariableStatData));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
vardata->root = root;
|
||||
|
||||
/* we enable possion to estimate distinct for default. */
|
||||
vardata->enablePossion = true;
|
||||
/* Save the exposed type of the expression */
|
||||
|
|
@ -4980,7 +4983,7 @@ statistic_proc_security_check(const VariableStatData *vardata, Oid func_oid)
|
|||
* compare the result to exact integer counts, or might divide by it.
|
||||
*/
|
||||
double get_variable_numdistinct(VariableStatData* vardata, bool* isdefault, bool adjust_rows, double join_ratio,
|
||||
SpecialJoinInfo* sjinfo, STATS_EST_TYPE eType)
|
||||
SpecialJoinInfo* sjinfo, STATS_EST_TYPE eType, bool isJoinVar)
|
||||
{
|
||||
double stadistinct;
|
||||
double stanullfrac = 0.0;
|
||||
|
|
@ -5067,6 +5070,19 @@ double get_variable_numdistinct(VariableStatData* vardata, bool* isdefault, bool
|
|||
if (vardata->isunique)
|
||||
stadistinct = -1.0 * (1.0 - stanullfrac);
|
||||
|
||||
/*
|
||||
* If no stats, try to get the estimation
|
||||
*/
|
||||
if (ENABLE_SQL_BETA_FEATURE(JOIN_SEL_WITH_CAST_FUNC) && !HeapTupleIsValid(vardata->statsTuple) &&
|
||||
stadistinct == 0.0) {
|
||||
stadistinct = GetExprNumDistinctRouter(vardata, adjust_rows, eType, isJoinVar);
|
||||
if (stadistinct > 0.0) {
|
||||
ereport(DEBUG2, (errmodule(MOD_OPT),
|
||||
errmsg("[Get Variable Distinct]: direct distinct is %.0lf by router, early return", stadistinct)));
|
||||
return clamp_row_est(stadistinct);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise we need to get the relation size; punt if not available.
|
||||
*/
|
||||
|
|
@ -6502,7 +6518,8 @@ static void genericcostestimate(PlannerInfo* root, IndexPath* path, double loop_
|
|||
* enough to not alter index-vs-seqscan decisions, but will prevent
|
||||
* indexes of different sizes from looking exactly equally attractive.
|
||||
*/
|
||||
*indexTotalCost += index->pages * spc_random_page_cost / 100000.0;
|
||||
if (ENABLE_SQL_BETA_FEATURE(INDEX_COST_WITH_LEAF_PAGES_ONLY))
|
||||
*indexTotalCost += index->pages * spc_random_page_cost / 100000.0;
|
||||
|
||||
/*
|
||||
* CPU cost: any complex expressions in the indexquals will need to be
|
||||
|
|
@ -8697,7 +8714,7 @@ void set_varratio_after_calc_selectivity(
|
|||
* Return:
|
||||
* minimum join ratio with specific relation
|
||||
*/
|
||||
static double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo)
|
||||
double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo)
|
||||
{
|
||||
double ratio = 1.0;
|
||||
ListCell* lc = NULL;
|
||||
|
|
|
|||
|
|
@ -1575,7 +1575,7 @@ static HeapTuple SearchCatCacheMiss(
|
|||
ereport(DEBUG1, (errmsg("cache->cc_reloid - %d", cache->cc_reloid)));
|
||||
|
||||
scandesc = systable_beginscan(
|
||||
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), SnapshotNow, nkeys, cur_skey);
|
||||
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), NULL, nkeys, cur_skey);
|
||||
|
||||
while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) {
|
||||
ct = CatalogCacheCreateEntry(cache, ntp, arguments, hashValue, hashIndex, false);
|
||||
|
|
@ -2452,7 +2452,7 @@ CatCList* SearchCatCacheList(CatCache* cache, int nkeys, Datum v1, Datum v2, Dat
|
|||
relation = heap_open(cache->cc_reloid, AccessShareLock);
|
||||
|
||||
scandesc = systable_beginscan(
|
||||
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), SnapshotNow, nkeys, cur_skey);
|
||||
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), NULL, nkeys, cur_skey);
|
||||
|
||||
/* The list will be ordered iff we are doing an index scan */
|
||||
ordered = (scandesc->irel != NULL);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@
|
|||
#include "catalog/pg_proc.h"
|
||||
#include "commands/prepare.h"
|
||||
#include "miscadmin.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "storage/sinval.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/inval.h"
|
||||
|
|
@ -561,7 +562,11 @@ void LocalExecuteInvalidationMessage(SharedInvalidationMessage* msg)
|
|||
|
||||
if (ENABLE_GPC) {
|
||||
bool check = GlobalPlanCache::MsgCheck(msg);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (check == true && u_sess->pcache_cxt.gpc_remote_msg == false) {
|
||||
#else
|
||||
if (check == true && (u_sess->pcache_cxt.gpc_remote_msg == false || pmState == PM_HOT_STANDBY)) {
|
||||
#endif
|
||||
u_sess->pcache_cxt.gpc_in_ddl = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3341,7 +3341,7 @@ static List* GetAllSliceTuples(Relation pgxcSliceRel, Oid tableOid)
|
|||
F_OIDEQ, ObjectIdGetDatum(tableOid));
|
||||
ScanKeyInit(&skey[1], Anum_pgxc_slice_type, BTEqualStrategyNumber,
|
||||
F_CHAREQ, CharGetDatum(PGXC_SLICE_TYPE_SLICE));
|
||||
sliceScan = systable_beginscan(pgxcSliceRel, PgxcSliceOrderIndexId, true, SnapshotNow, 2, skey);
|
||||
sliceScan = systable_beginscan(pgxcSliceRel, PgxcSliceOrderIndexId, true, NULL, 2, skey);
|
||||
while (HeapTupleIsValid((htup = systable_getnext(sliceScan)))) {
|
||||
dtup = heap_copytuple(htup);
|
||||
sliceList = lappend(sliceList, dtup);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,10 @@ static HeapTuple ScanPgPartition(Oid targetPartId, bool indexOK, Snapshot snapsh
|
|||
(errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("cannot read pg_class without having selected a database")));
|
||||
}
|
||||
|
||||
if (snapshot == NULL) {
|
||||
snapshot = GetCatalogSnapshot();
|
||||
}
|
||||
|
||||
/*
|
||||
* form a scan key
|
||||
*/
|
||||
|
|
@ -237,7 +241,7 @@ static Partition PartitionBuildDesc(Oid targetPartId, bool insertIt, bool isbukc
|
|||
/*
|
||||
* find the tuple in pg_class corresponding to the given relation id
|
||||
*/
|
||||
pg_partition_tuple = ScanPgPartition(targetPartId, true, SnapshotNow);
|
||||
pg_partition_tuple = ScanPgPartition(targetPartId, true, NULL);
|
||||
/*
|
||||
* if no such tuple exists, return NULL
|
||||
*/
|
||||
|
|
@ -378,7 +382,7 @@ Partition PartitionIdGetPartition(Oid partitionId, bool isbucket)
|
|||
|
||||
char* PartitionOidGetName(Oid partOid)
|
||||
{
|
||||
HeapTuple tuple = ScanPgPartition(partOid, true, SnapshotNow);
|
||||
HeapTuple tuple = ScanPgPartition(partOid, true, NULL);
|
||||
if (!HeapTupleIsValid(tuple)) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -394,7 +398,7 @@ char* PartitionOidGetName(Oid partOid)
|
|||
|
||||
Oid PartitionOidGetTablespace(Oid partOid)
|
||||
{
|
||||
HeapTuple tuple = ScanPgPartition(partOid, true, SnapshotNow);
|
||||
HeapTuple tuple = ScanPgPartition(partOid, true, NULL);
|
||||
if (!HeapTupleIsValid(tuple)) {
|
||||
return InvalidOid;
|
||||
}
|
||||
|
|
@ -1333,7 +1337,7 @@ static void PartitionReloadIndexInfo(Partition part)
|
|||
*/
|
||||
Assert(NULL == part->pd_smgr);
|
||||
|
||||
pg_partition_tuple = ScanPgPartition(PartitionGetPartid(part), true, SnapshotNow);
|
||||
pg_partition_tuple = ScanPgPartition(PartitionGetPartid(part), true, NULL);
|
||||
if (!HeapTupleIsValid(pg_partition_tuple)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NO_DATA),
|
||||
|
|
@ -1822,6 +1826,28 @@ bool PartitionInvisibleMetadataKeep(Datum datumRelOptions)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Check whether a partition is properly used. */
|
||||
bool PartitionParentOidIsLive(Datum parentDatum)
|
||||
{
|
||||
Oid parentid = InvalidOid;
|
||||
HeapTuple partTuple = NULL;
|
||||
|
||||
if (!PointerIsValid(parentDatum)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parentid = DatumGetObjectId(parentDatum);
|
||||
|
||||
/* Get table information from syscache */
|
||||
partTuple = SearchSysCache1WithLogLevel(RELOID, ObjectIdGetDatum(parentid), LOG);
|
||||
if (HeapTupleIsValid(partTuple)) {
|
||||
ReleaseSysCache(partTuple);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* In pg_partition, search all tuples (visible and invisible) containing wait_clean_gpi=y
|
||||
* in reloptios of one partitioed relation and set wait_clean_gpi=n
|
||||
|
|
@ -2008,7 +2034,7 @@ bool PartitionMetadataDisabledClean(Relation pgPartition)
|
|||
&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(PART_OBJ_TYPE_PARTED_TABLE));
|
||||
|
||||
partTupdesc = RelationGetDescr(pgPartition);
|
||||
scan = systable_beginscan(pgPartition, PartitionParentOidIndexId, true, SnapshotNow, 1, key);
|
||||
scan = systable_beginscan(pgPartition, PartitionParentOidIndexId, true, NULL, 1, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
bool isNull = false;
|
||||
Datum partOptions = fastgetattr(tuple, Anum_pg_partition_reloptions, partTupdesc, &isNull);
|
||||
|
|
|
|||
|
|
@ -103,8 +103,6 @@ static bool ChooseCustomPlan(CachedPlanSource* plansource, ParamListInfo boundPa
|
|||
static bool IsForceCustomplan(CachedPlanSource *plansource);
|
||||
static bool IsDeleteLimit(CachedPlanSource* plansource, ParamListInfo boundParams);
|
||||
static double cached_plan_cost(CachedPlan* plan);
|
||||
static void AcquireExecutorLocks(List* stmt_list, bool acquire);
|
||||
static void AcquirePlannerLocks(List* stmt_list, bool acquire);
|
||||
static void ScanQueryForLocks(Query* parsetree, bool acquire);
|
||||
static bool ScanQueryWalker(Node* node, bool* acquire);
|
||||
static TupleDesc PlanCacheComputeResultDesc(List* stmt_list);
|
||||
|
|
@ -139,6 +137,25 @@ void InitPlanCache(void)
|
|||
CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum)0);
|
||||
}
|
||||
|
||||
/* ddl no need to global it */
|
||||
static bool IsSupportGPCStmt(const Node* node)
|
||||
{
|
||||
bool isSupportGPC = false;
|
||||
switch (nodeTag(node)) {
|
||||
case T_InsertStmt:
|
||||
case T_DeleteStmt:
|
||||
case T_UpdateStmt:
|
||||
case T_MergeStmt:
|
||||
case T_SelectStmt:
|
||||
isSupportGPC = false;
|
||||
break;
|
||||
default:
|
||||
isSupportGPC = true;
|
||||
break;
|
||||
}
|
||||
return isSupportGPC;
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateCachedPlan: initially create a plan cache entry.
|
||||
*
|
||||
|
|
@ -174,15 +191,8 @@ CachedPlanSource* CreateCachedPlan(Node* raw_parse_tree, const char* query_strin
|
|||
MemoryContext oldcxt;
|
||||
|
||||
Assert(query_string != NULL); /* required as of 8.4 */
|
||||
bool enable_pbe_gpc = false;
|
||||
if (stmt_name != NULL && stmt_name[0] != '\0') {
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/* TransactionStmt do not support shared plan */
|
||||
enable_pbe_gpc = (ENABLE_CN_GPC && raw_parse_tree && !IsA(raw_parse_tree, TransactionStmt)) || ENABLE_DN_GPC;
|
||||
#else
|
||||
enable_pbe_gpc = ENABLE_GPC && raw_parse_tree && !IsA(raw_parse_tree, TransactionStmt);
|
||||
#endif
|
||||
}
|
||||
bool isSupportGPC = raw_parse_tree && IsSupportGPCStmt(raw_parse_tree);
|
||||
bool enable_pbe_gpc = ENABLE_GPC && stmt_name != NULL && stmt_name[0] != '\0' && !isSupportGPC;
|
||||
|
||||
if(!enable_pbe_gpc && !(ENABLE_CN_GPC && enable_spi_gpc)) {
|
||||
/*
|
||||
|
|
@ -710,10 +720,9 @@ List* RevalidateCachedQuery(CachedPlanSource* plansource, bool has_lp)
|
|||
Assert(plansource->is_valid);
|
||||
return NIL;
|
||||
}
|
||||
/* if is shared plan, we should acquire plan lock for this transaction */
|
||||
/* if is shared plan, we should acquire plan lock before check recreate plan */
|
||||
if (plansource->gpc.status.InShareTable()) {
|
||||
Assert(plansource->is_valid);
|
||||
AcquirePlannerLocks(plansource->query_list, true);
|
||||
return NIL;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1947,18 +1956,20 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
|
|||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot copy a one-shot cached plan")));
|
||||
|
||||
if (ENABLE_GPC && is_share == true) {
|
||||
source_context = AllocSetContextCreate(GLOBAL_PLANCACHE_MEMCONTEXT,
|
||||
"GPCCachedPlanSource",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE,
|
||||
SHARED_CONTEXT);
|
||||
source_context = AllocSetContextCreate(GLOBAL_PLANCACHE_MEMCONTEXT,
|
||||
"GPCCachedPlanSource",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE,
|
||||
SHARED_CONTEXT);
|
||||
ResourceOwnerEnlargeGMemContext(t_thrd.utils_cxt.TopTransactionResourceOwner);
|
||||
ResourceOwnerRememberGMemContext(t_thrd.utils_cxt.TopTransactionResourceOwner, source_context);
|
||||
} else {
|
||||
source_context = AllocSetContextCreate(u_sess->cache_mem_cxt,
|
||||
"CachedPlanSource",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
source_context = AllocSetContextCreate(u_sess->cache_mem_cxt,
|
||||
"CachedPlanSource",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1992,19 +2003,19 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
|
|||
newsource->context = source_context;
|
||||
|
||||
if (ENABLE_GPC && is_share == true) {
|
||||
querytree_context = AllocSetContextCreate(source_context,
|
||||
"GPCCachedPlanQuery",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE,
|
||||
SHARED_CONTEXT);
|
||||
querytree_context = AllocSetContextCreate(source_context,
|
||||
"GPCCachedPlanQuery",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE,
|
||||
SHARED_CONTEXT);
|
||||
}
|
||||
else {
|
||||
querytree_context = AllocSetContextCreate(source_context,
|
||||
"CachedPlanQuery",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
querytree_context = AllocSetContextCreate(source_context,
|
||||
"CachedPlanQuery",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
}
|
||||
MemoryContextSwitchTo(querytree_context);
|
||||
newsource->query_list = (List*)copyObject(plansource->query_list);
|
||||
|
|
@ -2030,6 +2041,7 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
|
|||
newsource->opFusionObj = NULL;
|
||||
newsource->is_checked_opfusion = false;
|
||||
newsource->spi_signature = plansource->spi_signature;
|
||||
newsource->gplan_is_fqs = plansource->gplan_is_fqs;
|
||||
|
||||
#ifdef ENABLE_MOT
|
||||
newsource->storageEngineType = SE_TYPE_UNSPECIFIED;
|
||||
|
|
@ -2101,7 +2113,7 @@ List* CachedPlanGetTargetList(CachedPlanSource* plansource)
|
|||
* AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
|
||||
* or release them if acquire is false.
|
||||
*/
|
||||
static void AcquireExecutorLocks(List* stmt_list, bool acquire)
|
||||
void AcquireExecutorLocks(List* stmt_list, bool acquire)
|
||||
{
|
||||
ListCell* lc1 = NULL;
|
||||
|
||||
|
|
@ -2167,7 +2179,7 @@ static void AcquireExecutorLocks(List* stmt_list, bool acquire)
|
|||
* fail if one has been dropped entirely --- we'll just transiently acquire
|
||||
* a non-conflicting lock.
|
||||
*/
|
||||
static void AcquirePlannerLocks(List* stmt_list, bool acquire)
|
||||
void AcquirePlannerLocks(List* stmt_list, bool acquire)
|
||||
{
|
||||
ListCell* lc = NULL;
|
||||
|
||||
|
|
@ -2660,12 +2672,13 @@ void DropCachedPlanInternal(CachedPlanSource* plansource)
|
|||
}
|
||||
plansource->lightProxyObj = NULL;
|
||||
} else {
|
||||
if (plansource->opFusionObj != NULL) {
|
||||
if (!plansource->gpc.status.InShareTable() && plansource->opFusionObj != NULL) {
|
||||
OpFusion *opfusion = (OpFusion *)plansource->opFusionObj;
|
||||
if (opfusion->m_portalName == NULL || OpFusion::locateFusion(opfusion->m_portalName) == NULL) {
|
||||
if (opfusion->m_local.m_portalName == NULL ||
|
||||
OpFusion::locateFusion(opfusion->m_local.m_portalName) == NULL) {
|
||||
OpFusion::tearDown(opfusion);
|
||||
} else {
|
||||
opfusion->m_psrc = NULL;
|
||||
opfusion->m_global->m_psrc = NULL;
|
||||
}
|
||||
plansource->opFusionObj = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1205,11 +1205,14 @@ HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
|
|||
pg_class_desc = heap_open(RelationRelationId, AccessShareLock);
|
||||
|
||||
/*
|
||||
* for logical decoding
|
||||
* The caller might need a tuple that's newer than the one the historic
|
||||
* snapshot; currently the only case requiring to do so is looking up the
|
||||
* relfilenode of non mapped system relations during decoding.
|
||||
*/
|
||||
snapshot = SnapshotNow;
|
||||
if (HistoricSnapshotActive())
|
||||
snapshot = GetCatalogSnapshot(RelationRelationId);
|
||||
if (HistoricSnapshotActive() && !force_non_historic) {
|
||||
snapshot = GetCatalogSnapshot();
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller might need a tuple that's newer than the one the historic
|
||||
|
|
@ -1389,6 +1392,15 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
|
|||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
ScanKeyInit(&skey[1], Anum_pg_attribute_attnum, BTGreaterStrategyNumber, F_INT2GT, Int16GetDatum(0));
|
||||
|
||||
/*
|
||||
* Using historical snapshot in logic decoding.
|
||||
*/
|
||||
Snapshot snapshot = NULL;
|
||||
snapshot = SnapshotNow;
|
||||
if (HistoricSnapshotActive()) {
|
||||
snapshot = GetCatalogSnapshot();
|
||||
}
|
||||
|
||||
/*
|
||||
* Open pg_attribute and begin a scan. Force heap scan if we haven't yet
|
||||
* built the critical relcache entries (this includes initdb and startup
|
||||
|
|
@ -1396,7 +1408,7 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
|
|||
*/
|
||||
pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock);
|
||||
pg_attribute_scan = systable_beginscan(
|
||||
pg_attribute_desc, AttributeRelidNumIndexId, u_sess->relcache_cxt.criticalRelcachesBuilt, SnapshotNow, 2, skey);
|
||||
pg_attribute_desc, AttributeRelidNumIndexId, u_sess->relcache_cxt.criticalRelcachesBuilt, snapshot, 2, skey);
|
||||
|
||||
/*
|
||||
* add attribute data to relation->rd_att
|
||||
|
|
@ -1651,7 +1663,7 @@ static void RelationBuildRuleLock(Relation relation)
|
|||
*/
|
||||
rewrite_desc = heap_open(RewriteRelationId, AccessShareLock);
|
||||
rewrite_tupdesc = RelationGetDescr(rewrite_desc);
|
||||
rewrite_scan = systable_beginscan(rewrite_desc, RewriteRelRulenameIndexId, true, SnapshotNow, 1, &key);
|
||||
rewrite_scan = systable_beginscan(rewrite_desc, RewriteRelRulenameIndexId, true, NULL, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan))) {
|
||||
Form_pg_rewrite rewrite_form = (Form_pg_rewrite)GETSTRUCT(rewrite_tuple);
|
||||
|
|
@ -2619,7 +2631,7 @@ static OpClassCacheEnt* LookupOpclassInfo(Oid operatorClassOid, StrategyNumber n
|
|||
*/
|
||||
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(operatorClassOid));
|
||||
rel = heap_open(OperatorClassRelationId, AccessShareLock);
|
||||
scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, SnapshotNow, 1, skey);
|
||||
scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, NULL, 1, skey);
|
||||
|
||||
if (HeapTupleIsValid(htup = systable_getnext(scan))) {
|
||||
Form_pg_opclass opclassform = (Form_pg_opclass)GETSTRUCT(htup);
|
||||
|
|
@ -2655,7 +2667,7 @@ static OpClassCacheEnt* LookupOpclassInfo(Oid operatorClassOid, StrategyNumber n
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(opcentry->opcintype));
|
||||
rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock);
|
||||
scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, SnapshotNow, 3, skey);
|
||||
scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, NULL, 3, skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(scan))) {
|
||||
Form_pg_amproc amprocform = (Form_pg_amproc)GETSTRUCT(htup);
|
||||
|
|
@ -5022,7 +5034,7 @@ static void AttrDefaultFetch(Relation relation)
|
|||
&skey, Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
adrel = heap_open(AttrDefaultRelationId, AccessShareLock);
|
||||
adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, SnapshotNow, 1, &skey);
|
||||
adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 1, &skey);
|
||||
found = 0;
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(adscan))) {
|
||||
|
|
@ -5087,7 +5099,7 @@ static void CheckConstraintFetch(Relation relation)
|
|||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
conrel = heap_open(ConstraintRelationId, AccessShareLock);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
|
||||
Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup);
|
||||
|
|
@ -5251,7 +5263,7 @@ List* RelationGetIndexList(Relation relation)
|
|||
&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
indrel = heap_open(IndexRelationId, AccessShareLock);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
|
||||
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
|
||||
|
|
@ -5413,7 +5425,7 @@ int RelationGetIndexNum(Relation relation)
|
|||
&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
indrel = heap_open(IndexRelationId, AccessShareLock);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey);
|
||||
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
|
||||
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
|
||||
|
|
@ -5776,7 +5788,7 @@ static void ClusterConstraintFetch(__inout Relation relation)
|
|||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
conrel = heap_open(ConstraintRelationId, AccessShareLock);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
|
||||
Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup);
|
||||
|
|
@ -6012,7 +6024,7 @@ void RelationGetExclusionInfo(Relation indexRelation, Oid** operators, Oid** pro
|
|||
ObjectIdGetDatum(indexRelation->rd_index->indrelid));
|
||||
|
||||
conrel = heap_open(ConstraintRelationId, AccessShareLock);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey);
|
||||
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
|
||||
found = false;
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
|
||||
|
|
@ -6936,7 +6948,7 @@ List* PartitionGetPartIndexList(Partition part)
|
|||
ObjectIdGetDatum(PartitionGetPartid(part)));
|
||||
|
||||
partrel = heap_open(PartitionRelationId, AccessShareLock);
|
||||
indscan = systable_beginscan(partrel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, &skey);
|
||||
indscan = systable_beginscan(partrel, PartitionIndexTableIdIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(parttup = systable_getnext(indscan))) {
|
||||
Form_pg_partition partform = (Form_pg_partition)GETSTRUCT(parttup);
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@
|
|||
#include "utils/relmapper.h"
|
||||
#include "utils/snapmgr.h"
|
||||
|
||||
/* built first time through in InitializeRelfilenodeMap */
|
||||
ScanKeyData relfilenode_skey[2];
|
||||
static const int PARTITION_HASH_ELEM_SIZE = 4096;
|
||||
|
||||
typedef struct {
|
||||
Oid reltablespace;
|
||||
|
|
@ -47,6 +46,17 @@ typedef struct {
|
|||
Oid relid; /* pg_class.oid */
|
||||
} RelfilenodeMapEntry;
|
||||
|
||||
typedef struct {
|
||||
Oid reltablespace;
|
||||
Oid relfilenode;
|
||||
} PartfilenodeMapKey;
|
||||
|
||||
typedef struct {
|
||||
PartfilenodeMapKey key; /* lookup key - must be first */
|
||||
Oid relid; /* pg_partition.oid */
|
||||
Oid reltoastrelid; /* pg_partition.reltoastrelid */
|
||||
} PartfilenodeMapEntry;
|
||||
|
||||
/*
|
||||
* RelfilenodeMapInvalidateCallback
|
||||
* Flush mapping entries when pg_class is updated in a relevant fashion.
|
||||
|
|
@ -75,30 +85,56 @@ static void RelfilenodeMapInvalidateCallback(Datum arg, Oid relid)
|
|||
}
|
||||
}
|
||||
|
||||
static void PartfilenodeMapInvalidateCallback(Datum arg, Oid relid)
|
||||
{
|
||||
HASH_SEQ_STATUS status;
|
||||
PartfilenodeMapEntry* entry = NULL;
|
||||
/* callback only gets registered after creating the hash */
|
||||
Assert(u_sess->relmap_cxt.PartfilenodeMapHash != NULL);
|
||||
|
||||
hash_seq_init(&status, u_sess->relmap_cxt.PartfilenodeMapHash);
|
||||
while ((entry = (PartfilenodeMapEntry*)hash_seq_search(&status)) != NULL) {
|
||||
/*
|
||||
* If relid is InvalidOid, signalling a complete reset, we must remove
|
||||
* all entries, otherwise just remove the specific relation's entry.
|
||||
* Always remove negative cache entries.
|
||||
*/
|
||||
if (relid == InvalidOid || /* complete reset */
|
||||
entry->relid == InvalidOid || /* negative cache entry */
|
||||
entry->relid == relid) { /* individual flushed relation */
|
||||
if (hash_search(u_sess->relmap_cxt.PartfilenodeMapHash,
|
||||
(void *) &entry->key, HASH_REMOVE, NULL) == NULL) {
|
||||
ereport(ERROR, (errcode(ERRCODE_RELFILENODEMAP), errmsg("hash table corrupted")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RelfilenodeMapInvalidateCallback
|
||||
* Initialize cache, either on first use or after a reset.
|
||||
*/
|
||||
static void InitializeRelfilenodeMap(void)
|
||||
static void InitializeRelfilenodeMap()
|
||||
{
|
||||
HASHCTL ctl;
|
||||
int i;
|
||||
|
||||
/* build skey */
|
||||
errno_t ret = memset_s(&relfilenode_skey, sizeof(relfilenode_skey), 0, sizeof(relfilenode_skey));
|
||||
errno_t ret = memset_s(&u_sess->relmap_cxt.relfilenodeSkey, sizeof(u_sess->relmap_cxt.relfilenodeSkey), 0,
|
||||
sizeof(u_sess->relmap_cxt.relfilenodeSkey));
|
||||
securec_check(ret, "\0", "\0");
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
fmgr_info_cxt(F_OIDEQ, &relfilenode_skey[i].sk_func, u_sess->cache_mem_cxt);
|
||||
relfilenode_skey[i].sk_strategy = BTEqualStrategyNumber;
|
||||
relfilenode_skey[i].sk_subtype = InvalidOid;
|
||||
relfilenode_skey[i].sk_collation = InvalidOid;
|
||||
fmgr_info_cxt(F_OIDEQ, &u_sess->relmap_cxt.relfilenodeSkey[i].sk_func, u_sess->cache_mem_cxt);
|
||||
u_sess->relmap_cxt.relfilenodeSkey[i].sk_strategy = BTEqualStrategyNumber;
|
||||
u_sess->relmap_cxt.relfilenodeSkey[i].sk_subtype = InvalidOid;
|
||||
u_sess->relmap_cxt.relfilenodeSkey[i].sk_collation = InvalidOid;
|
||||
}
|
||||
|
||||
relfilenode_skey[0].sk_attno = Anum_pg_class_reltablespace;
|
||||
relfilenode_skey[1].sk_attno = Anum_pg_class_relfilenode;
|
||||
u_sess->relmap_cxt.relfilenodeSkey[0].sk_attno = Anum_pg_class_reltablespace;
|
||||
u_sess->relmap_cxt.relfilenodeSkey[1].sk_attno = Anum_pg_class_relfilenode;
|
||||
|
||||
/* Initialize the hash table. */
|
||||
HASHCTL ctl;
|
||||
ret = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl));
|
||||
securec_check(ret, "\0", "\0");
|
||||
ctl.keysize = sizeof(RelfilenodeMapKey);
|
||||
|
|
@ -118,6 +154,73 @@ static void InitializeRelfilenodeMap(void)
|
|||
CacheRegisterRelcacheCallback(RelfilenodeMapInvalidateCallback, (Datum)0);
|
||||
}
|
||||
|
||||
static void InitializePartfilenodeMap()
|
||||
{
|
||||
HASHCTL ctl;
|
||||
int i;
|
||||
|
||||
/* build skey */
|
||||
errno_t ret = memset_s(&u_sess->relmap_cxt.partfilenodeSkey,
|
||||
sizeof(u_sess->relmap_cxt.partfilenodeSkey), 0, sizeof(u_sess->relmap_cxt.partfilenodeSkey));
|
||||
securec_check(ret, "\0", "\0");
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
fmgr_info_cxt(F_OIDEQ, &u_sess->relmap_cxt.partfilenodeSkey[i].sk_func, u_sess->cache_mem_cxt);
|
||||
u_sess->relmap_cxt.partfilenodeSkey[i].sk_strategy = BTEqualStrategyNumber;
|
||||
u_sess->relmap_cxt.partfilenodeSkey[i].sk_subtype = InvalidOid;
|
||||
u_sess->relmap_cxt.partfilenodeSkey[i].sk_collation = InvalidOid;
|
||||
}
|
||||
|
||||
u_sess->relmap_cxt.partfilenodeSkey[0].sk_attno = Anum_pg_partition_reltablespace;
|
||||
u_sess->relmap_cxt.partfilenodeSkey[1].sk_attno = Anum_pg_partition_relfilenode;
|
||||
|
||||
/* Initialize the hash table. */
|
||||
ret = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl));
|
||||
securec_check(ret, "\0", "\0");
|
||||
ctl.keysize = sizeof(PartfilenodeMapKey);
|
||||
ctl.entrysize = sizeof(PartfilenodeMapEntry);
|
||||
ctl.hash = tag_hash;
|
||||
ctl.hcxt = u_sess->cache_mem_cxt;
|
||||
|
||||
/*
|
||||
* Only create the relmap_cxt->PartfilenodeMapHash now, so we don't end up partially
|
||||
* initialized when fmgr_info_cxt() above ERRORs out with an out of memory
|
||||
* error.
|
||||
*/
|
||||
u_sess->relmap_cxt.PartfilenodeMapHash = hash_create("PartfilenodeMap cache",
|
||||
PARTITION_HASH_ELEM_SIZE, &ctl, HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
|
||||
|
||||
/* Watch for invalidation events. */
|
||||
CacheRegisterRelcacheCallback(PartfilenodeMapInvalidateCallback, (Datum)0);
|
||||
}
|
||||
|
||||
Oid RelidByRelfilenodeCache(Oid reltablespace, Oid relfilenode)
|
||||
{
|
||||
RelfilenodeMapKey key;
|
||||
bool found = true;
|
||||
if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL) {
|
||||
InitializeRelfilenodeMap();
|
||||
}
|
||||
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
|
||||
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) {
|
||||
reltablespace = 0;
|
||||
}
|
||||
|
||||
errno_t ret = memset_s(&key, sizeof(key), 0, sizeof(key));
|
||||
securec_check(ret, "\0", "\0");
|
||||
|
||||
key.reltablespace = reltablespace;
|
||||
key.relfilenode = relfilenode;
|
||||
|
||||
RelfilenodeMapEntry* entry =
|
||||
(RelfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.RelfilenodeMapHash, (void*)&key, HASH_FIND, &found);
|
||||
|
||||
if (found) {
|
||||
return entry->relid;
|
||||
}
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a relation's (tablespace, filenode) to a relation's oid and cache the
|
||||
* result.
|
||||
|
|
@ -135,8 +238,9 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
|
|||
ScanKeyData skey[2];
|
||||
Oid relid;
|
||||
int rc = 0;
|
||||
if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL)
|
||||
if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL) {
|
||||
InitializeRelfilenodeMap();
|
||||
}
|
||||
|
||||
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
|
||||
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace)
|
||||
|
|
@ -148,22 +252,6 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
|
|||
key.reltablespace = reltablespace;
|
||||
key.relfilenode = relfilenode;
|
||||
|
||||
/*
|
||||
* Check cache and enter entry if nothing could be found. Even if no target
|
||||
* Check cache and return entry if one is found. Even if no target
|
||||
* relation can be found later on we store the negative match and return a
|
||||
* InvalidOid from cache. That's not really necessary for performance since
|
||||
* querying invalid values isn't supposed to be a frequent thing, but the
|
||||
* implementation is simpler this way.
|
||||
* InvalidOid from cache. That's not really necessary for performance
|
||||
* since querying invalid values isn't supposed to be a frequent thing,
|
||||
* but it's basically free.
|
||||
*/
|
||||
entry = (RelfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.RelfilenodeMapHash, (void*)&key, HASH_FIND, &found);
|
||||
|
||||
if (found)
|
||||
return entry->relid;
|
||||
|
||||
/* ok, no previous cache entry, do it the hard way */
|
||||
|
||||
/* initialize empty/negative cache entry before doing the actual lookups */
|
||||
|
|
@ -185,14 +273,17 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
|
|||
relation = heap_open(RelationRelationId, AccessShareLock);
|
||||
|
||||
/* copy scankey to local copy, it will be modified during the scan */
|
||||
rc = memcpy_s(skey, sizeof(skey), relfilenode_skey, sizeof(skey));
|
||||
rc = memcpy_s(skey, sizeof(skey), u_sess->relmap_cxt.relfilenodeSkey, sizeof(skey));
|
||||
securec_check(rc, "", "");
|
||||
|
||||
/* set scan arguments */
|
||||
skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
|
||||
skey[1].sk_argument = ObjectIdGetDatum(relfilenode);
|
||||
|
||||
scandesc = systable_beginscan(relation, ClassTblspcRelfilenodeIndexId, true, SnapshotNow, 2, skey);
|
||||
/*
|
||||
* Using historical snapshot in logic decoding.
|
||||
*/
|
||||
scandesc = systable_beginscan(relation, ClassTblspcRelfilenodeIndexId, true, NULL, 2, skey);
|
||||
|
||||
found = false;
|
||||
|
||||
|
|
@ -240,6 +331,39 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
|
|||
|
||||
return relid;
|
||||
}
|
||||
|
||||
Oid PartitionRelidByRelfilenodeCache(Oid reltablespace, Oid relfilenode, Oid &partationReltoastrelid)
|
||||
{
|
||||
PartfilenodeMapKey key;
|
||||
PartfilenodeMapEntry* entry = NULL;
|
||||
bool found = false;
|
||||
if (u_sess->relmap_cxt.PartfilenodeMapHash == NULL) {
|
||||
InitializePartfilenodeMap();
|
||||
}
|
||||
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
|
||||
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) {
|
||||
reltablespace = 0;
|
||||
}
|
||||
|
||||
key.reltablespace = reltablespace;
|
||||
key.relfilenode = relfilenode;
|
||||
|
||||
/*
|
||||
* Check cache and return entry if one is found. Even if no target
|
||||
* relation can be found later on we store the negative match and return a
|
||||
* InvalidOid from cache. That's not really necessary for performance since
|
||||
* querying invalid values isn't supposed to be a frequent thing, but the
|
||||
* implementation is simpler this way.
|
||||
*/
|
||||
entry = (PartfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.PartfilenodeMapHash, (void*)&key, HASH_FIND, &found);
|
||||
|
||||
if (found) {
|
||||
partationReltoastrelid = entry->reltoastrelid;
|
||||
return entry->relid;
|
||||
}
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a partation-relation's (tablespace, filenode) to it's parent relation's oid and
|
||||
* save partation-relation's Reltoastrelid to partationReltoastrelid.
|
||||
|
|
@ -247,38 +371,49 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
|
|||
*/
|
||||
Oid PartitionRelidByRelfilenode(Oid reltablespace, Oid relfilenode, Oid& partationReltoastrelid)
|
||||
{
|
||||
bool foundflag = false;
|
||||
PartfilenodeMapKey key;
|
||||
PartfilenodeMapEntry* entry = NULL;
|
||||
bool found = false;
|
||||
SysScanDesc scandesc;
|
||||
Relation relation;
|
||||
HeapTuple ntp;
|
||||
ScanKeyData skey[2];
|
||||
Oid relid = InvalidOid;
|
||||
int rc = 0;
|
||||
if (u_sess->relmap_cxt.PartfilenodeMapHash == NULL) {
|
||||
InitializePartfilenodeMap();
|
||||
}
|
||||
|
||||
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
|
||||
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace)
|
||||
reltablespace = 0;
|
||||
|
||||
key.reltablespace = reltablespace;
|
||||
key.relfilenode = relfilenode;
|
||||
|
||||
/* initialize empty/negative cache entry before doing the actual lookups */
|
||||
relid = InvalidOid;
|
||||
|
||||
/* For partition table in MPPDB, the relfilenode is in pg_partition instead of pg_class,
|
||||
* so here we scan the pg_partition again to get the parent's oid. */
|
||||
/* check plain relations by looking in pg_class */
|
||||
relation = heap_open(PartitionRelationId, AccessShareLock);
|
||||
|
||||
rc = memcpy_s(skey, sizeof(skey), relfilenode_skey, sizeof(skey));
|
||||
rc = memcpy_s(skey, sizeof(skey), u_sess->relmap_cxt.partfilenodeSkey, sizeof(skey));
|
||||
securec_check(rc, "", "");
|
||||
skey[0].sk_attno = Anum_pg_partition_reltablespace;
|
||||
skey[1].sk_attno = Anum_pg_partition_relfilenode;
|
||||
/* set scan arguments */
|
||||
skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
|
||||
skey[1].sk_argument = ObjectIdGetDatum(relfilenode);
|
||||
|
||||
scandesc = systable_beginscan(relation, InvalidOid, false, SnapshotNow, 2, skey);
|
||||
scandesc = systable_beginscan(relation, InvalidOid, false, NULL, 2, skey);
|
||||
|
||||
found = false;
|
||||
while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) {
|
||||
if (foundflag)
|
||||
if (found)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_RELFILENODEMAP),
|
||||
errmsg("unexpected duplicate for tablespace %u, relfilenode %u", reltablespace, relfilenode)));
|
||||
foundflag = true;
|
||||
found = true;
|
||||
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
if (assert_enabled) {
|
||||
|
|
@ -299,5 +434,35 @@ Oid PartitionRelidByRelfilenode(Oid reltablespace, Oid relfilenode, Oid& partati
|
|||
systable_endscan(scandesc);
|
||||
heap_close(relation, AccessShareLock);
|
||||
|
||||
/*
|
||||
* Only enter entry into cache now, our opening of pg_partition could have
|
||||
* caused cache invalidations to be executed which would have deleted a
|
||||
* new entry if we had entered it above.
|
||||
*/
|
||||
if (relid != InvalidOid) {
|
||||
entry =
|
||||
(PartfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.PartfilenodeMapHash, (void*)&key, HASH_ENTER, &found);
|
||||
entry->relid = relid;
|
||||
entry->reltoastrelid = partationReltoastrelid;
|
||||
}
|
||||
return relid;
|
||||
}
|
||||
|
||||
Oid HeapGetRelid(Oid reltablespace, Oid relfilenode, Oid &partationReltoastrelid)
|
||||
{
|
||||
Oid reloid = InvalidOid;
|
||||
reloid = RelidByRelfilenodeCache(reltablespace, relfilenode);
|
||||
if (reloid == InvalidOid) {
|
||||
reloid = PartitionRelidByRelfilenodeCache(reltablespace, relfilenode, partationReltoastrelid);
|
||||
}
|
||||
|
||||
if (reloid == InvalidOid) {
|
||||
reloid = RelidByRelfilenode(reltablespace, relfilenode);
|
||||
}
|
||||
|
||||
if (reloid == InvalidOid) {
|
||||
reloid = PartitionRelidByRelfilenode(reltablespace, relfilenode, partationReltoastrelid);
|
||||
}
|
||||
return reloid;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue