PostgreSQL Source Code: src/include/storage/lock.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef LOCK_H_

15#define LOCK_H_

16

17#ifdef FRONTEND

18#error "lock.h may not be included from frontend code"

19#endif

20

27

28

30

31

34

35#ifdef LOCK_DEBUG

41#endif

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60typedef struct

61{

65

66#define InvalidLocalTransactionId 0

67#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)

68#define VirtualTransactionIdIsValid(vxid) \

69 (LocalTransactionIdIsValid((vxid).localTransactionId))

70#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \

71 ((vxid).procNumber == INVALID_PROC_NUMBER)

72#define VirtualTransactionIdEquals(vxid1, vxid2) \

73 ((vxid1).procNumber == (vxid2).procNumber && \

74 (vxid1).localTransactionId == (vxid2).localTransactionId)

75#define SetInvalidVirtualTransactionId(vxid) \

76 ((vxid).procNumber = INVALID_PROC_NUMBER, \

77 (vxid).localTransactionId = InvalidLocalTransactionId)

78#define GET_VXID_FROM_PGPROC(vxid_dst, proc) \

79 ((vxid_dst).procNumber = (proc).vxid.procNumber, \

80 (vxid_dst).localTransactionId = (proc).vxid.lxid)

81

82

83#define MAX_LOCKMODES 10

84

85#define LOCKBIT_ON(lockmode) (1 << (lockmode))

86#define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

110{

116

118

119

120

121

122

124

125

126#define DEFAULT_LOCKMETHOD 1

127#define USER_LOCKMETHOD 2

128

129

130

131

132

133

134

135

137{

150

152

153#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION

154

156

157

158

159

160

161

162

163

164

166{

174

175

176

177

178

179

180

181

182#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \

183 ((locktag).locktag_field1 = (dboid), \

184 (locktag).locktag_field2 = (reloid), \

185 (locktag).locktag_field3 = 0, \

186 (locktag).locktag_field4 = 0, \

187 (locktag).locktag_type = LOCKTAG_RELATION, \

188 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

189

190

191#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \

192 ((locktag).locktag_field1 = (dboid), \

193 (locktag).locktag_field2 = (reloid), \

194 (locktag).locktag_field3 = 0, \

195 (locktag).locktag_field4 = 0, \

196 (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \

197 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

198

199

200#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \

201 ((locktag).locktag_field1 = (dboid), \

202 (locktag).locktag_field2 = 0, \

203 (locktag).locktag_field3 = 0, \

204 (locktag).locktag_field4 = 0, \

205 (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \

206 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

207

208

209#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \

210 ((locktag).locktag_field1 = (dboid), \

211 (locktag).locktag_field2 = (reloid), \

212 (locktag).locktag_field3 = (blocknum), \

213 (locktag).locktag_field4 = 0, \

214 (locktag).locktag_type = LOCKTAG_PAGE, \

215 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

216

217

218#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \

219 ((locktag).locktag_field1 = (dboid), \

220 (locktag).locktag_field2 = (reloid), \

221 (locktag).locktag_field3 = (blocknum), \

222 (locktag).locktag_field4 = (offnum), \

223 (locktag).locktag_type = LOCKTAG_TUPLE, \

224 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

225

226

227#define SET_LOCKTAG_TRANSACTION(locktag,xid) \

228 ((locktag).locktag_field1 = (xid), \

229 (locktag).locktag_field2 = 0, \

230 (locktag).locktag_field3 = 0, \

231 (locktag).locktag_field4 = 0, \

232 (locktag).locktag_type = LOCKTAG_TRANSACTION, \

233 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

234

235

236#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \

237 ((locktag).locktag_field1 = (vxid).procNumber, \

238 (locktag).locktag_field2 = (vxid).localTransactionId, \

239 (locktag).locktag_field3 = 0, \

240 (locktag).locktag_field4 = 0, \

241 (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \

242 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

243

244

245

246

247

248#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \

249 ((locktag).locktag_field1 = (xid), \

250 (locktag).locktag_field2 = (token), \

251 (locktag).locktag_field3 = 0, \

252 (locktag).locktag_field4 = 0, \

253 (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \

254 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

255

256

257

258

259

260

261

262

263#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \

264 ((locktag).locktag_field1 = (dboid), \

265 (locktag).locktag_field2 = (classoid), \

266 (locktag).locktag_field3 = (objoid), \

267 (locktag).locktag_field4 = (objsubid), \

268 (locktag).locktag_type = LOCKTAG_OBJECT, \

269 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

270

271#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \

272 ((locktag).locktag_field1 = (id1), \

273 (locktag).locktag_field2 = (id2), \

274 (locktag).locktag_field3 = (id3), \

275 (locktag).locktag_field4 = (id4), \

276 (locktag).locktag_type = LOCKTAG_ADVISORY, \

277 (locktag).locktag_lockmethodid = USER_LOCKMETHOD)

278

279

280

281

282

283#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \

284 ((locktag).locktag_field1 = (dboid), \

285 (locktag).locktag_field2 = (suboid), \

286 (locktag).locktag_field3 = (xid), \

287 (locktag).locktag_field4 = (objid), \

288 (locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \

289 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

310{

311

312 LOCKTAG tag;

313

314

322 int nGranted;

324

325#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)

326#define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type)

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

364{

365

366 LOCK *myLock;

369

371{

372

374

375

382

383#define PROCLOCK_LOCKMETHOD(proclock) \

384 LOCK_LOCKMETHOD(*((proclock).tag.myLock))

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

410{

414

416{

417

418

419

420

421

422

426

428{

429

431

432

434 LOCK *lock;

436 int64 nLocks;

441 bool lockCleared;

443

444#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)

445#define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)

446

447

448

449

450

451

452

454{

460

461 int pid;

462 int leaderPid;

465

467{

471

473{

474 int pid;

475

476

477 int first_lock;

478 int num_locks;

479

480

484

486{

489 int *waiter_pids;

490 int nprocs;

491 int maxprocs;

492 int nlocks;

493 int maxlocks;

494 int npids;

495 int maxpids;

497

498

499

500typedef enum

501{

507

508

509typedef enum

510{

516

518

519

520

521

522

523

524

525#define LockHashPartition(hashcode) \

526 ((hashcode) % NUM_LOCK_PARTITIONS)

527#define LockHashPartitionLock(hashcode) \

528 (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \

529 LockHashPartition(hashcode)].lock)

530#define LockHashPartitionLockByIndex(i) \

531 (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)

532

533

534

535

536

537

538

539

540

541

542#define LockHashPartitionLockByProc(leader_pgproc) \

543 LockHashPartitionLock(GetNumberFromPGProc(leader_pgproc))

544

545

546

547

557 bool sessionLock,

558 bool dontWait);

561 bool sessionLock,

562 bool dontWait,

563 bool reportMemoryError,

565 bool logLockFailure);

569 LOCKMODE lockmode, bool sessionLock);

575 LOCKMODE lockmode, bool orstronger);

576#ifdef USE_ASSERT_CHECKING

577extern HTAB *GetLockMethodLocalHash(void);

578#endif

580 LOCKMODE lockmode, bool sessionLock);

582 LOCKMODE lockmode, int *countp);

592

596

599

608

617

619

620#ifdef LOCK_DEBUG

621extern void DumpLocks(PGPROC *proc);

622extern void DumpAllLocks(void);

623#endif

624

625

629

630#endif

uint32 LocalTransactionId

LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)

bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode, bool orstronger)

PGDLLIMPORT int max_locks_per_xact

bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2)

struct LOCALLOCK LOCALLOCK

const LockMethodData * LockMethod

void VirtualXactLockTableInsert(VirtualTransactionId vxid)

PGPROC * GetBlockingAutoVacuumPgproc(void)

@ LOCKTAG_RELATION_EXTEND

@ LOCKTAG_SPECULATIVE_TOKEN

@ LOCKTAG_APPLY_TRANSACTION

@ LOCKTAG_DATABASE_FROZEN_IDS

@ LOCKTAG_VIRTUALTRANSACTION

void GrantAwaitedLock(void)

int LockWaiterCount(const LOCKTAG *locktag)

void AtPrepare_Locks(void)

bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)

void lock_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len)

Size LockManagerShmemSize(void)

void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)

struct LOCALLOCKOWNER LOCALLOCKOWNER

void InitLockManagerAccess(void)

void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)

void VirtualXactLockTableCleanup(void)

bool VirtualXactLock(VirtualTransactionId vxid, bool wait)

VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)

void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)

LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp, bool logLockFailure)

void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)

struct LockMethodData LockMethodData

void ResetAwaitedLock(void)

void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)

struct BlockedProcData BlockedProcData

void AbortStrongLockAcquire(void)

@ DS_BLOCKED_BY_AUTOVACUUM

struct LockInstanceData LockInstanceData

BlockedProcsData * GetBlockerStatusData(int blocked_pid)

void LockManagerShmemInit(void)

void lock_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len)

bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)

const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)

struct PROCLOCKTAG PROCLOCKTAG

PGDLLIMPORT const char *const LockTagTypeNames[]

void lock_twophase_standby_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)

void InitDeadLockChecking(void)

void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)

LOCALLOCK * GetAwaitedLock(void)

void lock_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)

void LockReleaseSession(LOCKMETHODID lockmethodid)

void MarkLockClear(LOCALLOCK *locallock)

LockData * GetLockStatusData(void)

DeadLockState DeadLockCheck(PGPROC *proc)

uint32 LockTagHashCode(const LOCKTAG *locktag)

bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)

pg_noreturn void DeadLockReport(void)

struct LOCALLOCKTAG LOCALLOCKTAG

PGDLLIMPORT bool log_lock_failure

LockMethod GetLocksMethodTable(const LOCK *lock)

void PostPrepare_Locks(TransactionId xid)

@ LOCKACQUIRE_ALREADY_CLEAR

@ LOCKACQUIRE_ALREADY_HELD

struct BlockedProcsData BlockedProcsData

xl_standby_lock * GetRunningTransactionLocks(int *nlocks)

LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)

static PgChecksumMode mode

struct ResourceOwnerData * owner

LOCALLOCKOWNER * lockOwners

bool holdsStrongLockCount

uint8 locktag_lockmethodid

int requested[MAX_LOCKMODES]

int granted[MAX_LOCKMODES]

VirtualTransactionId vxid

const LOCKMASK * conflictTab

const char *const * lockModeNames

LocalTransactionId localTransactionId