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

1633bool

1635{

1636 bool result = false;

1639 int i;

1640

1641

1642

1643

1644

1646 return false;

1647

1649

1651 {

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

1655

1656

1658

1660 continue;

1661

1662 if (proc->pid == 0)

1663 continue;

1664

1666 {

1667 result = true;

1668 break;

1669 }

1670 }

1671

1673

1674 return result;

1675}

1676

1677

1678

1679

1680

1681

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700

1701

1702

1703

1704

1705

1706

1707

1708

1709

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723

1724

1725

1726

1727

1728

1729

1730

1731

1732

1733

1734static void

1736{

1741

1742

1744

1746

1748

1749

1750

1751

1752

1753

1754

1755 {

1757

1761

1765

1766

1767

1768

1769

1770

1771

1772

1773

1774

1775

1776

1777

1780 else

1782 }

1783

1784

1785

1786

1787

1788

1791

1793 {

1799

1800

1803

1804

1805

1806

1807

1808

1809

1810

1812

1813

1815 continue;

1816

1817

1818

1819

1820

1821

1822

1825

1826

1827

1828

1829

1830

1832 continue;

1833

1834

1837

1838

1839

1840

1841

1842

1843

1844

1845

1846

1847

1848

1849

1850

1851

1852

1853

1854

1855

1856

1860 in_recovery)

1861 {

1864 }

1865 }

1866

1867

1868

1869

1870

1871 if (in_recovery)

1873

1874

1875

1876

1877

1879

1880 if (in_recovery)

1881 {

1888

1889 }

1890

1895

1896

1897

1898

1903

1904

1905

1906

1907

1908

1909

1910

1919

1920

1921

1922

1923

1933

1934

1935

1936

1937

1942

1943

1944

1945

1946

1961

1962

1964}

1965

1966

1967

1968

1969

1972{

1973

1974

1975

1976

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

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

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

1981

1989 else

1991}

1992

1993

1994

1995

1996

1997

1998

1999

2000

2001

2002

2003

2006{

2008

2010

2012 {

2021 }

2022

2023

2025}

2026

2027

2028

2029

2030

2031

2032

2035{

2037

2039

2041}

2042

2043

2044

2045

2046void

2048{

2050

2052

2053

2054

2055

2056

2057

2058

2061}

2062

2063

2064

2065

2066

2067

2068int

2070{

2072}

2073

2074

2075

2076

2077

2078

2079int

2081{

2083}

2084

2085

2086

2087

2088

2089

2090

2091

2092

2093

2094static bool

2096{

2097 uint64 curXactCompletionCount;

2098

2100

2102 return false;

2103

2106 return false;

2107

2108

2109

2110

2111

2112

2113

2114

2115

2116

2117

2118

2119

2120

2121

2122

2123

2124

2125

2126

2127

2130

2133

2137 snapshot->copied = false;

2138

2139 return true;

2140}

2141

2142

2143

2144

2145

2146

2147

2148

2149

2150

2151

2152

2153

2154

2155

2156

2157

2158

2159

2160

2161

2162

2163

2164

2165

2166

2167

2168

2169

2170

2171

2172

2173

2176{

2181 int count = 0;

2182 int subcount = 0;

2183 bool suboverflowed = false;

2186 int mypgxactoff;

2188 uint64 curXactCompletionCount;

2189

2192

2193 Assert(snapshot != NULL);

2194

2195

2196

2197

2198

2199

2200

2201

2202

2203

2204

2205

2206 if (snapshot->xip == NULL)

2207 {

2208

2209

2210

2211

2214 if (snapshot->xip == NULL)

2216 (errcode(ERRCODE_OUT_OF_MEMORY),

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

2221 if (snapshot->subxip == NULL)

2223 (errcode(ERRCODE_OUT_OF_MEMORY),

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

2225 }

2226

2227

2228

2229

2230

2232

2234 {

2236 return snapshot;

2237 }

2238

2241 myxid = other_xids[mypgxactoff];

2243

2246

2247

2251

2252

2253 xmin = xmax;

2254

2255

2257 xmin = myxid;

2258

2260

2262 {

2263 int numProcs = arrayP->numProcs;

2265 int *pgprocnos = arrayP->pgprocnos;

2268

2269

2270

2271

2272

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

2274 {

2275

2277 uint8 statusFlags;

2278

2280

2281

2282

2283

2284

2286 continue;

2287

2288

2289

2290

2291

2292

2293 if (pgxactoff == mypgxactoff)

2294 continue;

2295

2296

2297

2298

2299

2300

2301

2303

2304

2305

2306

2307

2308

2310 continue;

2311

2312

2313

2314

2315

2316 statusFlags = allStatusFlags[pgxactoff];

2318 continue;

2319

2321 xmin = xid;

2322

2323

2324 xip[count++] = xid;

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337

2338

2339

2340

2341 if (!suboverflowed)

2342 {

2343

2344 if (subxidStates[pgxactoff].overflowed)

2345 suboverflowed = true;

2346 else

2347 {

2348 int nsubxids = subxidStates[pgxactoff].count;

2349

2350 if (nsubxids > 0)

2351 {

2352 int pgprocno = pgprocnos[pgxactoff];

2354

2356

2357 memcpy(snapshot->subxip + subcount,

2360 subcount += nsubxids;

2361 }

2362 }

2363 }

2364 }

2365 }

2366 else

2367 {

2368

2369

2370

2371

2372

2373

2374

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388

2389

2390

2391

2392

2393

2394

2395

2396

2398 xmax);

2399

2401 suboverflowed = true;

2402 }

2403

2404

2405

2406

2407

2408

2409

2412

2415

2417

2418

2419 {

2425

2426

2427

2428

2429

2430

2432

2433

2434 def_vis_xid_data =

2436

2437

2438

2439

2440

2441 def_vis_xid = def_vis_xid_data;

2442

2443

2444

2445

2446

2447 def_vis_xid =

2449

2450 def_vis_fxid = FullXidRelativeTo(latest_completed, def_vis_xid);

2451 def_vis_fxid_data = FullXidRelativeTo(latest_completed, def_vis_xid_data);

2452

2453

2454

2455

2456

2457

2467

2471 else

2472 {

2475 }

2476

2477

2478

2479

2480

2481

2482

2483

2484

2487 oldestfxid);

2490 oldestfxid);

2493 oldestfxid);

2494

2496 }

2497

2500

2501 snapshot->xmin = xmin;

2502 snapshot->xmax = xmax;

2503 snapshot->xcnt = count;

2504 snapshot->subxcnt = subcount;

2507

2509

2510

2511

2512

2513

2516 snapshot->copied = false;

2517

2518 return snapshot;

2519}

2520

2521

2522

2523

2524

2525

2526

2527

2528

2529

2530

2531bool

2534{

2535 bool result = false;

2538

2540 if (!sourcevxid)

2541 return false;

2542

2543

2545

2546

2547

2548

2549

2550

2552 {

2557

2558

2560 continue;

2561

2562

2564 continue;

2566 continue;

2567

2568

2569

2570

2571

2572

2573

2575 continue;

2576

2577

2578

2579

2583 continue;

2584

2585

2586

2587

2588

2589

2590

2592

2593 result = true;

2594 break;

2595 }

2596

2598

2599 return result;

2600}

2601

2602

2603

2604

2605

2606

2607

2608

2609

2610

2611

2612

2613

2614

2615bool

2617{

2618 bool result = false;

2620

2622 Assert(proc != NULL);

2623

2624

2625

2626

2628

2629

2630

2631

2632

2633

2634

2639 {

2640

2641

2642

2643

2648

2649 result = true;

2650 }

2651

2653

2654 return result;

2655}

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677

2678

2679

2680

2681

2682

2683

2684

2685

2686

2687

2690{

2691

2693

2702 int count;

2703 int subcount;

2704 bool suboverflowed;

2705

2707

2708

2709

2710

2711

2712

2713

2714

2715

2716

2717 if (CurrentRunningXacts->xids == NULL)

2718 {

2719

2720

2721

2724 if (CurrentRunningXacts->xids == NULL)

2726 (errcode(ERRCODE_OUT_OF_MEMORY),

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

2728 }

2729

2730 xids = CurrentRunningXacts->xids;

2731

2732 count = subcount = 0;

2733 suboverflowed = false;

2734

2735

2736

2737

2738

2741

2742 latestCompletedXid =

2744 oldestDatabaseRunningXid = oldestRunningXid =

2746

2747

2748

2749

2751 {

2753

2754

2756

2757

2758

2759

2760

2762 continue;

2763

2764

2765

2766

2767

2768

2770 oldestRunningXid = xid;

2771

2772

2773

2774

2775

2776

2778 {

2781

2783 oldestDatabaseRunningXid = xid;

2784 }

2785

2787 suboverflowed = true;

2788

2789

2790

2791

2792

2793

2794

2795

2796

2797 xids[count++] = xid;

2798 }

2799

2800

2801

2802

2803

2804 if (!suboverflowed)

2805 {

2807

2809 {

2812 int nsubxids;

2813

2814

2815

2816

2817

2818 nsubxids = other_subxidstates[index].count;

2819 if (nsubxids > 0)

2820 {

2821

2823

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

2826 count += nsubxids;

2827 subcount += nsubxids;

2828

2829

2830

2831

2832

2833

2834 }

2835 }

2836 }

2837

2838

2839

2840

2841

2842

2843

2844

2845

2846

2847 CurrentRunningXacts->xcnt = count - subcount;

2848 CurrentRunningXacts->subxcnt = subcount;

2854

2858

2859

2860

2861 return CurrentRunningXacts;

2862}

2863

2864

2865

2866

2867

2868

2869

2870

2871

2872

2873

2874

2875

2876

2877

2878

2881{

2886

2888

2889

2890

2891

2892

2893

2894

2895

2899

2900

2901

2902

2905 {

2907

2908

2910

2912 continue;

2913

2915 oldestRunningXid = xid;

2916

2917

2918

2919

2920

2921

2922 }

2924

2925 return oldestRunningXid;

2926}

2927

2928

2929

2930

2931

2932

2933

2934

2935

2936

2937

2938

2939

2940

2941

2942

2943

2946{

2951

2953

2954

2955

2956

2957

2958

2959

2960

2961

2964

2965

2966

2967

2968

2969

2970

2971

2974 oldestSafeXid))

2976

2977 if (catalogOnly &&

2980 oldestSafeXid))

2982

2983

2984

2985

2986

2987

2988

2989

2990

2991

2992

2993

2994

2995 if (!recovery_in_progress)

2996 {

2998

2999

3000

3001

3003 {

3005

3006

3008

3010 continue;

3011

3013 oldestSafeXid = xid;

3014 }

3015 }

3016

3018

3019 return oldestSafeXid;

3020}

3021

3022

3023

3024

3025

3026

3027

3028

3029

3030

3031

3032

3033

3034

3035

3036

3037

3038

3039

3040

3041

3044{

3047 int count = 0;

3049

3051

3052

3055

3057

3059 {

3062

3064 {

3066

3069 vxids[count++] = vxid;

3070 }

3071 }

3072

3074

3075 *nvxids = count;

3076 return vxids;

3077}

3078

3079

3080

3081

3082

3083

3084

3085

3086

3087

3088bool

3090{

3091 bool result = false;

3094

3096

3098

3100 {

3104

3106

3109 {

3110 int i;

3111

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

3113 {

3115 {

3116 result = true;

3117 break;

3118 }

3119 }

3120 if (result)

3121 break;

3122 }

3123 }

3124

3126

3127 return result;

3128}

3129

3130

3131

3132

3133

3134

3135

3136

3139{

3141

3143 return NULL;

3145

3146 if (result->pid == 0)

3147 return NULL;

3148

3149 return result;

3150}

3151

3152

3153

3154

3155

3156

3157

3158

3159void

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

3162{

3164

3167 *nsubxid = 0;

3168 *overflowed = false;

3169

3171 return;

3173

3174

3176

3177 if (proc->pid != 0)

3178 {

3179 *xid = proc->xid;

3180 *xmin = proc->xmin;

3183 }

3184

3186}

3187

3188

3189

3190

3191

3192

3193

3194

3197{

3199

3200 if (pid == 0)

3201 return NULL;

3202

3204

3206

3208

3209 return result;

3210}

3211

3212

3213

3214

3215

3216

3217

3220{

3221 PGPROC *result = NULL;

3224

3225 if (pid == 0)

3226 return NULL;

3227

3229 {

3231

3232 if (proc->pid == pid)

3233 {

3234 result = proc;

3235 break;

3236 }

3237 }

3238

3239 return result;

3240}

3241

3242

3243

3244

3245

3246

3247

3248

3249

3250

3251

3252

3253

3254

3255int

3257{

3258 int result = 0;

3262

3264 return 0;

3265

3267

3269 {

3270 if (other_xids[index] == xid)

3271 {

3274

3275 result = proc->pid;

3276 break;

3277 }

3278 }

3279

3281

3282 return result;

3283}

3284

3285

3286

3287

3288

3289

3290bool

3292{

3294}

3295

3296

3297

3298

3299

3300

3301

3302

3303

3304

3305

3306

3307

3308

3309

3310

3311

3312

3313

3314

3315

3316

3317

3318

3319

3320

3321

3322

3325 bool allDbs, int excludeVacuum,

3326 int *nvxids)

3327{

3330 int count = 0;

3332

3333

3336

3338

3340 {

3344

3346 continue;

3347

3348 if (excludeVacuum & statusFlags)

3349 continue;

3350

3352 {

3353

3355

3357 continue;

3358

3359

3360

3361

3362

3365 {

3367

3370 vxids[count++] = vxid;

3371 }

3372 }

3373 }

3374

3376

3377 *nvxids = count;

3378 return vxids;

3379}

3380

3381

3382

3383

3384

3385

3386

3387

3388

3389

3390

3391

3392

3393

3394

3395

3396

3397

3398

3399

3400

3401

3402

3403

3404

3405

3406

3407

3408

3409

3410

3411

3412

3413

3414

3415

3418{

3421 int count = 0;

3423

3424

3425

3426

3427

3428

3429 if (vxids == NULL)

3430 {

3433 if (vxids == NULL)

3435 (errcode(ERRCODE_OUT_OF_MEMORY),

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

3437 }

3438

3440

3442 {

3445

3446

3447 if (proc->pid == 0)

3448 continue;

3449

3452 {

3453

3455

3456

3457

3458

3459

3460

3461

3462

3463

3466 {

3468

3471 vxids[count++] = vxid;

3472 }

3473 }

3474 }

3475

3477

3478

3481

3482 return vxids;

3483}

3484

3485

3486

3487

3488

3489

3490pid_t

3492{

3494}

3495

3496pid_t

3498 bool conflictPending)

3499{

3502 pid_t pid = 0;

3503

3505

3507 {

3511

3513

3516 {

3518 pid = proc->pid;

3519 if (pid != 0)

3520 {

3521

3522

3523

3524

3526 }

3527 break;

3528 }

3529 }

3530

3532

3533 return pid;

3534}

3535

3536

3537

3538

3539

3540

3541

3542

3543

3544

3545bool

3547{

3549 int count = 0;

3551

3552

3553 if (min == 0)

3554 return true;

3555

3556

3557

3558

3559

3560

3562 {

3565

3566

3567

3568

3569

3570

3571

3572

3573

3574

3575

3576

3577 if (pgprocno == -1)

3578 continue;

3580 continue;

3582 continue;

3583 if (proc->pid == 0)

3584 continue;

3586 continue;

3587 count++;

3588 if (count >= min)

3589 break;

3590 }

3591

3592 return count >= min;

3593}

3594

3595

3596

3597

3598int

3600{

3602 int count = 0;

3604

3606

3608 {

3611

3612 if (proc->pid == 0)

3613 continue;

3616 count++;

3617 }

3618

3620

3621 return count;

3622}

3623

3624

3625

3626

3627int

3629{

3631 int count = 0;

3633

3635

3637 {

3640

3641 if (proc->pid == 0)

3642 continue;

3644 continue;

3647 count++;

3648 }

3649

3651

3652 return count;

3653}

3654

3655

3656

3657

3658void

3660{

3663

3664

3666

3668 {

3671

3673 {

3675 pid_t pid;

3676

3678

3680 pid = proc->pid;

3681 if (pid != 0)

3682 {

3683

3684

3685

3686

3688 }

3689 }

3690 }

3691

3693}

3694

3695

3696

3697

3698

3699int

3701{

3703 int count = 0;

3705

3707

3709 {

3712

3713 if (proc->pid == 0)

3714 continue;

3716 continue;

3717 if (proc->roleId == roleid)

3718 count++;

3719 }

3720

3722

3723 return count;

3724}

3725

3726

3727

3728

3729

3730

3731

3732

3733

3734

3735

3736

3737

3738

3739

3740

3741

3742

3743

3744

3745

3746

3747

3748

3749bool

3751{

3753

3754#define MAXAUTOVACPIDS 10

3756 int tries;

3757

3758

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

3760 {

3761 int nautovacs = 0;

3762 bool found = false;

3764

3766

3767 *nbackends = *nprepared = 0;

3768

3770

3772 {

3776

3778 continue;

3780 continue;

3781

3782 found = true;

3783

3784 if (proc->pid == 0)

3785 (*nprepared)++;

3786 else

3787 {

3788 (*nbackends)++;

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

3792 }

3793 }

3794

3796

3797 if (!found)

3798 return false;

3799

3800

3801

3802

3803

3804

3805

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

3808

3809

3810 pg_usleep(100 * 1000L);

3811 }

3812

3813 return true;

3814}

3815

3816

3817

3818

3819

3820

3821

3822

3823

3824

3825

3826

3827void

3829{

3832 int nprepared = 0;

3833 int i;

3834

3836

3838 {

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

3841

3843 continue;

3845 continue;

3846

3847 if (proc->pid != 0)

3849 else

3850 nprepared++;

3851 }

3852

3854

3855 if (nprepared > 0)

3857 (errcode(ERRCODE_OBJECT_IN_USE),

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

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

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

3862 nprepared,

3863 nprepared)));

3864

3865 if (pids)

3866 {

3868

3869

3870

3871

3872

3873

3874

3875

3876

3877

3878

3879

3880

3881

3882

3883

3884 foreach(lc, pids)

3885 {

3888

3889 if (proc != NULL)

3890 {

3893 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

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

3896 "SUPERUSER", "SUPERUSER")));

3897

3901 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

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

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

3904 "pg_signal_backend")));

3905 }

3906 }

3907

3908

3909

3910

3911

3912

3913

3914 foreach(lc, pids)

3915 {

3918

3919 if (proc != NULL)

3920 {

3921

3922

3923

3924

3925#ifdef HAVE_SETSID

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

3927#else

3928 (void) kill(pid, SIGTERM);

3929#endif

3930 }

3931 }

3932 }

3933}

3934

3935

3936

3937

3938

3939

3940

3941

3942void

3944 bool already_locked)

3945{

3947

3948 if (!already_locked)

3950

3953

3954 if (!already_locked)

3956

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

3958 xmin, catalog_xmin);

3959}

3960

3961

3962

3963

3964

3965

3966

3967void

3970{

3972

3973 if (xmin != NULL)

3975

3976 if (catalog_xmin != NULL)

3978

3980}

3981

3982

3983

3984

3985

3986

3987

3988

3989

3990void

3994{

3995 int i,

3996 j;

3998

4000

4001

4002

4003

4004

4005

4006

4007

4008

4009

4010

4011

4012

4014

4016

4017

4018

4019

4020

4021

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

4023 {

4025

4027 {

4029 {

4032 mysubxidstat->count--;

4034 break;

4035 }

4036 }

4037

4038

4039

4040

4041

4042

4043

4044

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

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

4047 }

4048

4050 {

4052 {

4055 mysubxidstat->count--;

4057 break;

4058 }

4059 }

4060

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

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

4063

4064

4066

4067

4069

4071}

4072

4073#ifdef XIDCACHE_DEBUG

4074

4075

4076

4077

4078static void

4079DisplayXidCache(void)

4080{

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

4083 xc_by_recent_xmin,

4084 xc_by_known_xact,

4085 xc_by_my_xact,

4086 xc_by_latest_xid,

4087 xc_by_main_xid,

4088 xc_by_child_xid,

4089 xc_by_known_assigned,

4090 xc_no_overflow,

4091 xc_slow_answer);

4092}

4093#endif

4094

4095

4096

4097

4098

4099

4100

4101

4102

4103

4104

4105

4108{

4110

4111

4113

4115 {

4118 break;

4121 break;

4124 break;

4127 break;

4128 }

4129

4132

4134}

4135

4136

4137

4138

4139

4140

4141

4142

4143

4144

4145

4146static bool

4148{

4149

4151 return true;

4152

4153

4154

4155

4156

4158 state->definitely_needed))

4159 return false;

4160

4161

4163}

4164

4165static void

4167{

4180

4181

4182

4183

4184

4185

4196

4198}

4199

4200

4201

4202

4203

4204static void

4206{

4208

4209

4211}

4212

4213

4214

4215

4216

4217

4218

4219

4220

4221bool

4224{

4225

4226

4227

4228

4230 return true;

4231

4232

4233

4234

4235

4237 return false;

4238

4239

4240

4241

4242

4243

4245 {

4247

4249

4251 }

4252 else

4253 return false;

4254}

4255

4256

4257

4258

4259

4260

4261

4262

4263bool

4265{

4267

4268

4269

4270

4271

4272

4273

4274

4275

4277

4279}

4280

4281

4282

4283

4284

4285bool

4287{

4289

4291

4293}

4294

4295

4296

4297

4298

4299bool

4301{

4303

4305

4307}

4308

4309

4310

4311

4312

4313

4314

4315

4316

4317

4318

4319

4322{

4324

4327

4328

4330

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

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

4362

4363

4364

4365

4366

4367

4368

4369

4370

4371

4372

4373

4374

4375

4376

4377

4378

4379

4380

4381

4382

4383

4384

4385

4386

4387

4388

4389

4390

4391

4392

4393

4394

4395

4396

4397

4398

4399

4400

4401

4402void

4404{

4408

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

4411

4412

4413

4414

4415

4416

4418 {

4420

4421

4422

4423

4424

4425

4426

4427

4428

4429

4432 {

4435 }

4436 Assert(next_expected_xid == xid);

4437

4438

4439

4440

4441

4443 {

4445 return;

4446 }

4447

4448

4449

4450

4454

4455

4456

4457

4459

4460

4462 }

4463}

4464

4465

4466

4467

4468

4469

4470

4471void

4474{

4476

4477

4478

4479

4481

4483

4484

4486

4487

4489

4491}

4492

4493

4494

4495

4496

4497void

4499{

4501

4504

4505

4510

4511

4512

4513

4514

4516

4517

4518

4519

4520

4521

4524}

4525

4526

4527

4528

4529

4530

4531void

4533{

4535

4537

4538

4539 latestXid = xid;

4542

4543

4545

4546

4547

4548

4549

4550

4551

4556}

4557

4558

4559

4560

4561

4562

4563void

4565{

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

4624

4625

4626

4627

4628

4629

4630

4631

4632

4633

4634

4635

4636

4637

4638

4639

4640

4641

4642

4643

4644

4645

4646

4647

4648

4649

4650

4651

4652

4653

4654

4655

4656

4657

4658

4659

4660

4661

4662

4663

4664static void

4666{

4668 int head,

4669 tail,

4670 nelements;

4671 int compress_index;

4672 int i;

4673

4674

4675 static unsigned int transactionEndsCounter;

4677

4678

4679#define KAX_COMPRESS_FREQUENCY 128

4680#define KAX_COMPRESS_IDLE_INTERVAL 1000

4681

4682

4683

4684

4685

4688 nelements = head - tail;

4689

4690

4691

4692

4693

4694

4695

4697 {

4698

4699

4700

4701

4702

4704 return;

4705 }

4707 {

4708

4709

4710

4711

4713 return;

4714

4715

4716

4717

4718

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

4720 return;

4721 }

4723 {

4724

4725

4726

4727

4728

4729 if (lastCompressTs != 0)

4730 {

4732

4736 return;

4737 }

4738 }

4739

4740

4741 if (!haveLock)

4743

4744

4745

4746

4747

4748 compress_index = 0;

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

4750 {

4752 {

4755 compress_index++;

4756 }

4757 }

4759

4762

4763 if (!haveLock)

4765

4766

4768}

4769

4770

4771

4772

4773

4774

4775

4776

4777

4778

4779

4780

4781static void

4783 bool exclusive_lock)

4784{

4787 int head,

4788 tail;

4789 int nxids;

4790 int i;

4791

4793

4794

4795

4796

4797

4798

4799 if (to_xid >= from_xid)

4800 nxids = to_xid - from_xid + 1;

4801 else

4802 {

4803 nxids = 1;

4804 next_xid = from_xid;

4806 {

4807 nxids++;

4809 }

4810 }

4811

4812

4813

4814

4815

4818

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

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

4821

4822

4823

4824

4825

4826

4827 if (head > tail &&

4829 {

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

4832 }

4833

4834

4835

4836

4838 {

4840

4842

4843

4844

4845

4846

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

4849 }

4850

4851

4852 next_xid = from_xid;

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

4854 {

4858 head++;

4859 }

4860

4861

4863

4864

4865

4866

4867

4868

4869

4870 if (!exclusive_lock)

4872

4874}

4875

4876

4877

4878

4879

4880

4881

4882

4883

4884

4885static bool

4887{

4889 int first,

4890 last;

4891 int head;

4892 int tail;

4893 int result_index = -1;

4894

4897

4898

4899

4900

4901

4902 if (!remove)

4903 pg_read_barrier();

4904

4905

4906

4907

4908

4909 first = tail;

4910 last = head - 1;

4911 while (first <= last)

4912 {

4913 int mid_index;

4915

4916 mid_index = (first + last) / 2;

4918

4919 if (xid == mid_xid)

4920 {

4921 result_index = mid_index;

4922 break;

4923 }

4925 last = mid_index - 1;

4926 else

4927 first = mid_index + 1;

4928 }

4929

4930 if (result_index < 0)

4931 return false;

4932

4934 return false;

4935

4936 if (remove)

4937 {

4939

4942

4943

4944

4945

4946

4947 if (result_index == tail)

4948 {

4949 tail++;

4951 tail++;

4952 if (tail >= head)

4953 {

4954

4957 }

4958 else

4959 {

4961 }

4962 }

4963 }

4964

4965 return true;

4966}

4967

4968

4969

4970

4971

4972

4973static bool

4975{

4977

4979}

4980

4981

4982

4983

4984

4985

4986static void

4988{

4990

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

4992

4993

4994

4995

4996

4997

4998

4999

5000

5001

5002

5004}

5005

5006

5007

5008

5009

5010

5011

5012static void

5015{

5016 int i;

5017

5020

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

5023

5024

5026}

5027

5028

5029

5030

5031

5032

5033

5034static void

5036{

5038 int count = 0;

5039 int head,

5040 tail,

5041 i;

5042

5044 {

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

5048 return;

5049 }

5050

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

5052

5053

5054

5055

5056

5059

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

5061 {

5063 {

5065

5067 break;

5068

5070 {

5072 count++;

5073 }

5074 }

5075 }

5076

5079

5080

5081

5082

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

5084 {

5086 break;

5087 }

5088 if (i >= head)

5089 {

5090

5093 }

5094 else

5095 {

5097 }

5098

5099

5101}

5102

5103

5104

5105

5106

5107

5108

5109

5110

5111

5112static int

5114{

5116

5118}

5119

5120

5121

5122

5123

5124

5125

5126static int

5129{

5130 int count = 0;

5131 int head,

5132 tail;

5133 int i;

5134

5135

5136

5137

5138

5139

5140

5141

5144

5145 pg_read_barrier();

5146

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

5148 {

5149

5151 {

5153

5154

5155

5156

5157

5158 if (count == 0 &&

5160 *xmin = knownXid;

5161

5162

5163

5164

5165

5168 break;

5169

5170

5171 xarray[count++] = knownXid;

5172 }

5173 }

5174

5175 return count;

5176}

5177

5178

5179

5180

5181

5184{

5185 int head,

5186 tail;

5187 int i;

5188

5189

5190

5191

5194

5195 pg_read_barrier();

5196

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

5198 {

5199

5202 }

5203

5205}

5206

5207

5208

5209

5210

5211

5212

5213

5214

5215

5216

5217static void

5219{

5222 int head,

5223 tail,

5224 i;

5225 int nxids = 0;

5226

5229

5231

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

5233 {

5235 {

5236 nxids++;

5238 }

5239 }

5240

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

5242 nxids,

5246 buf.data);

5247

5249}

5250

5251

5252

5253

5254

5255static void

5257{

5259

5261

5265

5267}

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)

char * get_database_name(Oid dbid)

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,...)

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)

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)

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

void PGSemaphoreUnlock(PGSemaphore sema)

void PGSemaphoreLock(PGSemaphore sema)

#define PROC_IN_LOGICAL_DECODING

#define NUM_AUXILIARY_PROCS

#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)

bool TransactionIdIsActive(TransactionId xid)

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)

TransactionId GetOldestActiveTransactionId(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)

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 TransactionIdPrecedes(TransactionId id1, TransactionId id2)

bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)

bool TransactionIdDidAbort(TransactionId transactionId)

bool TransactionIdFollows(TransactionId id1, TransactionId id2)

bool TransactionIdFollowsOrEquals(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 FullTransactionId FullTransactionIdFromU64(uint64 value)

#define FullTransactionIdFollowsOrEquals(a, b)

#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)

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