PostgreSQL Source Code: src/backend/storage/ipc/procarray.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

47

48#include <signal.h>

49

67

68#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))

69

70

72{

73 int numProcs;

74 int maxProcs;

75

76

77

78

83

84

85

86

87

88

89

90

92

93

95

97

98

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

168{

169

171

172

174};

175

176

177

178

180{

181

182

183

184

186

187

188

189

190

193

194

195

196

197

198

199

200

201

202

203

204

206

207

208

209

210

211

212

213

215

216

217

218

219

220

221

222

223

224

226

227

228

229

230

232

233

234

235

236

238

239

240

241

242

245

246

247

248

250{

256

257

258

259

261{

267

268

270

272

273

274

275

277

278

279

280

284

285

286

287

288

289

291

292

293

294

295

296

301

302

303

304

305

306

308

309#ifdef XIDCACHE_DEBUG

310

311

312static long xc_by_recent_xmin = 0;

313static long xc_by_known_xact = 0;

314static long xc_by_my_xact = 0;

315static long xc_by_latest_xid = 0;

316static long xc_by_main_xid = 0;

317static long xc_by_child_xid = 0;

318static long xc_by_known_assigned = 0;

319static long xc_no_overflow = 0;

320static long xc_slow_answer = 0;

321

322#define xc_by_recent_xmin_inc() (xc_by_recent_xmin++)

323#define xc_by_known_xact_inc() (xc_by_known_xact++)

324#define xc_by_my_xact_inc() (xc_by_my_xact++)

325#define xc_by_latest_xid_inc() (xc_by_latest_xid++)

326#define xc_by_main_xid_inc() (xc_by_main_xid++)

327#define xc_by_child_xid_inc() (xc_by_child_xid++)

328#define xc_by_known_assigned_inc() (xc_by_known_assigned++)

329#define xc_no_overflow_inc() (xc_no_overflow++)

330#define xc_slow_answer_inc() (xc_slow_answer++)

331

332static void DisplayXidCache(void);

333#else

334

335#define xc_by_recent_xmin_inc() ((void) 0)

336#define xc_by_known_xact_inc() ((void) 0)

337#define xc_by_my_xact_inc() ((void) 0)

338#define xc_by_latest_xid_inc() ((void) 0)

339#define xc_by_main_xid_inc() ((void) 0)

340#define xc_by_child_xid_inc() ((void) 0)

341#define xc_by_known_assigned_inc() ((void) 0)

342#define xc_no_overflow_inc() ((void) 0)

343#define xc_slow_answer_inc() ((void) 0)

344#endif

345

346

349 bool exclusive_lock);

367

371

372

373

374

377{

379

380

381#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)

382

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399#define TOTAL_MAX_CACHED_SUBXIDS \

400 ((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)

401

403 {

409 }

410

411 return size;

412}

413

414

415

416

417void

419{

420 bool found;

421

422

428 &found);

429

430 if (!found)

431 {

432

433

434

445 }

446

448

449

451 {

456 &found);

460 &found);

461 }

462}

463

464

465

466

467void

469{

473 int movecount;

474

475

478

480 {

481

482

483

484

485

487 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),

488 errmsg("sorry, too many clients already")));

489 }

490

491

492

493

494

495

496

497

498

499

501 {

503

506

507

508 if (this_procno > pgprocno)

509 break;

510 }

511

515 movecount * sizeof(*arrayP->pgprocnos));

525

531

533

534

537 {

539

542

544 }

545

546

547

548

549

552}

553

554

555

556

557

558

559

560

561

562

563

564void

566{

568 int myoff;

569 int movecount;

570

571#ifdef XIDCACHE_DEBUG

572

573 if (proc->pid != 0)

574 DisplayXidCache();

575#endif

576

577

580

582

583 Assert(myoff >= 0 && myoff < arrayP->numProcs);

585

587 {

589

590

592

593

595

599 }

600 else

601 {

602

604 }

605

609

611

612

613 movecount = arrayP->numProcs - myoff - 1;

614 memmove(&arrayP->pgprocnos[myoff],

616 movecount * sizeof(*arrayP->pgprocnos));

626

627 arrayP->pgprocnos[arrayP->numProcs - 1] = -1;

629

630

631

632

633

635 {

637

640

642 }

643

644

645

646

647

650}

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666void

668{

670 {

671

672

673

674

675

676

678

679

680

681

682

683

685 {

688 }

689 else

691 }

692 else

693 {

694

695

696

697

698

702

705

706

708

710

711

712

714 {

718 proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;

721 }

722 }

723}

724

725

726

727

728

729

730static inline void

732{

734

735

736

737

738

742

747

748

750

752

753

754

756 {

757 proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;

759 }

760

761

765 {

770 }

771

772

774

775

777}

778

779

780

781

782

783

784

785

786

787

788

789

790

791static void

793{

798

799

801

802

806 while (true)

807 {

809

811 &nextidx,

813 break;

814 }

815

816

817

818

819

820

821

823 {

824 int extraWaits = 0;

825

826

828 for (;;)

829 {

830

833 break;

834 extraWaits++;

835 }

837

839

840

841 while (extraWaits-- > 0)

843 return;

844 }

845

846

848

849

850

851

852

853

856

857

858 wakeidx = nextidx;

859

860

862 {

864

866

867

869 }

870

871

873

874

875

876

877

878

879

880

882 {

884

887

888

890

892

893 if (nextproc != MyProc)

895 }

896}

897

898

899

900

901

902

903

904

905

906void

908{

909 int pgxactoff;

910

911

912

913

914

915

916

917

918

919

920

921

922

923

924

926

928

931

935

938

939

940

941

942

943

944

945

947

948

952 {

957 }

958

960}

961

962

963

964

965

966static void

968{

970

974

976 {

979 }

980

983}

984

985

986

987

988static void

990{

993

996

997

998

999

1000

1001

1004

1007 {

1010 }

1011

1013}

1014

1015

1016

1017

1018

1019

1020

1021

1022void

1024{

1027

1028

1029

1030

1031

1032

1033

1036}

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053void

1055{

1058 int nxids;

1059 int i;

1060

1065

1066

1067

1068

1070

1071

1072

1073

1074

1075

1076 advanceNextXid = running->nextXid;

1080

1081

1082

1083

1085

1086

1087

1088

1090 return;

1091

1092

1093

1094

1095

1096

1097

1098

1099

1100

1101

1102

1104 {

1105

1106

1107

1108

1110 {

1111

1112

1113

1114

1117 }

1118 else

1119 {

1122 {

1125 "recovery snapshots are now enabled");

1126 }

1127 else

1129 "recovery snapshot waiting for non-overflowed snapshot or "

1130 "until oldest active xid on standby is at least %u (now %u)",

1133 return;

1134 }

1135 }

1136

1138

1139

1140

1141

1142

1143

1144

1145

1146

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159

1160

1161

1162

1163

1164

1166

1167

1168

1169

1170 nxids = 0;

1171 for (i = 0; i < running->xcnt + running->subxcnt; i++)

1172 {

1174

1175

1176

1177

1178

1179

1180

1182 continue;

1183

1184 xids[nxids++] = xid;

1185 }

1186

1187 if (nxids > 0)

1188 {

1190 {

1192 elog(ERROR, "KnownAssignedXids is not empty");

1193 }

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1205

1206

1207

1208

1209

1210

1211 for (i = 0; i < nxids; i++)

1212 {

1214 {

1216 "found duplicated transaction %u for KnownAssignedXids insertion",

1217 xids[i]);

1218 continue;

1219 }

1221 }

1222

1224 }

1225

1227

1228

1229

1230

1231

1232

1233

1234

1235

1236

1237

1241 {

1244 }

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1262 {

1264

1267 }

1268 else

1269 {

1271

1273

1274

1275

1276

1277

1280 else

1281 {

1284 }

1285 }

1286

1287

1288

1289

1290

1291

1292

1294

1295

1296

1297

1298

1299

1301

1304 elog(DEBUG1, "recovery snapshots are now enabled");

1305 else

1307 "recovery snapshot waiting for non-overflowed snapshot or "

1308 "until oldest active xid on standby is at least %u (now %u)",

1311}

1312

1313

1314

1315

1316

1317void

1320{

1322 int i;

1323

1325

1327

1328

1329

1330

1331

1332

1333

1334

1335

1337

1338

1339

1340

1341

1342

1343

1344

1345

1346

1347

1348

1349 for (i = 0; i < nsubxids; i++)

1351

1352

1354 return;

1355

1356

1357

1358

1360

1361

1362

1363

1365

1366

1367

1368

1371

1373}

1374

1375

1376

1377

1378

1379

1380

1381

1382

1383

1384

1385

1386

1387

1388

1389

1390

1391

1392

1393

1394

1395

1396

1397

1398

1399

1400

1401bool

1403{

1407 int nxids = 0;

1411 int mypgxactoff;

1412 int numProcs;

1413 int j;

1414

1415

1416

1417

1418

1419

1420

1422 {

1424 return false;

1425 }

1426

1427

1428

1429

1430

1431

1433 {

1435 return false;

1436 }

1437

1438

1439

1440

1441

1443 {

1445 return true;

1446 }

1447

1448

1449

1450

1451

1452 if (xids == NULL)

1453 {

1454

1455

1456

1457

1458

1460

1462 if (xids == NULL)

1464 (errcode(ERRCODE_OUT_OF_MEMORY),

1465 errmsg("out of memory")));

1466 }

1467

1470

1472

1473

1474

1475

1476

1477 latestCompletedXid =

1480 {

1483 return true;

1484 }

1485

1486

1488 numProcs = arrayP->numProcs;

1489 for (int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)

1490 {

1491 int pgprocno;

1494 int pxids;

1495

1496

1497 if (pgxactoff == mypgxactoff)

1498 continue;

1499

1500

1502

1504 continue;

1505

1506

1507

1508

1510 {

1513 return true;

1514 }

1515

1516

1517

1518

1519

1521 continue;

1522

1523

1524

1525

1526 pxids = other_subxidstates[pgxactoff].count;

1527 pg_read_barrier();

1528 pgprocno = arrayP->pgprocnos[pgxactoff];

1530 for (j = pxids - 1; j >= 0; j--)

1531 {

1532

1534

1536 {

1539 return true;

1540 }

1541 }

1542

1543

1544

1545

1546

1547

1548

1549

1550 if (other_subxidstates[pgxactoff].overflowed)

1551 xids[nxids++] = pxid;

1552 }

1553

1554

1555

1556

1557

1559 {

1560

1562

1564 {

1567 return true;

1568 }

1569

1570

1571

1572

1573

1574

1575

1576

1579 }

1580

1582

1583

1584

1585

1586

1587 if (nxids == 0)

1588 {

1591 return false;

1592 }

1593

1594

1595

1596

1597

1598

1599

1600

1601

1603

1605 {

1607 return false;

1608 }

1609

1610

1611

1612

1613

1614

1619 return true;

1620

1622 return false;

1623}

1624

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636

1637

1638

1639

1640

1641

1642

1643

1644

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656

1657

1658

1659

1660

1661

1662

1663

1664

1665

1666

1667

1668

1669

1670

1671

1672

1673

1674

1675

1676

1677

1678

1679

1680

1681

1682static void

1684{

1689

1690

1692

1694

1696

1697

1698

1699

1700

1701

1702

1703 {

1705

1709

1713

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723

1724

1725

1728 else

1730 }

1731

1732

1733

1734

1735

1736

1739

1741 {

1747

1748

1751

1752

1753

1754

1755

1756

1757

1758

1760

1761

1763 continue;

1764

1765

1766

1767

1768

1769

1770

1773

1774

1775

1776

1777

1778

1780 continue;

1781

1782

1785

1786

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797

1798

1799

1800

1801

1802

1803

1804

1808 in_recovery)

1809 {

1812 }

1813 }

1814

1815

1816

1817

1818

1819 if (in_recovery)

1821

1822

1823

1824

1825

1827

1828 if (in_recovery)

1829 {

1836

1837 }

1838

1843

1844

1845

1846

1851

1852

1853

1854

1855

1856

1857

1858

1867

1868

1869

1870

1871

1881

1882

1883

1884

1885

1890

1891

1892

1893

1894

1909

1910

1912}

1913

1914

1915

1916

1917

1920{

1921

1922

1923

1924

1926 rel->rd_rel->relkind == RELKIND_RELATION ||

1927 rel->rd_rel->relkind == RELKIND_MATVIEW ||

1928 rel->rd_rel->relkind == RELKIND_TOASTVALUE);

1929

1937 else

1939}

1940

1941

1942

1943

1944

1945

1946

1947

1948

1949

1950

1951

1954{

1956

1958

1960 {

1969 }

1970

1971

1973}

1974

1975

1976

1977

1978

1979

1980

1983{

1985

1987

1989}

1990

1991

1992

1993

1994void

1996{

1998

2000

2001

2002

2003

2004

2005

2006

2009}

2010

2011

2012

2013

2014

2015

2016int

2018{

2020}

2021

2022

2023

2024

2025

2026

2027int

2029{

2031}

2032

2033

2034

2035

2036

2037

2038

2039

2040

2041

2042static bool

2044{

2045 uint64 curXactCompletionCount;

2046

2048

2050 return false;

2051

2054 return false;

2055

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067

2068

2069

2070

2071

2072

2073

2074

2075

2078

2081

2085 snapshot->copied = false;

2086

2087 return true;

2088}

2089

2090

2091

2092

2093

2094

2095

2096

2097

2098

2099

2100

2101

2102

2103

2104

2105

2106

2107

2108

2109

2110

2111

2112

2113

2114

2115

2116

2117

2118

2119

2120

2121

2124{

2129 int count = 0;

2130 int subcount = 0;

2131 bool suboverflowed = false;

2134 int mypgxactoff;

2136 uint64 curXactCompletionCount;

2137

2140

2141 Assert(snapshot != NULL);

2142

2143

2144

2145

2146

2147

2148

2149

2150

2151

2152

2153

2154 if (snapshot->xip == NULL)

2155 {

2156

2157

2158

2159

2162 if (snapshot->xip == NULL)

2164 (errcode(ERRCODE_OUT_OF_MEMORY),

2165 errmsg("out of memory")));

2169 if (snapshot->subxip == NULL)

2171 (errcode(ERRCODE_OUT_OF_MEMORY),

2172 errmsg("out of memory")));

2173 }

2174

2175

2176

2177

2178

2180

2182 {

2184 return snapshot;

2185 }

2186

2189 myxid = other_xids[mypgxactoff];

2191

2194

2195

2199

2200

2201 xmin = xmax;

2202

2203

2205 xmin = myxid;

2206

2208

2210 {

2211 int numProcs = arrayP->numProcs;

2213 int *pgprocnos = arrayP->pgprocnos;

2216

2217

2218

2219

2220

2221 for (int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)

2222 {

2223

2225 uint8 statusFlags;

2226

2228

2229

2230

2231

2232

2234 continue;

2235

2236

2237

2238

2239

2240

2241 if (pgxactoff == mypgxactoff)

2242 continue;

2243

2244

2245

2246

2247

2248

2249

2251

2252

2253

2254

2255

2256

2258 continue;

2259

2260

2261

2262

2263

2264 statusFlags = allStatusFlags[pgxactoff];

2266 continue;

2267

2269 xmin = xid;

2270

2271

2272 xip[count++] = xid;

2273

2274

2275

2276

2277

2278

2279

2280

2281

2282

2283

2284

2285

2286

2287

2288

2289 if (!suboverflowed)

2290 {

2291

2292 if (subxidStates[pgxactoff].overflowed)

2293 suboverflowed = true;

2294 else

2295 {

2296 int nsubxids = subxidStates[pgxactoff].count;

2297

2298 if (nsubxids > 0)

2299 {

2300 int pgprocno = pgprocnos[pgxactoff];

2302

2304

2305 memcpy(snapshot->subxip + subcount,

2308 subcount += nsubxids;

2309 }

2310 }

2311 }

2312 }

2313 }

2314 else

2315 {

2316

2317

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337

2338

2339

2340

2341

2342

2343

2344

2346 xmax);

2347

2349 suboverflowed = true;

2350 }

2351

2352

2353

2354

2355

2356

2357

2360

2363

2365

2366

2367 {

2373

2374

2375

2376

2377

2378

2380

2381

2382 def_vis_xid_data =

2384

2385

2386

2387

2388

2389 def_vis_xid = def_vis_xid_data;

2390

2391

2392

2393

2394

2395 def_vis_xid =

2397

2398 def_vis_fxid = FullXidRelativeTo(latest_completed, def_vis_xid);

2399 def_vis_fxid_data = FullXidRelativeTo(latest_completed, def_vis_xid_data);

2400

2401

2402

2403

2404

2405

2415

2419 else

2420 {

2423 }

2424

2425

2426

2427

2428

2429

2430

2431

2432

2435 oldestfxid);

2438 oldestfxid);

2441 oldestfxid);

2442

2444 }

2445

2448

2449 snapshot->xmin = xmin;

2450 snapshot->xmax = xmax;

2451 snapshot->xcnt = count;

2452 snapshot->subxcnt = subcount;

2455

2457

2458

2459

2460

2461

2464 snapshot->copied = false;

2465

2466 return snapshot;

2467}

2468

2469

2470

2471

2472

2473

2474

2475

2476

2477

2478

2479bool

2482{

2483 bool result = false;

2486

2488 if (!sourcevxid)

2489 return false;

2490

2491

2493

2494

2495

2496

2497

2498

2500 {

2505

2506

2508 continue;

2509

2510

2512 continue;

2514 continue;

2515

2516

2517

2518

2519

2520

2521

2523 continue;

2524

2525

2526

2527

2531 continue;

2532

2533

2534

2535

2536

2537

2538

2540

2541 result = true;

2542 break;

2543 }

2544

2546

2547 return result;

2548}

2549

2550

2551

2552

2553

2554

2555

2556

2557

2558

2559

2560

2561

2562

2563bool

2565{

2566 bool result = false;

2568

2570 Assert(proc != NULL);

2571

2572

2573

2574

2576

2577

2578

2579

2580

2581

2582

2587 {

2588

2589

2590

2591

2596

2597 result = true;

2598 }

2599

2601

2602 return result;

2603}

2604

2605

2606

2607

2608

2609

2610

2611

2612

2613

2614

2615

2616

2617

2618

2619

2620

2621

2622

2623

2624

2625

2626

2627

2628

2629

2630

2631

2632

2633

2634

2635

2638{

2639

2641

2650 int count;

2651 int subcount;

2652 bool suboverflowed;

2653

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665 if (CurrentRunningXacts->xids == NULL)

2666 {

2667

2668

2669

2672 if (CurrentRunningXacts->xids == NULL)

2674 (errcode(ERRCODE_OUT_OF_MEMORY),

2675 errmsg("out of memory")));

2676 }

2677

2678 xids = CurrentRunningXacts->xids;

2679

2680 count = subcount = 0;

2681 suboverflowed = false;

2682

2683

2684

2685

2686

2689

2690 latestCompletedXid =

2692 oldestDatabaseRunningXid = oldestRunningXid =

2694

2695

2696

2697

2699 {

2701

2702

2704

2705

2706

2707

2708

2710 continue;

2711

2712

2713

2714

2715

2716

2718 oldestRunningXid = xid;

2719

2720

2721

2722

2723

2724

2726 {

2729

2731 oldestDatabaseRunningXid = xid;

2732 }

2733

2735 suboverflowed = true;

2736

2737

2738

2739

2740

2741

2742

2743

2744

2745 xids[count++] = xid;

2746 }

2747

2748

2749

2750

2751

2752 if (!suboverflowed)

2753 {

2755

2757 {

2760 int nsubxids;

2761

2762

2763

2764

2765

2766 nsubxids = other_subxidstates[index].count;

2767 if (nsubxids > 0)

2768 {

2769

2771

2772 memcpy(&xids[count], proc->subxids.xids,

2774 count += nsubxids;

2775 subcount += nsubxids;

2776

2777

2778

2779

2780

2781

2782 }

2783 }

2784 }

2785

2786

2787

2788

2789

2790

2791

2792

2793

2794

2795 CurrentRunningXacts->xcnt = count - subcount;

2796 CurrentRunningXacts->subxcnt = subcount;

2802

2806

2807

2808

2809 return CurrentRunningXacts;

2810}

2811

2812

2813

2814

2815

2816

2817

2818

2819

2820

2821

2822

2823

2824

2825

2826

2827

2828

2829

2830

2831

2834{

2839

2841

2842

2843

2844

2845

2846

2847

2848

2852

2853

2854

2855

2858 {

2862

2863

2865

2867 continue;

2868

2869 if (inCommitOnly &&

2871 continue;

2872

2874 continue;

2875

2877 oldestRunningXid = xid;

2878

2879

2880

2881

2882

2883

2884 }

2886

2887 return oldestRunningXid;

2888}

2889

2890

2891

2892

2893

2894

2895

2896

2897

2898

2899

2900

2901

2902

2903

2904

2905

2908{

2913

2915

2916

2917

2918

2919

2920

2921

2922

2923

2926

2927

2928

2929

2930

2931

2932

2933

2936 oldestSafeXid))

2938

2939 if (catalogOnly &&

2942 oldestSafeXid))

2944

2945

2946

2947

2948

2949

2950

2951

2952

2953

2954

2955

2956

2957 if (!recovery_in_progress)

2958 {

2960

2961

2962

2963

2965 {

2967

2968

2970

2972 continue;

2973

2975 oldestSafeXid = xid;

2976 }

2977 }

2978

2980

2981 return oldestSafeXid;

2982}

2983

2984

2985

2986

2987

2988

2989

2990

2991

2992

2993

2994

2995

2996

2997

2998

2999

3000

3001

3002

3003

3006{

3009 int count = 0;

3011

3013

3014

3016

3018

3020 {

3023

3025 {

3027

3030 vxids[count++] = vxid;

3031 }

3032 }

3033

3035

3036 *nvxids = count;

3037 return vxids;

3038}

3039

3040

3041

3042

3043

3044

3045

3046

3047

3048

3049bool

3051{

3052 bool result = false;

3055

3057

3059

3061 {

3065

3067

3070 {

3071 int i;

3072

3073 for (i = 0; i < nvxids; i++)

3074 {

3076 {

3077 result = true;

3078 break;

3079 }

3080 }

3081 if (result)

3082 break;

3083 }

3084 }

3085

3087

3088 return result;

3089}

3090

3091

3092

3093

3094

3095

3096

3097

3100{

3102

3104 return NULL;

3106

3107 if (result->pid == 0)

3108 return NULL;

3109

3110 return result;

3111}

3112

3113

3114

3115

3116

3117

3118

3119

3120void

3122 TransactionId *xmin, int *nsubxid, bool *overflowed)

3123{

3125

3128 *nsubxid = 0;

3129 *overflowed = false;

3130

3132 return;

3134

3135

3137

3138 if (proc->pid != 0)

3139 {

3140 *xid = proc->xid;

3141 *xmin = proc->xmin;

3144 }

3145

3147}

3148

3149

3150

3151

3152

3153

3154

3155

3158{

3160

3161 if (pid == 0)

3162 return NULL;

3163

3165

3167

3169

3170 return result;

3171}

3172

3173

3174

3175

3176

3177

3178

3181{

3182 PGPROC *result = NULL;

3185

3186 if (pid == 0)

3187 return NULL;

3188

3190 {

3192

3193 if (proc->pid == pid)

3194 {

3195 result = proc;

3196 break;

3197 }

3198 }

3199

3200 return result;

3201}

3202

3203

3204

3205

3206

3207

3208

3209

3210

3211

3212

3213

3214

3215

3216int

3218{

3219 int result = 0;

3223

3225 return 0;

3226

3228

3230 {

3231 if (other_xids[index] == xid)

3232 {

3235

3236 result = proc->pid;

3237 break;

3238 }

3239 }

3240

3242

3243 return result;

3244}

3245

3246

3247

3248

3249

3250

3251bool

3253{

3255}

3256

3257

3258

3259

3260

3261

3262

3263

3264

3265

3266

3267

3268

3269

3270

3271

3272

3273

3274

3275

3276

3277

3278

3279

3280

3281

3282

3283

3286 bool allDbs, int excludeVacuum,

3287 int *nvxids)

3288{

3291 int count = 0;

3293

3294

3296

3298

3300 {

3304

3306 continue;

3307

3308 if (excludeVacuum & statusFlags)

3309 continue;

3310

3312 {

3313

3315

3317 continue;

3318

3319

3320

3321

3322

3325 {

3327

3330 vxids[count++] = vxid;

3331 }

3332 }

3333 }

3334

3336

3337 *nvxids = count;

3338 return vxids;

3339}

3340

3341

3342

3343

3344

3345

3346

3347

3348

3349

3350

3351

3352

3353

3354

3355

3356

3357

3358

3359

3360

3361

3362

3363

3364

3365

3366

3367

3368

3369

3370

3371

3372

3373

3374

3375

3378{

3381 int count = 0;

3383

3384

3385

3386

3387

3388

3389 if (vxids == NULL)

3390 {

3393 if (vxids == NULL)

3395 (errcode(ERRCODE_OUT_OF_MEMORY),

3396 errmsg("out of memory")));

3397 }

3398

3400

3402 {

3405

3406

3407 if (proc->pid == 0)

3408 continue;

3409

3412 {

3413

3415

3416

3417

3418

3419

3420

3421

3422

3423

3426 {

3428

3431 vxids[count++] = vxid;

3432 }

3433 }

3434 }

3435

3437

3438

3441

3442 return vxids;

3443}

3444

3445

3446

3447

3448

3449

3450pid_t

3452{

3454}

3455

3456pid_t

3458 bool conflictPending)

3459{

3462 pid_t pid = 0;

3463

3465

3467 {

3471

3473

3476 {

3478 pid = proc->pid;

3479 if (pid != 0)

3480 {

3481

3482

3483

3484

3486 }

3487 break;

3488 }

3489 }

3490

3492

3493 return pid;

3494}

3495

3496

3497

3498

3499

3500

3501

3502

3503

3504

3505bool

3507{

3509 int count = 0;

3511

3512

3513 if (min == 0)

3514 return true;

3515

3516

3517

3518

3519

3520

3522 {

3525

3526

3527

3528

3529

3530

3531

3532

3533

3534

3535

3536

3537 if (pgprocno == -1)

3538 continue;

3540 continue;

3542 continue;

3543 if (proc->pid == 0)

3544 continue;

3546 continue;

3547 count++;

3548 if (count >= min)

3549 break;

3550 }

3551

3552 return count >= min;

3553}

3554

3555

3556

3557

3558int

3560{

3562 int count = 0;

3564

3566

3568 {

3571

3572 if (proc->pid == 0)

3573 continue;

3576 count++;

3577 }

3578

3580

3581 return count;

3582}

3583

3584

3585

3586

3587int

3589{

3591 int count = 0;

3593

3595

3597 {

3600

3601 if (proc->pid == 0)

3602 continue;

3604 continue;

3607 count++;

3608 }

3609

3611

3612 return count;

3613}

3614

3615

3616

3617

3618void

3620{

3623

3624

3626

3628 {

3631

3633 {

3635 pid_t pid;

3636

3638

3640 pid = proc->pid;

3641 if (pid != 0)

3642 {

3643

3644

3645

3646

3648 }

3649 }

3650 }

3651

3653}

3654

3655

3656

3657

3658

3659int

3661{

3663 int count = 0;

3665

3667

3669 {

3672

3673 if (proc->pid == 0)

3674 continue;

3676 continue;

3677 if (proc->roleId == roleid)

3678 count++;

3679 }

3680

3682

3683 return count;

3684}

3685

3686

3687

3688

3689

3690

3691

3692

3693

3694

3695

3696

3697

3698

3699

3700

3701

3702

3703

3704

3705

3706

3707

3708

3709bool

3711{

3713

3714#define MAXAUTOVACPIDS 10

3716 int tries;

3717

3718

3719 for (tries = 0; tries < 50; tries++)

3720 {

3721 int nautovacs = 0;

3722 bool found = false;

3724

3726

3727 *nbackends = *nprepared = 0;

3728

3730

3732 {

3736

3738 continue;

3740 continue;

3741

3742 found = true;

3743

3744 if (proc->pid == 0)

3745 (*nprepared)++;

3746 else

3747 {

3748 (*nbackends)++;

3751 autovac_pids[nautovacs++] = proc->pid;

3752 }

3753 }

3754

3756

3757 if (!found)

3758 return false;

3759

3760

3761

3762

3763

3764

3765

3767 (void) kill(autovac_pids[index], SIGTERM);

3768

3769

3770 pg_usleep(100 * 1000L);

3771 }

3772

3773 return true;

3774}

3775

3776

3777

3778

3779

3780

3781

3782

3783

3784

3785

3786

3787void

3789{

3792 int nprepared = 0;

3793 int i;

3794

3796

3798 {

3799 int pgprocno = arrayP->pgprocnos[i];

3801

3803 continue;

3805 continue;

3806

3807 if (proc->pid != 0)

3809 else

3810 nprepared++;

3811 }

3812

3814

3815 if (nprepared > 0)

3817 (errcode(ERRCODE_OBJECT_IN_USE),

3818 errmsg("database \"%s\" is being used by prepared transactions",

3820 errdetail_plural("There is %d prepared transaction using the database.",

3821 "There are %d prepared transactions using the database.",

3822 nprepared,

3823 nprepared)));

3824

3825 if (pids)

3826 {

3828

3829

3830

3831

3832

3833

3834

3835

3836

3837

3838

3839

3840

3841

3842

3843

3844 foreach(lc, pids)

3845 {

3848

3849 if (proc != NULL)

3850 {

3853 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

3854 errmsg("permission denied to terminate process"),

3855 errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",

3856 "SUPERUSER", "SUPERUSER")));

3857

3861 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

3862 errmsg("permission denied to terminate process"),

3863 errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",

3864 "pg_signal_backend")));

3865 }

3866 }

3867

3868

3869

3870

3871

3872

3873

3874 foreach(lc, pids)

3875 {

3878

3879 if (proc != NULL)

3880 {

3881

3882

3883

3884

3885#ifdef HAVE_SETSID

3886 (void) kill(-pid, SIGTERM);

3887#else

3888 (void) kill(pid, SIGTERM);

3889#endif

3890 }

3891 }

3892 }

3893}

3894

3895

3896

3897

3898

3899

3900

3901

3902void

3904 bool already_locked)

3905{

3907

3908 if (!already_locked)

3910

3913

3914 if (!already_locked)

3916

3917 elog(DEBUG1, "xmin required by slots: data %u, catalog %u",

3918 xmin, catalog_xmin);

3919}

3920

3921

3922

3923

3924

3925

3926

3927void

3930{

3932

3933 if (xmin != NULL)

3935

3936 if (catalog_xmin != NULL)

3938

3940}

3941

3942

3943

3944

3945

3946

3947

3948

3949

3950void

3954{

3955 int i,

3956 j;

3958

3960

3961

3962

3963

3964

3965

3966

3967

3968

3969

3970

3971

3972

3974

3976

3977

3978

3979

3980

3981

3982 for (i = nxids - 1; i >= 0; i--)

3983 {

3985

3987 {

3989 {

3992 mysubxidstat->count--;

3994 break;

3995 }

3996 }

3997

3998

3999

4000

4001

4002

4003

4004

4005 if (j < 0 && !MyProc->subxidStatus.overflowed)

4006 elog(WARNING, "did not find subXID %u in MyProc", anxid);

4007 }

4008

4010 {

4012 {

4015 mysubxidstat->count--;

4017 break;

4018 }

4019 }

4020

4021 if (j < 0 && !MyProc->subxidStatus.overflowed)

4022 elog(WARNING, "did not find subXID %u in MyProc", xid);

4023

4024

4026

4027

4029

4031}

4032

4033#ifdef XIDCACHE_DEBUG

4034

4035

4036

4037

4038static void

4039DisplayXidCache(void)

4040{

4042 "XidCache: xmin: %ld, known: %ld, myxact: %ld, latest: %ld, mainxid: %ld, childxid: %ld, knownassigned: %ld, nooflo: %ld, slow: %ld\n",

4043 xc_by_recent_xmin,

4044 xc_by_known_xact,

4045 xc_by_my_xact,

4046 xc_by_latest_xid,

4047 xc_by_main_xid,

4048 xc_by_child_xid,

4049 xc_by_known_assigned,

4050 xc_no_overflow,

4051 xc_slow_answer);

4052}

4053#endif

4054

4055

4056

4057

4058

4059

4060

4061

4062

4063

4064

4065

4068{

4070

4071

4073

4075 {

4078 break;

4081 break;

4084 break;

4087 break;

4088 }

4089

4092

4094}

4095

4096

4097

4098

4099

4100

4101

4102

4103

4104

4105

4106static bool

4108{

4109

4111 return true;

4112

4113

4114

4115

4116

4118 state->definitely_needed))

4119 return false;

4120

4121

4123}

4124

4125static void

4127{

4140

4141

4142

4143

4144

4145

4156

4158}

4159

4160

4161

4162

4163

4164static void

4166{

4168

4169

4171}

4172

4173

4174

4175

4176

4177

4178

4179

4180

4181bool

4184{

4185

4186

4187

4188

4190 return true;

4191

4192

4193

4194

4195

4197 return false;

4198

4199

4200

4201

4202

4203

4205 {

4207

4209

4211 }

4212 else

4213 return false;

4214}

4215

4216

4217

4218

4219

4220

4221

4222

4223bool

4225{

4227

4228

4229

4230

4231

4232

4233

4234

4235

4237

4239}

4240

4241

4242

4243

4244

4245bool

4247{

4249

4251

4253}

4254

4255

4256

4257

4258

4259bool

4261{

4263

4265

4267}

4268

4269

4270

4271

4272

4273

4274

4275

4276

4277

4278

4279

4282{

4284

4287

4288

4290

4292 + (int32) (xid - rel_xid));

4293}

4294

4295

4296

4297

4298

4299

4300

4301

4302

4303

4304

4305

4306

4307

4308

4309

4310

4311

4312

4313

4314

4315

4316

4317

4318

4319

4320

4321

4322

4323

4324

4325

4326

4327

4328

4329

4330

4331

4332

4333

4334

4335

4336

4337

4338

4339

4340

4341

4342

4343

4344

4345

4346

4347

4348

4349

4350

4351

4352

4353

4354

4355

4356

4357

4358

4359

4360

4361

4362void

4364{

4368

4369 elog(DEBUG4, "record known xact %u latestObservedXid %u",

4371

4372

4373

4374

4375

4376

4378 {

4380

4381

4382

4383

4384

4385

4386

4387

4388

4389

4392 {

4395 }

4396 Assert(next_expected_xid == xid);

4397

4398

4399

4400

4401

4403 {

4405 return;

4406 }

4407

4408

4409

4410

4414

4415

4416

4417

4419

4420

4422 }

4423}

4424

4425

4426

4427

4428

4429

4430

4431void

4434{

4436

4437

4438

4439

4441

4443

4444

4446

4447

4449

4451}

4452

4453

4454

4455

4456

4457void

4459{

4461

4464

4465

4470

4471

4472

4473

4474

4476

4477

4478

4479

4480

4481

4484}

4485

4486

4487

4488

4489

4490

4491void

4493{

4495

4497

4498

4499 latestXid = xid;

4502

4503

4505

4506

4507

4508

4509

4510

4511

4516}

4517

4518

4519

4520

4521

4522

4523void

4525{

4527}

4528

4529

4530

4531

4532

4533

4534

4535

4536

4537

4538

4539

4540

4541

4542

4543

4544

4545

4546

4547

4548

4549

4550

4551

4552

4553

4554

4555

4556

4557

4558

4559

4560

4561

4562

4563

4564

4565

4566

4567

4568

4569

4570

4571

4572

4573

4574

4575

4576

4577

4578

4579

4580

4581

4582

4583

4584

4585

4586

4587

4588

4589

4590

4591

4592

4593

4594

4595

4596

4597

4598

4599

4600

4601

4602

4603

4604

4605

4606

4607

4608

4609

4610

4611

4612

4613

4614

4615

4616

4617

4618

4619

4620

4621

4622

4623

4624static void

4626{

4628 int head,

4629 tail,

4630 nelements;

4631 int compress_index;

4632 int i;

4633

4634

4635 static unsigned int transactionEndsCounter;

4637

4638

4639#define KAX_COMPRESS_FREQUENCY 128

4640#define KAX_COMPRESS_IDLE_INTERVAL 1000

4641

4642

4643

4644

4645

4648 nelements = head - tail;

4649

4650

4651

4652

4653

4654

4655

4657 {

4658

4659

4660

4661

4662

4664 return;

4665 }

4667 {

4668

4669

4670

4671

4673 return;

4674

4675

4676

4677

4678

4679 if (nelements < 2 * pArray->numKnownAssignedXids)

4680 return;

4681 }

4683 {

4684

4685

4686

4687

4688

4689 if (lastCompressTs != 0)

4690 {

4692

4696 return;

4697 }

4698 }

4699

4700

4701 if (!haveLock)

4703

4704

4705

4706

4707

4708 compress_index = 0;

4709 for (i = tail; i < head; i++)

4710 {

4712 {

4715 compress_index++;

4716 }

4717 }

4719

4722

4723 if (!haveLock)

4725

4726

4728}

4729

4730

4731

4732

4733

4734

4735

4736

4737

4738

4739

4740

4741static void

4743 bool exclusive_lock)

4744{

4747 int head,

4748 tail;

4749 int nxids;

4750 int i;

4751

4753

4754

4755

4756

4757

4758

4759 if (to_xid >= from_xid)

4760 nxids = to_xid - from_xid + 1;

4761 else

4762 {

4763 nxids = 1;

4764 next_xid = from_xid;

4766 {

4767 nxids++;

4769 }

4770 }

4771

4772

4773

4774

4775

4778

4779 Assert(head >= 0 && head <= pArray->maxKnownAssignedXids);

4780 Assert(tail >= 0 && tail < pArray->maxKnownAssignedXids);

4781

4782

4783

4784

4785

4786

4787 if (head > tail &&

4789 {

4791 elog(ERROR, "out-of-order XID insertion in KnownAssignedXids");

4792 }

4793

4794

4795

4796

4798 {

4800

4802

4803

4804

4805

4806

4808 elog(ERROR, "too many KnownAssignedXids");

4809 }

4810

4811

4812 next_xid = from_xid;

4813 for (i = 0; i < nxids; i++)

4814 {

4818 head++;

4819 }

4820

4821

4823

4824

4825

4826

4827

4828

4829

4830 if (!exclusive_lock)

4832

4834}

4835

4836

4837

4838

4839

4840

4841

4842

4843

4844

4845static bool

4847{

4849 int first,

4850 last;

4851 int head;

4852 int tail;

4853 int result_index = -1;

4854

4857

4858

4859

4860

4861

4862 if (!remove)

4863 pg_read_barrier();

4864

4865

4866

4867

4868

4869 first = tail;

4870 last = head - 1;

4871 while (first <= last)

4872 {

4873 int mid_index;

4875

4876 mid_index = (first + last) / 2;

4878

4879 if (xid == mid_xid)

4880 {

4881 result_index = mid_index;

4882 break;

4883 }

4885 last = mid_index - 1;

4886 else

4887 first = mid_index + 1;

4888 }

4889

4890 if (result_index < 0)

4891 return false;

4892

4894 return false;

4895

4896 if (remove)

4897 {

4899

4902

4903

4904

4905

4906

4907 if (result_index == tail)

4908 {

4909 tail++;

4911 tail++;

4912 if (tail >= head)

4913 {

4914

4917 }

4918 else

4919 {

4921 }

4922 }

4923 }

4924

4925 return true;

4926}

4927

4928

4929

4930

4931

4932

4933static bool

4935{

4937

4939}

4940

4941

4942

4943

4944

4945

4946static void

4948{

4950

4951 elog(DEBUG4, "remove KnownAssignedXid %u", xid);

4952

4953

4954

4955

4956

4957

4958

4959

4960

4961

4962

4964}

4965

4966

4967

4968

4969

4970

4971

4972static void

4975{

4976 int i;

4977

4980

4981 for (i = 0; i < nsubxids; i++)

4983

4984

4986}

4987

4988

4989

4990

4991

4992

4993

4994static void

4996{

4998 int count = 0;

4999 int head,

5000 tail,

5001 i;

5002

5004 {

5005 elog(DEBUG4, "removing all KnownAssignedXids");

5008 return;

5009 }

5010

5011 elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);

5012

5013

5014

5015

5016

5019

5020 for (i = tail; i < head; i++)

5021 {

5023 {

5025

5027 break;

5028

5030 {

5032 count++;

5033 }

5034 }

5035 }

5036

5039

5040

5041

5042

5043 for (i = tail; i < head; i++)

5044 {

5046 break;

5047 }

5048 if (i >= head)

5049 {

5050

5053 }

5054 else

5055 {

5057 }

5058

5059

5061}

5062

5063

5064

5065

5066

5067

5068

5069

5070

5071

5072static int

5074{

5076

5078}

5079

5080

5081

5082

5083

5084

5085

5086static int

5089{

5090 int count = 0;

5091 int head,

5092 tail;

5093 int i;

5094

5095

5096

5097

5098

5099

5100

5101

5104

5105 pg_read_barrier();

5106

5107 for (i = tail; i < head; i++)

5108 {

5109

5111 {

5113

5114

5115

5116

5117

5118 if (count == 0 &&

5120 *xmin = knownXid;

5121

5122

5123

5124

5125

5128 break;

5129

5130

5131 xarray[count++] = knownXid;

5132 }

5133 }

5134

5135 return count;

5136}

5137

5138

5139

5140

5141

5144{

5145 int head,

5146 tail;

5147 int i;

5148

5149

5150

5151

5154

5155 pg_read_barrier();

5156

5157 for (i = tail; i < head; i++)

5158 {

5159

5162 }

5163

5165}

5166

5167

5168

5169

5170

5171

5172

5173

5174

5175

5176

5177static void

5179{

5182 int head,

5183 tail,

5184 i;

5185 int nxids = 0;

5186

5189

5191

5192 for (i = tail; i < head; i++)

5193 {

5195 {

5196 nxids++;

5198 }

5199 }

5200

5201 elog(trace_level, "%d KnownAssignedXids (num=%d tail=%d head=%d) %s",

5202 nxids,

5206 buf.data);

5207

5209}

5210

5211

5212

5213

5214

5215static void

5217{

5219

5221

5225

5227}

bool has_privs_of_role(Oid member, Oid role)

static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)

#define pg_read_barrier()

#define pg_write_barrier()

static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)

static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)

static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)

TimestampTz GetCurrentTimestamp(void)

#define FLEXIBLE_ARRAY_MEMBER

#define OidIsValid(objectId)

bool IsCatalogRelation(Relation relation)

#define fprintf(file, fmt, msg)

int errdetail(const char *fmt,...)

int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define palloc_array(type, count)

Assert(PointerIsAligned(start, uint64))

List * lappend_int(List *list, int datum)

#define VirtualTransactionIdIsValid(vxid)

#define GET_VXID_FROM_PGPROC(vxid_dst, proc)

#define InvalidLocalTransactionId

#define VirtualTransactionIdEquals(vxid1, vxid2)

char * get_database_name(Oid dbid)

bool LWLockHeldByMe(LWLock *lock)

bool LWLockAcquire(LWLock *lock, LWLockMode mode)

bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)

void LWLockRelease(LWLock *lock)

bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)

void pfree(void *pointer)

#define AmStartupProcess()

#define IsBootstrapProcessingMode()

#define CHECK_FOR_INTERRUPTS()

static bool pg_lfind32(uint32 key, const uint32 *base, uint32 nelem)

static char buf[DEFAULT_XLOG_SEG_SIZE]

#define qsort(a, b, c, d)

void PGSemaphoreUnlock(PGSemaphore sema)

void PGSemaphoreLock(PGSemaphore sema)

#define PROC_IN_LOGICAL_DECODING

#define NUM_AUXILIARY_PROCS

#define DELAY_CHKPT_IN_COMMIT

#define PROC_AFFECTS_ALL_HORIZONS

#define GetPGProcByNumber(n)

#define GetNumberFromPGProc(proc)

#define PROC_VACUUM_STATE_MASK

#define PROC_IS_AUTOVACUUM

@ KAX_STARTUP_PROCESS_IDLE

static GlobalVisState GlobalVisDataRels

bool GlobalVisTestIsRemovableFullXid(GlobalVisState *state, FullTransactionId fxid)

TransactionId GetOldestNonRemovableTransactionId(Relation rel)

#define TOTAL_MAX_CACHED_SUBXIDS

static GlobalVisState GlobalVisSharedRels

void ProcArrayGetReplicationSlotXmin(TransactionId *xmin, TransactionId *catalog_xmin)

static GlobalVisState GlobalVisCatalogRels

VirtualTransactionId * GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, int *nvxids)

bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid)

bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)

static void KnownAssignedXidsCompress(KAXCompressReason reason, bool haveLock)

pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)

Size ProcArrayShmemSize(void)

TransactionId GetOldestSafeDecodingTransactionId(bool catalogOnly)

void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)

static FullTransactionId FullXidRelativeTo(FullTransactionId rel, TransactionId xid)

bool MinimumActiveBackends(int min)

void TerminateOtherDBBackends(Oid databaseId)

#define xc_no_overflow_inc()

static TransactionId standbySnapshotPendingXmin

void ExpireAllKnownAssignedTransactionIds(void)

#define UINT32_ACCESS_ONCE(var)

RunningTransactions GetRunningTransactionData(void)

static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids, TransactionId *subxids)

static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, TransactionId xmax)

#define xc_by_recent_xmin_inc()

void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)

void ProcNumberGetTransactionIds(ProcNumber procNumber, TransactionId *xid, TransactionId *xmin, int *nsubxid, bool *overflowed)

void RecordKnownAssignedTransactionIds(TransactionId xid)

static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax)

TransactionId GetOldestTransactionIdConsideredRunning(void)

static TransactionId latestObservedXid

static ProcArrayStruct * procArray

int GetMaxSnapshotSubxidCount(void)

int CountDBConnections(Oid databaseid)

static GlobalVisState GlobalVisTempRels

#define xc_by_my_xact_inc()

#define xc_by_known_assigned_inc()

struct ProcArrayStruct ProcArrayStruct

void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)

#define PROCARRAY_MAXPROCS

void GetReplicationHorizons(TransactionId *xmin, TransactionId *catalog_xmin)

static bool GlobalVisTestShouldUpdate(GlobalVisState *state)

static void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)

static void KnownAssignedXidsRemovePreceding(TransactionId removeXid)

void ProcArrayAdd(PGPROC *proc)

struct ComputeXidHorizonsResult ComputeXidHorizonsResult

static TransactionId * KnownAssignedXids

#define xc_by_child_xid_inc()

pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)

Snapshot GetSnapshotData(Snapshot snapshot)

static bool * KnownAssignedXidsValid

bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)

static void KnownAssignedXidsRemove(TransactionId xid)

void KnownAssignedTransactionIdsIdleMaintenance(void)

static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons)

int GetMaxSnapshotXidCount(void)

int CountDBBackends(Oid databaseid)

PGPROC * BackendPidGetProcWithLock(int pid)

bool GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)

PGPROC * BackendPidGetProc(int pid)

bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)

PGPROC * ProcNumberGetProc(ProcNumber procNumber)

#define KAX_COMPRESS_FREQUENCY

GlobalVisState * GlobalVisTestFor(Relation rel)

static TransactionId KnownAssignedXidsGetOldestXmin(void)

void ProcArrayApplyRecoveryInfo(RunningTransactions running)

void ProcArrayClearTransaction(PGPROC *proc)

int CountUserBackends(Oid roleid)

static TransactionId ComputeXidHorizonsResultLastXmin

static void GlobalVisUpdate(void)

#define xc_slow_answer_inc()

static void KnownAssignedXidsDisplay(int trace_level)

#define xc_by_main_xid_inc()

static void MaintainLatestCompletedXidRecovery(TransactionId latestXid)

static void ComputeXidHorizons(ComputeXidHorizonsResult *h)

void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)

static bool KnownAssignedXidExists(TransactionId xid)

TransactionId GetOldestActiveTransactionId(bool inCommitOnly, bool allDbs)

void ProcArrayShmemInit(void)

bool CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)

int BackendXidGetPid(TransactionId xid)

#define xc_by_latest_xid_inc()

bool IsBackendPid(int pid)

#define xc_by_known_xact_inc()

static bool KnownAssignedXidsSearch(TransactionId xid, bool remove)

static void KnownAssignedXidsReset(void)

static GlobalVisHorizonKind GlobalVisHorizonKindForRel(Relation rel)

void ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin, bool already_locked)

void ProcArrayInitRecovery(TransactionId initializedUptoXID)

void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)

#define KAX_COMPRESS_IDLE_INTERVAL

VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)

static void MaintainLatestCompletedXid(TransactionId latestXid)

static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)

void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)

VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)

static TransactionId cachedXidIsNotInProgress

bool ProcArrayInstallImportedXmin(TransactionId xmin, VirtualTransactionId *sourcevxid)

static bool GetSnapshotDataReuse(Snapshot snapshot)

static void KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, bool exclusive_lock)

bool TransactionIdIsInProgress(TransactionId xid)

void ExpireOldKnownAssignedTransactionIds(TransactionId xid)

#define INVALID_PROC_NUMBER

int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)

#define RELATION_IS_LOCAL(relation)

#define RelationIsAccessibleInLogicalDecoding(relation)

Size add_size(Size s1, Size s2)

Size mul_size(Size s1, Size s2)

void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)

void pg_usleep(long microsec)

TransactionId TransactionXmin

void StandbyReleaseOldLocks(TransactionId oldxid)

void appendStringInfo(StringInfo str, const char *fmt,...)

void initStringInfo(StringInfo str)

TransactionId slot_catalog_xmin

TransactionId data_oldest_nonremovable

TransactionId temp_oldest_nonremovable

TransactionId shared_oldest_nonremovable

TransactionId oldest_considered_running

FullTransactionId latest_completed

TransactionId catalog_oldest_nonremovable

TransactionId shared_oldest_nonremovable_raw

FullTransactionId definitely_needed

FullTransactionId maybe_needed

bool procArrayGroupMember

pg_atomic_uint32 procArrayGroupNext

bool recoveryConflictPending

XidCacheStatus subxidStatus

TransactionId procArrayGroupMemberXid

XidCacheStatus * subxidStates

pg_atomic_uint32 procArrayGroupFirst

TransactionId replication_slot_xmin

TransactionId replication_slot_catalog_xmin

int pgprocnos[FLEXIBLE_ARRAY_MEMBER]

TransactionId lastOverflowedXid

int tailKnownAssignedXids

int headKnownAssignedXids

TransactionId oldestRunningXid

TransactionId oldestDatabaseRunningXid

TransactionId latestCompletedXid

subxids_array_status subxid_status

uint64 snapXactCompletionCount

FullTransactionId latestCompletedXid

FullTransactionId nextXid

uint64 xactCompletionCount

LocalTransactionId localTransactionId

TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]

void SubTransSetParent(TransactionId xid, TransactionId parent)

TransactionId SubTransGetTopmostTransaction(TransactionId xid)

void ExtendSUBTRANS(TransactionId newestXact)

bool superuser_arg(Oid roleid)

TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)

bool TransactionIdDidCommit(TransactionId transactionId)

bool TransactionIdDidAbort(TransactionId transactionId)

static bool TransactionIdFollows(TransactionId id1, TransactionId id2)

#define FullTransactionIdIsNormal(x)

static FullTransactionId FullTransactionIdNewer(FullTransactionId a, FullTransactionId b)

#define TransactionIdRetreat(dest)

#define InvalidTransactionId

static void FullTransactionIdRetreat(FullTransactionId *dest)

#define U64FromFullTransactionId(x)

static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)

static FullTransactionId FullTransactionIdFromU64(uint64 value)

#define FullTransactionIdFollowsOrEquals(a, b)

static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)

#define AssertTransactionIdInAllowableRange(xid)

#define TransactionIdEquals(id1, id2)

#define NormalTransactionIdPrecedes(id1, id2)

#define XidFromFullTransactionId(x)

static void FullTransactionIdAdvance(FullTransactionId *dest)

#define TransactionIdIsValid(xid)

#define TransactionIdIsNormal(xid)

#define TransactionIdAdvance(dest)

#define FullTransactionIdPrecedes(a, b)

#define FullTransactionIdIsValid(x)

static TransactionId TransactionIdOlder(TransactionId a, TransactionId b)

static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)

bool StandbyTransactionIdIsPrepared(TransactionId xid)

#define TimestampTzPlusMilliseconds(tz, ms)

void AdvanceNextFullTransactionIdPastXid(TransactionId xid)

TransamVariablesData * TransamVariables

static void pgstat_report_wait_start(uint32 wait_event_info)

static void pgstat_report_wait_end(void)

bool TransactionIdIsCurrentTransactionId(TransactionId xid)

CommandId GetCurrentCommandId(bool used)

int xidLogicalComparator(const void *arg1, const void *arg2)

bool RecoveryInProgress(void)

HotStandbyState standbyState

@ STANDBY_SNAPSHOT_PENDING