Skip to content

Commit 4a12787

Browse files
committed
dirty PoC
1 parent f11c557 commit 4a12787

File tree

1 file changed

+146
-129
lines changed

1 file changed

+146
-129
lines changed

src/backend/access/transam/twophase.c

Lines changed: 146 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,19 @@ static void ProcessRecords(char *bufptr, TransactionId xid,
167167
static void RemoveGXact(GlobalTransaction gxact);
168168

169169

170+
171+
static char twophase_buf[10*1024];
172+
static int twophase_pos = 0;
173+
size_t
174+
bogus_write(int fd, char *buf, size_t nbytes)
175+
{
176+
memcpy(twophase_buf + twophase_pos, buf, nbytes);
177+
twophase_pos += nbytes;
178+
return nbytes;
179+
}
180+
181+
182+
170183
/*
171184
* Initialization of shared memory
172185
*/
@@ -1050,11 +1063,13 @@ EndPrepare(GlobalTransaction gxact)
10501063
/*
10511064
* Create the 2PC state file.
10521065
*/
1053-
TwoPhaseFilePath(path, xid);
1066+
// TwoPhaseFilePath(path, xid);
1067+
1068+
// fd = OpenTransientFile(path,
1069+
// O_CREAT | O_EXCL | O_WRONLY | PG_BINARY,
1070+
// S_IRUSR | S_IWUSR);
1071+
fd = 1;
10541072

1055-
fd = OpenTransientFile(path,
1056-
O_CREAT | O_EXCL | O_WRONLY | PG_BINARY,
1057-
S_IRUSR | S_IWUSR);
10581073
if (fd < 0)
10591074
ereport(ERROR,
10601075
(errcode_for_file_access(),
@@ -1067,7 +1082,7 @@ EndPrepare(GlobalTransaction gxact)
10671082
for (record = records.head; record != NULL; record = record->next)
10681083
{
10691084
COMP_CRC32C(statefile_crc, record->data, record->len);
1070-
if ((write(fd, record->data, record->len)) != record->len)
1085+
if ((bogus_write(fd, record->data, record->len)) != record->len)
10711086
{
10721087
CloseTransientFile(fd);
10731088
ereport(ERROR,
@@ -1078,28 +1093,28 @@ EndPrepare(GlobalTransaction gxact)
10781093

10791094
FIN_CRC32C(statefile_crc);
10801095

1081-
/*
1082-
* Write a deliberately bogus CRC to the state file; this is just paranoia
1083-
* to catch the case where four more bytes will run us out of disk space.
1084-
*/
1085-
bogus_crc = ~statefile_crc;
1086-
1087-
if ((write(fd, &bogus_crc, sizeof(pg_crc32c))) != sizeof(pg_crc32c))
1088-
{
1089-
CloseTransientFile(fd);
1090-
ereport(ERROR,
1091-
(errcode_for_file_access(),
1092-
errmsg("could not write two-phase state file: %m")));
1093-
}
1094-
1095-
/* Back up to prepare for rewriting the CRC */
1096-
if (lseek(fd, -((off_t) sizeof(pg_crc32c)), SEEK_CUR) < 0)
1097-
{
1098-
CloseTransientFile(fd);
1099-
ereport(ERROR,
1100-
(errcode_for_file_access(),
1101-
errmsg("could not seek in two-phase state file: %m")));
1102-
}
1096+
// /*
1097+
// * Write a deliberately bogus CRC to the state file; this is just paranoia
1098+
// * to catch the case where four more bytes will run us out of disk space.
1099+
// */
1100+
// bogus_crc = ~statefile_crc;
1101+
1102+
// if ((bogus_write(fd, &bogus_crc, sizeof(pg_crc32c))) != sizeof(pg_crc32c))
1103+
// {
1104+
// CloseTransientFile(fd);
1105+
// ereport(ERROR,
1106+
// (errcode_for_file_access(),
1107+
// errmsg("could not write two-phase state file: %m")));
1108+
// }
1109+
1110+
// /* Back up to prepare for rewriting the CRC */
1111+
// if (lseek(fd, -((off_t) sizeof(pg_crc32c)), SEEK_CUR) < 0)
1112+
// {
1113+
// CloseTransientFile(fd);
1114+
// ereport(ERROR,
1115+
// (errcode_for_file_access(),
1116+
// errmsg("could not seek in two-phase state file: %m")));
1117+
// }
11031118

11041119
/*
11051120
* The state file isn't valid yet, because we haven't written the correct
@@ -1137,18 +1152,18 @@ EndPrepare(GlobalTransaction gxact)
11371152
/* If we crash now, we have prepared: WAL replay will fix things */
11381153

11391154
/* write correct CRC and close file */
1140-
if ((write(fd, &statefile_crc, sizeof(pg_crc32c))) != sizeof(pg_crc32c))
1155+
if ((bogus_write(fd, &statefile_crc, sizeof(pg_crc32c))) != sizeof(pg_crc32c))
11411156
{
11421157
CloseTransientFile(fd);
11431158
ereport(ERROR,
11441159
(errcode_for_file_access(),
11451160
errmsg("could not write two-phase state file: %m")));
11461161
}
11471162

1148-
if (CloseTransientFile(fd) != 0)
1149-
ereport(ERROR,
1150-
(errcode_for_file_access(),
1151-
errmsg("could not close two-phase state file: %m")));
1163+
// if (CloseTransientFile(fd) != 0)
1164+
// ereport(ERROR,
1165+
// (errcode_for_file_access(),
1166+
// errmsg("could not close two-phase state file: %m")));
11521167

11531168
/*
11541169
* Mark the prepared transaction as valid. As soon as xact.c marks
@@ -1219,100 +1234,101 @@ RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info,
12191234
static char *
12201235
ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
12211236
{
1222-
char path[MAXPGPATH];
1223-
char *buf;
1224-
TwoPhaseFileHeader *hdr;
1225-
int fd;
1226-
struct stat stat;
1227-
uint32 crc_offset;
1228-
pg_crc32c calc_crc,
1229-
file_crc;
1230-
1231-
TwoPhaseFilePath(path, xid);
1232-
1233-
fd = OpenTransientFile(path, O_RDONLY | PG_BINARY, 0);
1234-
if (fd < 0)
1235-
{
1236-
if (give_warnings)
1237-
ereport(WARNING,
1238-
(errcode_for_file_access(),
1239-
errmsg("could not open two-phase state file \"%s\": %m",
1240-
path)));
1241-
return NULL;
1242-
}
1237+
// char path[MAXPGPATH];
1238+
// char *buf;
1239+
// TwoPhaseFileHeader *hdr;
1240+
// int fd;
1241+
// struct stat stat;
1242+
// uint32 crc_offset;
1243+
// pg_crc32c calc_crc,
1244+
// file_crc;
1245+
1246+
// TwoPhaseFilePath(path, xid);
1247+
1248+
// fd = OpenTransientFile(path, O_RDONLY | PG_BINARY, 0);
1249+
1250+
// if (fd < 0)
1251+
// {
1252+
// if (give_warnings)
1253+
// ereport(WARNING,
1254+
// (errcode_for_file_access(),
1255+
// errmsg("could not open two-phase state file \"%s\": %m",
1256+
// path)));
1257+
// return NULL;
1258+
// }
12431259

12441260
/*
12451261
* Check file length. We can determine a lower bound pretty easily. We
12461262
* set an upper bound to avoid palloc() failure on a corrupt file, though
12471263
* we can't guarantee that we won't get an out of memory error anyway,
12481264
* even on a valid file.
12491265
*/
1250-
if (fstat(fd, &stat))
1251-
{
1252-
CloseTransientFile(fd);
1253-
if (give_warnings)
1254-
ereport(WARNING,
1255-
(errcode_for_file_access(),
1256-
errmsg("could not stat two-phase state file \"%s\": %m",
1257-
path)));
1258-
return NULL;
1259-
}
1260-
1261-
if (stat.st_size < (MAXALIGN(sizeof(TwoPhaseFileHeader)) +
1262-
MAXALIGN(sizeof(TwoPhaseRecordOnDisk)) +
1263-
sizeof(pg_crc32c)) ||
1264-
stat.st_size > MaxAllocSize)
1265-
{
1266-
CloseTransientFile(fd);
1267-
return NULL;
1268-
}
1269-
1270-
crc_offset = stat.st_size - sizeof(pg_crc32c);
1271-
if (crc_offset != MAXALIGN(crc_offset))
1272-
{
1273-
CloseTransientFile(fd);
1274-
return NULL;
1275-
}
1276-
1277-
/*
1278-
* OK, slurp in the file.
1279-
*/
1280-
buf = (char *) palloc(stat.st_size);
1281-
1282-
if (read(fd, buf, stat.st_size) != stat.st_size)
1283-
{
1284-
CloseTransientFile(fd);
1285-
if (give_warnings)
1286-
ereport(WARNING,
1287-
(errcode_for_file_access(),
1288-
errmsg("could not read two-phase state file \"%s\": %m",
1289-
path)));
1290-
pfree(buf);
1291-
return NULL;
1292-
}
1293-
1294-
CloseTransientFile(fd);
1295-
1296-
hdr = (TwoPhaseFileHeader *) buf;
1297-
if (hdr->magic != TWOPHASE_MAGIC || hdr->total_len != stat.st_size)
1298-
{
1299-
pfree(buf);
1300-
return NULL;
1301-
}
1302-
1303-
INIT_CRC32C(calc_crc);
1304-
COMP_CRC32C(calc_crc, buf, crc_offset);
1305-
FIN_CRC32C(calc_crc);
1306-
1307-
file_crc = *((pg_crc32c *) (buf + crc_offset));
1308-
1309-
if (!EQ_CRC32C(calc_crc, file_crc))
1310-
{
1311-
pfree(buf);
1312-
return NULL;
1313-
}
1314-
1315-
return buf;
1266+
// if (fstat(fd, &stat))
1267+
// {
1268+
// CloseTransientFile(fd);
1269+
// if (give_warnings)
1270+
// ereport(WARNING,
1271+
// (errcode_for_file_access(),
1272+
// errmsg("could not stat two-phase state file \"%s\": %m",
1273+
// path)));
1274+
// return NULL;
1275+
// }
1276+
1277+
// if (stat.st_size < (MAXALIGN(sizeof(TwoPhaseFileHeader)) +
1278+
// MAXALIGN(sizeof(TwoPhaseRecordOnDisk)) +
1279+
// sizeof(pg_crc32c)) ||
1280+
// stat.st_size > MaxAllocSize)
1281+
// {
1282+
// CloseTransientFile(fd);
1283+
// return NULL;
1284+
// }
1285+
1286+
// crc_offset = stat.st_size - sizeof(pg_crc32c);
1287+
// if (crc_offset != MAXALIGN(crc_offset))
1288+
// {
1289+
// CloseTransientFile(fd);
1290+
// return NULL;
1291+
// }
1292+
1293+
// /*
1294+
// * OK, slurp in the file.
1295+
// */
1296+
// buf = (char *) palloc(stat.st_size);
1297+
1298+
// if (read(fd, buf, stat.st_size) != stat.st_size)
1299+
// {
1300+
// CloseTransientFile(fd);
1301+
// if (give_warnings)
1302+
// ereport(WARNING,
1303+
// (errcode_for_file_access(),
1304+
// errmsg("could not read two-phase state file \"%s\": %m",
1305+
// path)));
1306+
// pfree(buf);
1307+
// return NULL;
1308+
// }
1309+
1310+
// CloseTransientFile(fd);
1311+
1312+
// hdr = (TwoPhaseFileHeader *) buf;
1313+
// if (hdr->magic != TWOPHASE_MAGIC || hdr->total_len != stat.st_size)
1314+
// {
1315+
// pfree(buf);
1316+
// return NULL;
1317+
// }
1318+
1319+
// INIT_CRC32C(calc_crc);
1320+
// COMP_CRC32C(calc_crc, buf, crc_offset);
1321+
// FIN_CRC32C(calc_crc);
1322+
1323+
// file_crc = *((pg_crc32c *) (buf + crc_offset));
1324+
1325+
// if (!EQ_CRC32C(calc_crc, file_crc))
1326+
// {
1327+
// pfree(buf);
1328+
// return NULL;
1329+
// }
1330+
1331+
return twophase_buf;
13161332
}
13171333

13181334
/*
@@ -1489,7 +1505,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
14891505
RemoveGXact(gxact);
14901506
MyLockedGxact = NULL;
14911507

1492-
pfree(buf);
1508+
// pfree(buf);
14931509
}
14941510

14951511
/*
@@ -1527,15 +1543,16 @@ ProcessRecords(char *bufptr, TransactionId xid,
15271543
void
15281544
RemoveTwoPhaseFile(TransactionId xid, bool giveWarning)
15291545
{
1530-
char path[MAXPGPATH];
1531-
1532-
TwoPhaseFilePath(path, xid);
1533-
if (unlink(path))
1534-
if (errno != ENOENT || giveWarning)
1535-
ereport(WARNING,
1536-
(errcode_for_file_access(),
1537-
errmsg("could not remove two-phase state file \"%s\": %m",
1538-
path)));
1546+
// char path[MAXPGPATH];
1547+
1548+
// TwoPhaseFilePath(path, xid);
1549+
// if (unlink(path))
1550+
// if (errno != ENOENT || giveWarning)
1551+
// ereport(WARNING,
1552+
// (errcode_for_file_access(),
1553+
// errmsg("could not remove two-phase state file \"%s\": %m",
1554+
// path)));
1555+
twophase_pos = 0;
15391556
}
15401557

15411558
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy