1 /* Copyright (c) 2012, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_md_locks.cc
25 Table METADATA_LOCKS (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_md_locks.h"
34 #include "pfs_global.h"
35 #include "pfs_buffer_container.h"
36 #include "field.h"
37
38 THR_LOCK table_metadata_locks::m_table_lock;
39
40 static const TABLE_FIELD_TYPE field_types[]=
41 {
42 {
43 { C_STRING_WITH_LEN("OBJECT_TYPE") },
44 { C_STRING_WITH_LEN("varchar(64)") },
45 { NULL, 0}
46 },
47 {
48 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
49 { C_STRING_WITH_LEN("varchar(64)") },
50 { NULL, 0}
51 },
52 {
53 { C_STRING_WITH_LEN("OBJECT_NAME") },
54 { C_STRING_WITH_LEN("varchar(64)") },
55 { NULL, 0}
56 },
57 {
58 { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
59 { C_STRING_WITH_LEN("bigint(20)") },
60 { NULL, 0}
61 },
62 {
63 { C_STRING_WITH_LEN("LOCK_TYPE") },
64 { C_STRING_WITH_LEN("varchar(32)") },
65 { NULL, 0}
66 },
67 {
68 { C_STRING_WITH_LEN("LOCK_DURATION") },
69 { C_STRING_WITH_LEN("varchar(32)") },
70 { NULL, 0}
71 },
72 {
73 { C_STRING_WITH_LEN("LOCK_STATUS") },
74 { C_STRING_WITH_LEN("varchar(32)") },
75 { NULL, 0}
76 },
77 {
78 { C_STRING_WITH_LEN("SOURCE") },
79 { C_STRING_WITH_LEN("varchar(64)") },
80 { NULL, 0}
81 },
82 {
83 { C_STRING_WITH_LEN("OWNER_THREAD_ID") },
84 { C_STRING_WITH_LEN("bigint(20)") },
85 { NULL, 0}
86 },
87 {
88 { C_STRING_WITH_LEN("OWNER_EVENT_ID") },
89 { C_STRING_WITH_LEN("bigint(20)") },
90 { NULL, 0}
91 }
92 };
93
94 TABLE_FIELD_DEF
95 table_metadata_locks::m_field_def=
96 { 10, field_types };
97
98 PFS_engine_table_share
99 table_metadata_locks::m_share=
100 {
101 { C_STRING_WITH_LEN("metadata_locks") },
102 &pfs_readonly_acl,
103 table_metadata_locks::create,
104 NULL, /* write_row */
105 NULL, /* delete_all_rows */
106 table_metadata_locks::get_row_count,
107 sizeof(PFS_simple_index),
108 &m_table_lock,
109 &m_field_def,
110 false, /* checked */
111 false /* perpetual */
112 };
113
create(void)114 PFS_engine_table* table_metadata_locks::create(void)
115 {
116 return new table_metadata_locks();
117 }
118
119 ha_rows
get_row_count(void)120 table_metadata_locks::get_row_count(void)
121 {
122 return global_mdl_container.get_row_count();
123 }
124
table_metadata_locks()125 table_metadata_locks::table_metadata_locks()
126 : PFS_engine_table(&m_share, &m_pos),
127 m_row_exists(false), m_pos(0), m_next_pos(0)
128 {}
129
reset_position(void)130 void table_metadata_locks::reset_position(void)
131 {
132 m_pos.m_index= 0;
133 m_next_pos.m_index= 0;
134 }
135
rnd_next(void)136 int table_metadata_locks::rnd_next(void)
137 {
138 PFS_metadata_lock *pfs;
139
140 m_pos.set_at(&m_next_pos);
141 PFS_mdl_iterator it= global_mdl_container.iterate(m_pos.m_index);
142 pfs= it.scan_next(& m_pos.m_index);
143 if (pfs != NULL)
144 {
145 make_row(pfs);
146 m_next_pos.set_after(&m_pos);
147 return 0;
148 }
149
150 return HA_ERR_END_OF_FILE;
151 }
152
rnd_pos(const void * pos)153 int table_metadata_locks::rnd_pos(const void *pos)
154 {
155 PFS_metadata_lock *pfs;
156
157 set_position(pos);
158
159 pfs= global_mdl_container.get(m_pos.m_index);
160 if (pfs != NULL)
161 {
162 make_row(pfs);
163 return 0;
164 }
165
166 return HA_ERR_RECORD_DELETED;
167 }
168
make_row(PFS_metadata_lock * pfs)169 void table_metadata_locks::make_row(PFS_metadata_lock *pfs)
170 {
171 pfs_optimistic_state lock;
172
173 m_row_exists= false;
174
175 /* Protect this reader against a metadata lock destroy */
176 pfs->m_lock.begin_optimistic_lock(&lock);
177
178 m_row.m_identity= pfs->m_identity;
179 m_row.m_mdl_type= pfs->m_mdl_type;
180 m_row.m_mdl_duration= pfs->m_mdl_duration;
181 m_row.m_mdl_status= pfs->m_mdl_status;
182
183 /* Disable source file and line to avoid stale __FILE__ pointers. */
184 m_row.m_source_length= 0;
185
186 m_row.m_owner_thread_id= static_cast<ulong>(pfs->m_owner_thread_id);
187 m_row.m_owner_event_id= static_cast<ulong>(pfs->m_owner_event_id);
188
189 if (m_row.m_object.make_row(& pfs->m_mdl_key))
190 return;
191
192 if (pfs->m_lock.end_optimistic_lock(&lock))
193 m_row_exists= true;
194 }
195
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)196 int table_metadata_locks::read_row_values(TABLE *table,
197 unsigned char *buf,
198 Field **fields,
199 bool read_all)
200 {
201 Field *f;
202
203 if (unlikely(! m_row_exists))
204 return HA_ERR_RECORD_DELETED;
205
206 /* Set the null bits */
207 assert(table->s->null_bytes == 1);
208 buf[0]= 0;
209
210 for (; (f= *fields) ; fields++)
211 {
212 if (read_all || bitmap_is_set(table->read_set, f->field_index))
213 {
214 switch(f->field_index)
215 {
216 case 0: /* OBJECT_TYPE */
217 case 1: /* OBJECT_SCHEMA */
218 case 2: /* OBJECT_NAME */
219 m_row.m_object.set_nullable_field(f->field_index, f);
220 break;
221 case 3: /* OBJECT_INSTANCE */
222 set_field_ulonglong(f, (intptr) m_row.m_identity);
223 break;
224 case 4: /* LOCK_TYPE */
225 set_field_mdl_type(f, m_row.m_mdl_type);
226 break;
227 case 5: /* LOCK_DURATION */
228 set_field_mdl_duration(f, m_row.m_mdl_duration);
229 break;
230 case 6: /* LOCK_STATUS */
231 set_field_mdl_status(f, m_row.m_mdl_status);
232 break;
233 case 7: /* SOURCE */
234 set_field_varchar_utf8(f, m_row.m_source, m_row.m_source_length);
235 break;
236 case 8: /* OWNER_THREAD_ID */
237 if (m_row.m_owner_thread_id != 0)
238 set_field_ulonglong(f, m_row.m_owner_thread_id);
239 else
240 f->set_null();
241 break;
242 case 9: /* OWNER_EVENT_ID */
243 if (m_row.m_owner_event_id != 0)
244 set_field_ulonglong(f, m_row.m_owner_event_id);
245 else
246 f->set_null();
247 break;
248 default:
249 assert(false);
250 }
251 }
252 }
253
254 return 0;
255 }
256
257