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)