PostgreSQL Source Code: src/backend/utils/adt/lockfuncs.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
14
21
22
23
24
25
26
27
29 "relation",
30 "extend",
31 "frozenid",
32 "page",
33 "tuple",
34 "transactionid",
35 "virtualxid",
36 "spectoken",
37 "object",
38 "userlock",
39 "advisory",
40 "applytransaction"
41};
42
44 "array length mismatch");
45
46
48 "relation",
49 "page",
50 "tuple"
51};
52
54 "array length mismatch");
55
56
57typedef struct
58{
62 int predLockIdx;
64
65
66#define NUM_LOCK_STATUS_COLUMNS 16
67
68
69
70
71
72
75{
76
77
78
79
80
81 char vxidstr[32];
82
83 snprintf(vxidstr, sizeof(vxidstr), "%d/%u", procNumber, lxid);
84
86}
87
88
89
90
91
94{
99
101 {
104
105
107
108
109
110
112
113
114
117 TEXTOID, -1, 0);
119 OIDOID, -1, 0);
121 OIDOID, -1, 0);
123 INT4OID, -1, 0);
125 INT2OID, -1, 0);
127 TEXTOID, -1, 0);
129 XIDOID, -1, 0);
131 OIDOID, -1, 0);
133 OIDOID, -1, 0);
135 INT2OID, -1, 0);
137 TEXTOID, -1, 0);
139 INT4OID, -1, 0);
141 TEXTOID, -1, 0);
143 BOOLOID, -1, 0);
145 BOOLOID, -1, 0);
147 TIMESTAMPTZOID, -1, 0);
148
150
151
152
153
154
157
162
164 }
165
168 lockData = mystatus->lockData;
169
171 {
172 bool granted;
174 const char *locktypename;
175 char tnbuf[32];
181
182 instance = &(lockData->locks[mystatus->currIdx]);
183
184
185
186
187
188
189 granted = false;
191 {
193 {
195 {
196 granted = true;
198 break;
199 }
200 }
201 }
202
203
204
205
206
207 if (!granted)
208 {
210 {
211
213
214
215
216
217
219 }
220 else
221 {
222
223
224
225
227 continue;
228 }
229 }
230
231
232
233
234
237 else
238 {
239 snprintf(tnbuf, sizeof(tnbuf), "unknown %d",
241 locktypename = tnbuf;
242 }
244
246 {
251 nulls[3] = true;
252 nulls[4] = true;
253 nulls[5] = true;
254 nulls[6] = true;
255 nulls[7] = true;
256 nulls[8] = true;
257 nulls[9] = true;
258 break;
261 nulls[2] = true;
262 nulls[3] = true;
263 nulls[4] = true;
264 nulls[5] = true;
265 nulls[6] = true;
266 nulls[7] = true;
267 nulls[8] = true;
268 nulls[9] = true;
269 break;
274 nulls[4] = true;
275 nulls[5] = true;
276 nulls[6] = true;
277 nulls[7] = true;
278 nulls[8] = true;
279 nulls[9] = true;
280 break;
286 nulls[5] = true;
287 nulls[6] = true;
288 nulls[7] = true;
289 nulls[8] = true;
290 nulls[9] = true;
291 break;
295 nulls[1] = true;
296 nulls[2] = true;
297 nulls[3] = true;
298 nulls[4] = true;
299 nulls[5] = true;
300 nulls[7] = true;
301 nulls[8] = true;
302 nulls[9] = true;
303 break;
307 nulls[1] = true;
308 nulls[2] = true;
309 nulls[3] = true;
310 nulls[4] = true;
311 nulls[6] = true;
312 nulls[7] = true;
313 nulls[8] = true;
314 nulls[9] = true;
315 break;
320 nulls[1] = true;
321 nulls[2] = true;
322 nulls[3] = true;
323 nulls[4] = true;
324 nulls[5] = true;
325 nulls[7] = true;
326 nulls[9] = true;
327 break;
333 nulls[2] = true;
334 nulls[3] = true;
335 nulls[4] = true;
336 nulls[5] = true;
337 nulls[7] = true;
338 break;
342 default:
347 nulls[2] = true;
348 nulls[3] = true;
349 nulls[4] = true;
350 nulls[5] = true;
351 nulls[6] = true;
352 break;
353 }
354
356 if (instance->pid != 0)
358 else
359 nulls[11] = true;
363 if (!granted && instance->waitStart != 0)
365 else
366 nulls[15] = true;
367
371 }
372
373
374
375
376
379 {
381
388
390
391
392
393
394
395
397
399
400
405 else
406 nulls[4] = true;
410 else
411 nulls[3] = true;
412
413
414 nulls[5] = true;
415 nulls[6] = true;
416 nulls[7] = true;
417 nulls[8] = true;
418 nulls[9] = true;
419
420
423 if (xact->pid != 0)
425 else
426 nulls[11] = true;
427
428
429
430
431
435 nulls[15] = true;
436
440 }
441
443}
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
467{
469 Datum *arrayelems;
470 int narrayelems;
472 int i,
473 j;
474
475
477
478
480 narrayelems = 0;
481
482
483 for (i = 0; i < lockData->nprocs; i++)
484 {
490 int conflictMask;
491
492
493
494
495
496 blocked_instance = NULL;
498 {
500
501 if (instance->pid == bproc->pid)
502 {
503 Assert(blocked_instance == NULL);
504 blocked_instance = instance;
505 }
506 }
507 Assert(blocked_instance != NULL);
508
511
512
514 {
516
517
518 if (instance == blocked_instance)
519 continue;
520
522 continue;
523
524 if (conflictMask & instance->holdMask)
525 {
526
527 }
530 {
531
532 bool ahead = false;
533 int k;
534
536 {
537 if (preceding_waiters[k] == instance->pid)
538 {
539
540 ahead = true;
541 break;
542 }
543 }
544 if (!ahead)
545 continue;
546 }
547 else
548 {
549
550 continue;
551 }
552
553
555 }
556 }
557
558
559 Assert(narrayelems <= lockData->nlocks);
560
562}
563
564
565
566
567
568
569
570
571
574{
576 int *blockers;
577 int num_blockers;
578 Datum *blocker_datums;
579
580
582
583
584 num_blockers =
586
587
588 if (num_blockers > 0)
589 {
590 int i;
591
592 blocker_datums = (Datum *) palloc(num_blockers * sizeof(Datum));
593 for (i = 0; i < num_blockers; ++i)
595 }
596 else
597 blocker_datums = NULL;
598
600}
601
602
603
604
605
606
607
608
609
610
611
612
613#define SET_LOCKTAG_INT64(tag, key64) \
614 SET_LOCKTAG_ADVISORY(tag, \
615 MyDatabaseId, \
616 (uint32) ((key64) >> 32), \
617 (uint32) (key64), \
618 1)
619#define SET_LOCKTAG_INT32(tag, key1, key2) \
620 SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, key1, key2, 2)
621
622
623
624
627{
630
632
634
636}
637
638
639
640
641
644{
647
649
651
653}
654
655
656
657
660{
663
665
667
669}
670
671
672
673
674
677{
680
682
684
686}
687
688
689
690
691
692
695{
699
701
703
705}
706
707
708
709
710
711
712
715{
719
721
723
725}
726
727
728
729
730
731
734{
738
740
742
744}
745
746
747
748
749
750
751
754{
758
760
762
764}
765
766
767
768
769
770
773{
776 bool res;
777
779
781
783}
784
785
786
787
788
789
792{
795 bool res;
796
798
800
802}
803
804
805
806
809{
813
815
817
819}
820
821
822
823
824
827{
831
833
835
837}
838
839
840
841
844{
848
850
852
854}
855
856
857
858
859
862{
866
868
870
872}
873
874
875
876
877
878
881{
886
888
890
892}
893
894
895
896
897
898
899
902{
907
909
911
913}
914
915
916
917
918
919
922{
927
929
931
933}
934
935
936
937
938
939
940
943{
948
950
952
954}
955
956
957
958
959
960
963{
967 bool res;
968
970
972
974}
975
976
977
978
979
980
983{
987 bool res;
988
990
992
994}
995
996
997
998
1001{
1003
1005}
#define PG_RETURN_ARRAYTYPE_P(x)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
uint32 LocalTransactionId
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define PG_GETARG_INT64(n)
#define PG_GETARG_INT32(n)
#define PG_RETURN_BOOL(x)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
BlockedProcsData * GetBlockerStatusData(int blocked_pid)
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
void LockReleaseSession(LOCKMETHODID lockmethodid)
LockData * GetLockStatusData(void)
LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)
@ LOCKTAG_RELATION_EXTEND
@ LOCKTAG_SPECULATIVE_TOKEN
@ LOCKTAG_APPLY_TRANSACTION
@ LOCKTAG_DATABASE_FROZEN_IDS
@ LOCKTAG_VIRTUALTRANSACTION
#define LOCKBIT_OFF(lockmode)
#define LOCKTAG_LAST_TYPE
#define LOCKBIT_ON(lockmode)
Datum pg_advisory_lock_int4(PG_FUNCTION_ARGS)
#define SET_LOCKTAG_INT64(tag, key64)
Datum pg_try_advisory_xact_lock_int4(PG_FUNCTION_ARGS)
Datum pg_advisory_unlock_int8(PG_FUNCTION_ARGS)
Datum pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
Datum pg_safe_snapshot_blocking_pids(PG_FUNCTION_ARGS)
Datum pg_advisory_lock_int8(PG_FUNCTION_ARGS)
Datum pg_try_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS)
Datum pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
Datum pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
static Datum VXIDGetDatum(ProcNumber procNumber, LocalTransactionId lxid)
Datum pg_try_advisory_lock_int4(PG_FUNCTION_ARGS)
#define SET_LOCKTAG_INT32(tag, key1, key2)
#define NUM_LOCK_STATUS_COLUMNS
Datum pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS)
Datum pg_advisory_unlock_int4(PG_FUNCTION_ARGS)
static const char *const PredicateLockTagTypeNames[]
Datum pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
Datum pg_lock_status(PG_FUNCTION_ARGS)
Datum pg_advisory_xact_lock_int4(PG_FUNCTION_ARGS)
StaticAssertDecl(lengthof(LockTagTypeNames)==(LOCKTAG_LAST_TYPE+1), "array length mismatch")
Datum pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
Datum pg_blocking_pids(PG_FUNCTION_ARGS)
Datum pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
Datum pg_try_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS)
Datum pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS)
Datum pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS)
Datum pg_try_advisory_lock_int8(PG_FUNCTION_ARGS)
Datum pg_advisory_unlock_all(PG_FUNCTION_ARGS)
const char *const LockTagTypeNames[]
Datum pg_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static PgChecksumMode mode
static Datum TransactionIdGetDatum(TransactionId X)
static Datum Int16GetDatum(int16 X)
static Datum UInt16GetDatum(uint16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Int32GetDatum(int32 X)
static Datum UInt32GetDatum(uint32 X)
PredicateLockData * GetPredicateLockStatusData(void)
int GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
#define GET_PREDICATELOCKTARGETTAG_DB(locktag)
#define GET_PREDICATELOCKTARGETTAG_RELATION(locktag)
#define GET_PREDICATELOCKTARGETTAG_TYPE(locktag)
#define GET_PREDICATELOCKTARGETTAG_PAGE(locktag)
#define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag)
MemoryContext multi_call_memory_ctx
uint8 locktag_lockmethodid
VirtualTransactionId vxid
const LOCKMASK * conflictTab
PredicateLockData * predLockData
PREDICATELOCKTARGETTAG * locktags
VirtualTransactionId vxid
LocalTransactionId localTransactionId
TupleDesc CreateTemplateTupleDesc(int natts)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
static Datum TimestampTzGetDatum(TimestampTz X)