3 * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
5 * locktimesid.d - Display lock wait times grouped by filename.
7 * This script graphs the time spent waiting for DB page locks.
9 * The optional integer maxcount parameter directs the script to exit once that
10 * many page lock waits have been measured.
12 * usage: locktimes.d { -p <pid> | -c "<program> [<args]" } [maxcount]
14 * The result times in nanoseconds are grouped by (filename, pgno, lock_mode).
17 * lock-suspend(DBT *lockobj, db_lockmode_t lock_ mode)
18 * lock-resume(DBT *lockobj, db_lockmode_t mode)
19 * db-open(char *file, char *db, uint32_t flags, uint8_t fileid[20])
20 * db-cursor(char *file, char *db, unsigned txnid, unsigned flags,
23 * The DBT locates the locked object in shared memory. As long as
24 * application-specific locks are not being used, the DBT points to
27 * u_int8_t fileid[20];
29 * Type is 1 for handle, 2 for page, 3 for a queue's record number.
30 * The mode paramteris the enum db_lockmode_t
31 * notgranted,read,write,wait,iread,iwrite,iwr,read_unc,wwrite
33 * This script may display unexpected results when application-specific
37 #pragma D option defaultargs
39 typedef D`uint32_t db_pgno_t;
41 /* A DBT for the DB API */
42 typedef struct __db_dbt {
43 uintptr_t data; /* Key/data */
44 uint32_t size; /* key/data length */
46 uint32_t ulen; /* RO: length of user buffer. */
47 uint32_t dlen; /* RO: get/put record length. */
48 uint32_t doff; /* RO: get/put record offset. */
54 /* A DBT in shared memory */
57 * DB fileids are actually uint8_t fileid[20]; in D it is easier to handle them
58 * as a struct of 5 four-byte integers.
69 typedef struct __db_ilock {
80 string filenames[unsigned, unsigned, unsigned, unsigned, unsigned];
86 maxcount = $1 != 0 ? $1 : -1;
88 printf("DB lock wait times by (file, pgno) for process %d\n", $target);
89 printf("Interrupt to display summary\n");
90 modes[0] = "NOTGRANTED";
94 modes[4] = "INTENT_WRITE";
95 modes[5] = "INTENT_READ";
96 modes[6] = "INTENT_WR";
97 modes[7] = "READ_UNCOMMITTED";
98 modes[8] = "WAS_WRITE";
102 /* lock-suspend(DBT *lockobj, int lock_mode) */
103 bdb$target:::lock-suspend
105 self->suspend = timestamp;
109 /* lock-resume(DBT *lockobj, int lock_mode) */
110 bdb$target:::lock-resume
113 this->duration = timestamp - self->suspend;
115 this->dbt = copyin(arg0, sizeof(DBT));
116 this->ilock = copyin(this->dbt->data, sizeof(DB_ILOCK));
117 this->filename = filenames[this->ilock->fileid.id1,
118 this->ilock->fileid.id2, this->ilock->fileid.id3,
119 this->ilock->fileid.id4, this->ilock->fileid.id5];
120 @locktimes[this->filename, this->ilock->pgno, modes[arg1]] =
121 quantize(this->duration);
125 bdb$target:::lock-resume
126 /lockcount == maxcount/
131 /* db-open(char *file, char *db, uint32_t flags, uint8_t fileid[20])
133 * Watch db-open probes in order to get the fileid -> file name mapping.
138 this->filename = copyinstr(arg0);
139 this->fileid = (FILEID *) copyin(arg3, 20);
140 filenames[this->fileid->id1, this->fileid->id2, this->fileid->id3,
141 this->fileid->id4, this->fileid->id5] = this->filename;
144 /* db-cursor(char *file, char *db, unsigned txnid, unsigned flags, uint8_t fileid[20])
146 * Watch cursor creation probes in order to get the fileid -> file name mapping.
148 bdb$target:::db-cursor
151 this->filename = (string) copyinstr(arg0);
152 this->fileid = (FILEID *) copyin(arg4, 20);
153 filenames[this->fileid->id1, this->fileid->id2, this->fileid->id3,
154 this->fileid->id4, this->fileid->id5] = this->filename;
159 printa("Wait time for file %s page %u %s locks in nanoseconds %@a\n", @locktimes);