/Users/deen/code/yugabyte-db/src/yb/master/catalog_entity_info.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | |
33 | | #include "yb/master/catalog_entity_info.h" |
34 | | |
35 | | #include <string> |
36 | | |
37 | | #include "yb/common/doc_hybrid_time.h" |
38 | | #include "yb/common/transaction.h" |
39 | | #include "yb/common/wire_protocol.h" |
40 | | |
41 | | #include "yb/master/master_client.pb.h" |
42 | | #include "yb/master/master_defaults.h" |
43 | | #include "yb/master/master_error.h" |
44 | | #include "yb/master/ts_descriptor.h" |
45 | | |
46 | | #include "yb/gutil/map-util.h" |
47 | | #include "yb/util/atomic.h" |
48 | | #include "yb/util/format.h" |
49 | | #include "yb/util/status_format.h" |
50 | | #include "yb/util/string_util.h" |
51 | | |
52 | | using std::string; |
53 | | |
54 | | using strings::Substitute; |
55 | | |
56 | | DECLARE_int32(tserver_unresponsive_timeout_ms); |
57 | | |
58 | | namespace yb { |
59 | | namespace master { |
60 | | |
61 | | // ================================================================================================ |
62 | | // TabletReplica |
63 | | // ================================================================================================ |
64 | | |
65 | 517k | string TabletReplica::ToString() const { |
66 | 517k | return Format("{ ts_desc: $0, state: $1, role: $2, member_type: $3, " |
67 | 517k | "should_disable_lb_move: $4, fs_data_dir: $5, " |
68 | 517k | "total_space_used: $6, time since update: $7ms }", |
69 | 517k | ts_desc->permanent_uuid(), |
70 | 517k | tablet::RaftGroupStatePB_Name(state), |
71 | 517k | PeerRole_Name(role), |
72 | 517k | consensus::PeerMemberType_Name(member_type), |
73 | 517k | should_disable_lb_move, fs_data_dir, |
74 | 517k | drive_info.sst_files_size + drive_info.wal_files_size, |
75 | 517k | MonoTime::Now().GetDeltaSince(time_updated).ToMilliseconds()); |
76 | 517k | } |
77 | | |
78 | 327k | void TabletReplica::UpdateFrom(const TabletReplica& source) { |
79 | 327k | state = source.state; |
80 | 327k | role = source.role; |
81 | 327k | member_type = source.member_type; |
82 | 327k | should_disable_lb_move = source.should_disable_lb_move; |
83 | 327k | fs_data_dir = source.fs_data_dir; |
84 | 327k | time_updated = MonoTime::Now(); |
85 | 327k | } |
86 | | |
87 | 2.39M | void TabletReplica::UpdateDriveInfo(const TabletReplicaDriveInfo& info) { |
88 | 2.39M | drive_info = info; |
89 | 2.39M | } |
90 | | |
91 | 11.5M | bool TabletReplica::IsStale() const { |
92 | 11.5M | MonoTime now(MonoTime::Now()); |
93 | 11.5M | if (now.GetDeltaSince(time_updated).ToMilliseconds() >= |
94 | 11.5M | GetAtomicFlag(&FLAGS_tserver_unresponsive_timeout_ms)) { |
95 | 6.49M | return true; |
96 | 6.49M | } |
97 | 5.02M | return false; |
98 | 11.5M | } |
99 | | |
100 | 127k | bool TabletReplica::IsStarting() const { |
101 | 127k | return (state == tablet::NOT_STARTED || state == tablet::BOOTSTRAPPING127k ); |
102 | 127k | } |
103 | | |
104 | | // ================================================================================================ |
105 | | // TabletInfo |
106 | | // ================================================================================================ |
107 | | |
108 | | class TabletInfo::LeaderChangeReporter { |
109 | | public: |
110 | | explicit LeaderChangeReporter(TabletInfo* info) |
111 | 441k | : info_(info), old_leader_(info->GetLeaderUnlocked()) { |
112 | 441k | } |
113 | | |
114 | 441k | ~LeaderChangeReporter() { |
115 | 441k | auto new_leader = info_->GetLeaderUnlocked(); |
116 | 441k | if (old_leader_ != new_leader) { |
117 | 59.7k | LOG(INFO) << "T " << info_->tablet_id() << ": Leader changed from " |
118 | 59.7k | << yb::ToString(old_leader_) << " to " << yb::ToString(new_leader); |
119 | 59.7k | } |
120 | 441k | } |
121 | | private: |
122 | | TabletInfo* info_; |
123 | | TSDescriptor* old_leader_; |
124 | | }; |
125 | | |
126 | | TabletInfo::TabletInfo(const scoped_refptr<TableInfo>& table, TabletId tablet_id) |
127 | | : tablet_id_(std::move(tablet_id)), |
128 | | table_(table), |
129 | | last_update_time_(MonoTime::Now()), |
130 | 100k | reported_schema_version_({}) { |
131 | | // Have to pre-initialize to an empty map, in case of access before the first setter is called. |
132 | 100k | replica_locations_ = std::make_shared<TabletReplicaMap>(); |
133 | 100k | } |
134 | | |
135 | 2.17k | TabletInfo::~TabletInfo() { |
136 | 2.17k | } |
137 | | |
138 | | void TabletInfo::SetReplicaLocations( |
139 | 113k | std::shared_ptr<TabletReplicaMap> replica_locations) { |
140 | 113k | std::lock_guard<simple_spinlock> l(lock_); |
141 | 113k | LeaderChangeReporter leader_change_reporter(this); |
142 | 113k | last_update_time_ = MonoTime::Now(); |
143 | 113k | replica_locations_ = replica_locations; |
144 | 113k | } |
145 | | |
146 | 92.0M | CHECKED_STATUS TabletInfo::CheckRunning() const { |
147 | 92.0M | if (!table()->is_running()) { |
148 | 255 | return STATUS_EC_FORMAT(Expired, MasterError(MasterErrorPB::TABLE_NOT_RUNNING), |
149 | 255 | "Table is not running: $0", table()->ToStringWithState()); |
150 | 255 | } |
151 | | |
152 | 92.0M | return Status::OK(); |
153 | 92.0M | } |
154 | | |
155 | 92.0M | CHECKED_STATUS TabletInfo::GetLeaderNotFoundStatus() const { |
156 | 92.0M | RETURN_NOT_OK(CheckRunning()); |
157 | | |
158 | 92.0M | return STATUS_FORMAT( |
159 | 92.0M | NotFound, |
160 | 92.0M | "No leader found for tablet $0 with $1 replicas: $2.", |
161 | 92.0M | ToString(), replica_locations_->size(), *replica_locations_); |
162 | 92.0M | } |
163 | | |
164 | 4.12M | Result<TSDescriptor*> TabletInfo::GetLeader() const { |
165 | 4.12M | std::lock_guard<simple_spinlock> l(lock_); |
166 | 4.12M | auto result = GetLeaderUnlocked(); |
167 | 4.12M | if (result) { |
168 | 3.96M | return result; |
169 | 3.96M | } |
170 | 160k | return GetLeaderNotFoundStatus(); |
171 | 4.12M | } |
172 | | |
173 | 95.3M | Result<TabletReplicaDriveInfo> TabletInfo::GetLeaderReplicaDriveInfo() const { |
174 | 95.3M | std::lock_guard<simple_spinlock> l(lock_); |
175 | | |
176 | 95.3M | for (const auto& pair : *replica_locations_) { |
177 | 6.92M | if (pair.second.role == PeerRole::LEADER) { |
178 | 3.50M | return pair.second.drive_info; |
179 | 3.50M | } |
180 | 6.92M | } |
181 | 91.8M | return GetLeaderNotFoundStatus(); |
182 | 95.3M | } |
183 | | |
184 | 5.00M | TSDescriptor* TabletInfo::GetLeaderUnlocked() const { |
185 | 10.3M | for (const auto& pair : *replica_locations_) { |
186 | 10.3M | if (pair.second.role == PeerRole::LEADER) { |
187 | 4.48M | return pair.second.ts_desc; |
188 | 4.48M | } |
189 | 10.3M | } |
190 | 526k | return nullptr; |
191 | 5.00M | } |
192 | | |
193 | 5.83M | std::shared_ptr<const TabletReplicaMap> TabletInfo::GetReplicaLocations() const { |
194 | 5.83M | std::lock_guard<simple_spinlock> l(lock_); |
195 | 5.83M | return replica_locations_; |
196 | 5.83M | } |
197 | | |
198 | 327k | void TabletInfo::UpdateReplicaLocations(const TabletReplica& replica) { |
199 | 327k | std::lock_guard<simple_spinlock> l(lock_); |
200 | 327k | LeaderChangeReporter leader_change_reporter(this); |
201 | 327k | last_update_time_ = MonoTime::Now(); |
202 | | // Make a new shared_ptr, copying the data, to ensure we don't race against access to data from |
203 | | // clients that already have the old shared_ptr. |
204 | 327k | replica_locations_ = std::make_shared<TabletReplicaMap>(*replica_locations_); |
205 | 327k | auto it = replica_locations_->find(replica.ts_desc->permanent_uuid()); |
206 | 327k | if (it == replica_locations_->end()) { |
207 | 86 | replica_locations_->emplace(replica.ts_desc->permanent_uuid(), replica); |
208 | 86 | return; |
209 | 86 | } |
210 | 327k | it->second.UpdateFrom(replica); |
211 | 327k | } |
212 | | |
213 | | void TabletInfo::UpdateReplicaDriveInfo(const std::string& ts_uuid, |
214 | 2.20M | const TabletReplicaDriveInfo& drive_info) { |
215 | 2.20M | std::lock_guard<simple_spinlock> l(lock_); |
216 | | // Make a new shared_ptr, copying the data, to ensure we don't race against access to data from |
217 | | // clients that already have the old shared_ptr. |
218 | 2.20M | replica_locations_ = std::make_shared<TabletReplicaMap>(*replica_locations_); |
219 | 2.20M | auto it = replica_locations_->find(ts_uuid); |
220 | 2.20M | if (it == replica_locations_->end()) { |
221 | 567 | return; |
222 | 567 | } |
223 | 2.19M | it->second.UpdateDriveInfo(drive_info); |
224 | 2.19M | } |
225 | | |
226 | 48.3k | void TabletInfo::set_last_update_time(const MonoTime& ts) { |
227 | 48.3k | std::lock_guard<simple_spinlock> l(lock_); |
228 | 48.3k | last_update_time_ = ts; |
229 | 48.3k | } |
230 | | |
231 | 38.3k | MonoTime TabletInfo::last_update_time() const { |
232 | 38.3k | std::lock_guard<simple_spinlock> l(lock_); |
233 | 38.3k | return last_update_time_; |
234 | 38.3k | } |
235 | | |
236 | 97.3k | bool TabletInfo::set_reported_schema_version(const TableId& table_id, uint32_t version) { |
237 | 97.3k | std::lock_guard<simple_spinlock> l(lock_); |
238 | 97.3k | if (reported_schema_version_.count(table_id) == 0 || |
239 | 97.3k | version > reported_schema_version_[table_id]48.3k ) { |
240 | 71.0k | reported_schema_version_[table_id] = version; |
241 | 71.0k | return true; |
242 | 71.0k | } |
243 | 26.2k | return false; |
244 | 97.3k | } |
245 | | |
246 | 74.7k | uint32_t TabletInfo::reported_schema_version(const TableId& table_id) { |
247 | 74.7k | std::lock_guard<simple_spinlock> l(lock_); |
248 | 74.7k | if (reported_schema_version_.count(table_id) == 0) { |
249 | 26 | return 0; |
250 | 26 | } |
251 | 74.7k | return reported_schema_version_[table_id]; |
252 | 74.7k | } |
253 | | |
254 | 3.50M | bool TabletInfo::colocated() const { |
255 | 3.50M | return LockForRead()->pb.colocated(); |
256 | 3.50M | } |
257 | | |
258 | 92.2M | string TabletInfo::ToString() const { |
259 | 92.2M | return Substitute("$0 (table $1)", tablet_id_, |
260 | 92.2M | (table_ != nullptr ? table_->ToString()92.2M : "MISSING"213 )); |
261 | 92.2M | } |
262 | | |
263 | | void TabletInfo::RegisterLeaderStepDownFailure(const TabletServerId& dest_leader, |
264 | 54.0k | MonoDelta time_since_stepdown_failure) { |
265 | 54.0k | std::lock_guard<simple_spinlock> l(lock_); |
266 | 54.0k | leader_stepdown_failure_times_[dest_leader] = MonoTime::Now() - time_since_stepdown_failure; |
267 | 54.0k | } |
268 | | |
269 | | void TabletInfo::GetLeaderStepDownFailureTimes(MonoTime forget_failures_before, |
270 | 3.94M | LeaderStepDownFailureTimes* dest) { |
271 | 3.94M | std::lock_guard<simple_spinlock> l(lock_); |
272 | 3.94M | for (auto iter = leader_stepdown_failure_times_.begin(); |
273 | 4.22M | iter != leader_stepdown_failure_times_.end(); ) { |
274 | 279k | if (iter->second < forget_failures_before) { |
275 | 4.55k | iter = leader_stepdown_failure_times_.erase(iter); |
276 | 275k | } else { |
277 | 275k | iter++; |
278 | 275k | } |
279 | 279k | } |
280 | 3.94M | *dest = leader_stepdown_failure_times_; |
281 | 3.94M | } |
282 | | |
283 | 121k | void PersistentTabletInfo::set_state(SysTabletsEntryPB::State state, const string& msg) { |
284 | 121k | pb.set_state(state); |
285 | 121k | pb.set_state_msg(msg); |
286 | 121k | } |
287 | | |
288 | | // ================================================================================================ |
289 | | // TableInfo |
290 | | // ================================================================================================ |
291 | | |
292 | | TableInfo::TableInfo(TableId table_id, |
293 | | scoped_refptr<TasksTracker> tasks_tracker) |
294 | | : table_id_(std::move(table_id)), |
295 | 499k | tasks_tracker_(tasks_tracker) { |
296 | 499k | } |
297 | | |
298 | 3.71k | TableInfo::~TableInfo() { |
299 | 3.71k | } |
300 | | |
301 | 596k | const TableName TableInfo::name() const { |
302 | 596k | return LockForRead()->pb.name(); |
303 | 596k | } |
304 | | |
305 | 92.0M | bool TableInfo::is_running() const { |
306 | 92.0M | return LockForRead()->is_running(); |
307 | 92.0M | } |
308 | | |
309 | 94.3M | bool TableInfo::is_deleted() const { |
310 | 94.3M | return LockForRead()->is_deleted(); |
311 | 94.3M | } |
312 | | |
313 | 93.9M | string TableInfo::ToString() const { |
314 | 93.9M | return Substitute("$0 [id=$1]", LockForRead()->pb.name(), table_id_); |
315 | 93.9M | } |
316 | | |
317 | 260 | string TableInfo::ToStringWithState() const { |
318 | 260 | auto l = LockForRead(); |
319 | 260 | return Substitute("$0 [id=$1, state=$2]", |
320 | 260 | l->pb.name(), table_id_, SysTablesEntryPB::State_Name(l->pb.state())); |
321 | 260 | } |
322 | | |
323 | 1.33M | const NamespaceId TableInfo::namespace_id() const { |
324 | 1.33M | return LockForRead()->namespace_id(); |
325 | 1.33M | } |
326 | | |
327 | 69.6k | const NamespaceName TableInfo::namespace_name() const { |
328 | 69.6k | return LockForRead()->namespace_name(); |
329 | 69.6k | } |
330 | | |
331 | 4.03M | const Status TableInfo::GetSchema(Schema* schema) const { |
332 | 4.03M | return SchemaFromPB(LockForRead()->schema(), schema); |
333 | 4.03M | } |
334 | | |
335 | 5.31M | bool TableInfo::colocated() const { |
336 | 5.31M | return LockForRead()->pb.colocated(); |
337 | 5.31M | } |
338 | | |
339 | 574k | std::string TableInfo::indexed_table_id() const { |
340 | 574k | return LockForRead()->indexed_table_id(); |
341 | 574k | } |
342 | | |
343 | 0 | bool TableInfo::is_local_index() const { |
344 | 0 | auto l = LockForRead(); |
345 | 0 | return l->pb.has_index_info() ? l->pb.index_info().is_local() |
346 | 0 | : l->pb.is_local_index(); |
347 | 0 | } |
348 | | |
349 | 5.94k | bool TableInfo::is_unique_index() const { |
350 | 5.94k | auto l = LockForRead(); |
351 | 5.94k | return l->pb.has_index_info() ? l->pb.index_info().is_unique() |
352 | 5.94k | : l->pb.is_unique_index()0 ; |
353 | 5.94k | } |
354 | | |
355 | 189M | TableType TableInfo::GetTableType() const { |
356 | 189M | return LockForRead()->pb.table_type(); |
357 | 189M | } |
358 | | |
359 | 457k | void TableInfo::AddTablet(const TabletInfoPtr& tablet) { |
360 | 457k | std::lock_guard<decltype(lock_)> l(lock_); |
361 | 457k | AddTabletUnlocked(tablet); |
362 | 457k | } |
363 | | |
364 | 10 | void TableInfo::ReplaceTablet(const TabletInfoPtr& old_tablet, const TabletInfoPtr& new_tablet) { |
365 | 10 | std::lock_guard<decltype(lock_)> l(lock_); |
366 | 10 | auto it = partitions_.find(old_tablet->metadata().dirty().pb.partition().partition_key_start()); |
367 | 10 | if (it != partitions_.end() && it->second == old_tablet.get()) { |
368 | 10 | partitions_.erase(it); |
369 | 10 | } |
370 | 10 | AddTabletUnlocked(new_tablet); |
371 | 10 | } |
372 | | |
373 | | |
374 | 42.8k | void TableInfo::AddTablets(const TabletInfos& tablets) { |
375 | 42.8k | std::lock_guard<decltype(lock_)> l(lock_); |
376 | 83.0k | for (const auto& tablet : tablets) { |
377 | 83.0k | AddTabletUnlocked(tablet); |
378 | 83.0k | } |
379 | 42.8k | } |
380 | | |
381 | 1.02M | void TableInfo::ClearTabletMaps(DeactivateOnly deactivate_only) { |
382 | 1.02M | std::lock_guard<decltype(lock_)> l(lock_); |
383 | 1.02M | partitions_.clear(); |
384 | 1.02M | if (!deactivate_only) { |
385 | 1.02M | tablets_.clear(); |
386 | 1.02M | } |
387 | 1.02M | } |
388 | | |
389 | 540k | void TableInfo::AddTabletUnlocked(const TabletInfoPtr& tablet) { |
390 | 540k | const auto& dirty = tablet->metadata().dirty(); |
391 | 540k | if (dirty.is_deleted()) { |
392 | 0 | return; |
393 | 0 | } |
394 | 540k | const auto& tablet_meta = dirty.pb; |
395 | 540k | tablets_.emplace(tablet->id(), tablet.get()); |
396 | | |
397 | 540k | if (dirty.is_hidden()) { |
398 | 0 | return; |
399 | 0 | } |
400 | | |
401 | 540k | const auto& partition_key_start = tablet_meta.partition().partition_key_start(); |
402 | 540k | auto p = partitions_.emplace(partition_key_start, tablet.get()); |
403 | 540k | if (p.second) { |
404 | 540k | return; |
405 | 540k | } |
406 | | |
407 | 56 | auto it = p.first; |
408 | 56 | auto old_tablet_lock = it->second->LockForRead(); |
409 | 56 | const auto old_split_depth = old_tablet_lock->pb.split_depth(); |
410 | 56 | if (tablet_meta.split_depth() > old_split_depth || old_tablet_lock->is_deleted()1 ) { |
411 | 55 | VLOG(1) << "Replacing tablet " << it->second->tablet_id() |
412 | 0 | << " (split_depth = " << old_split_depth << ")" |
413 | 0 | << " with tablet " << tablet->tablet_id() |
414 | 0 | << " (split_depth = " << tablet_meta.split_depth() << ")"; |
415 | 55 | it->second = tablet.get(); |
416 | 55 | return; |
417 | 55 | } |
418 | | |
419 | 1 | LOG_IF(DFATAL, tablet_meta.split_depth() == old_split_depth) |
420 | 0 | << "Two tablets with the same partition key start and split depth: " |
421 | 0 | << tablet_meta.ShortDebugString() << " and " << old_tablet_lock->pb.ShortDebugString(); |
422 | | |
423 | | // TODO: can we assert that the replaced tablet is not in Running state? |
424 | | // May be a little tricky since we don't know whether to look at its committed or |
425 | | // uncommitted state. |
426 | 1 | } |
427 | | |
428 | 24.9k | bool TableInfo::RemoveTablet(const TabletId& tablet_id, DeactivateOnly deactivate_only) { |
429 | 24.9k | std::lock_guard<decltype(lock_)> l(lock_); |
430 | 24.9k | return RemoveTabletUnlocked(tablet_id, deactivate_only); |
431 | 24.9k | } |
432 | | |
433 | 0 | bool TableInfo::RemoveTablets(const TabletInfos& tablets, DeactivateOnly deactivate_only) { |
434 | 0 | std::lock_guard<decltype(lock_)> l(lock_); |
435 | 0 | bool all_were_removed = true; |
436 | 0 | for (const auto& tablet : tablets) { |
437 | 0 | if (!RemoveTabletUnlocked(tablet->id(), deactivate_only)) { |
438 | 0 | all_were_removed = false; |
439 | 0 | } |
440 | 0 | } |
441 | 0 | return all_were_removed; |
442 | 0 | } |
443 | | |
444 | 24.9k | bool TableInfo::RemoveTabletUnlocked(const TabletId& tablet_id, DeactivateOnly deactivate_only) { |
445 | 24.9k | auto it = tablets_.find(tablet_id); |
446 | 24.9k | if (it == tablets_.end()) { |
447 | 0 | return false; |
448 | 0 | } |
449 | 24.9k | bool result = false; |
450 | 24.9k | auto partitions_it = partitions_.find( |
451 | 24.9k | it->second->metadata().dirty().pb.partition().partition_key_start()); |
452 | 24.9k | if (partitions_it != partitions_.end() && partitions_it->second == it->second24.9k ) { |
453 | 24.8k | partitions_.erase(partitions_it); |
454 | 24.8k | result = true; |
455 | 24.8k | } |
456 | 24.9k | if (!deactivate_only) { |
457 | 4 | tablets_.erase(it); |
458 | 4 | } |
459 | 24.9k | return result; |
460 | 24.9k | } |
461 | | |
462 | 228k | void TableInfo::GetTabletsInRange(const GetTableLocationsRequestPB* req, TabletInfos* ret) const { |
463 | 228k | if (req->has_include_inactive() && req->include_inactive()492 ) { |
464 | 0 | GetInactiveTabletsInRange( |
465 | 0 | req->partition_key_start(), req->partition_key_end(), |
466 | 0 | ret, req->max_returned_locations()); |
467 | 228k | } else { |
468 | 228k | GetTabletsInRange( |
469 | 228k | req->partition_key_start(), req->partition_key_end(), |
470 | 228k | ret, req->max_returned_locations()); |
471 | 228k | } |
472 | 228k | } |
473 | | |
474 | | void TableInfo::GetTabletsInRange( |
475 | | const std::string& partition_key_start, const std::string& partition_key_end, |
476 | 228k | TabletInfos* ret, const int32_t max_returned_locations) const { |
477 | 228k | SharedLock<decltype(lock_)> l(lock_); |
478 | 228k | decltype(partitions_)::const_iterator it, it_end; |
479 | 228k | if (partition_key_start.empty()) { |
480 | 223k | it = partitions_.begin(); |
481 | 223k | } else { |
482 | 5.08k | it = partitions_.upper_bound(partition_key_start); |
483 | 5.08k | if (it != partitions_.begin()) { |
484 | 5.02k | --it; |
485 | 5.02k | } |
486 | 5.08k | } |
487 | 228k | if (partition_key_end.empty()) { |
488 | 228k | it_end = partitions_.end(); |
489 | 228k | } else { |
490 | 64 | it_end = partitions_.upper_bound(partition_key_end); |
491 | 64 | } |
492 | | |
493 | 228k | int32_t count = 0; |
494 | 628k | for (; it != it_end && count < max_returned_locations407k ; ++it400k ) { |
495 | 400k | ret->push_back(it->second); |
496 | 400k | count++; |
497 | 400k | } |
498 | 228k | } |
499 | | |
500 | | void TableInfo::GetInactiveTabletsInRange( |
501 | | const std::string& partition_key_start, const std::string& partition_key_end, |
502 | 0 | TabletInfos* ret, const int32_t max_returned_locations) const { |
503 | 0 | SharedLock<decltype(lock_)> l(lock_); |
504 | 0 | int32_t count = 0; |
505 | 0 | for (const auto& p : tablets_) { |
506 | 0 | if (count >= max_returned_locations) { |
507 | 0 | break; |
508 | 0 | } |
509 | 0 | if (!partition_key_start.empty() && |
510 | 0 | p.second->metadata().dirty().pb.partition().partition_key_start() < partition_key_start) { |
511 | 0 | continue; |
512 | 0 | } |
513 | 0 | if (!partition_key_end.empty() && |
514 | 0 | p.second->metadata().dirty().pb.partition().partition_key_start() > partition_key_end) { |
515 | 0 | continue; |
516 | 0 | } |
517 | 0 | ret->push_back(p.second); |
518 | 0 | count++; |
519 | 0 | } |
520 | 0 | } |
521 | | |
522 | 27.7k | bool TableInfo::IsAlterInProgress(uint32_t version) const { |
523 | 27.7k | SharedLock<decltype(lock_)> l(lock_); |
524 | 74.7k | for (const auto& e : partitions_) { |
525 | 74.7k | if (e.second->reported_schema_version(table_id_) < version) { |
526 | 17.1k | VLOG_WITH_PREFIX_AND_FUNC0 (3) |
527 | 0 | << "ALTER in progress due to tablet " |
528 | 0 | << e.second->ToString() << " because reported schema " |
529 | 0 | << e.second->reported_schema_version(table_id_) << " < expected " << version; |
530 | 17.1k | return true; |
531 | 17.1k | } |
532 | 74.7k | } |
533 | 10.5k | return false; |
534 | 27.7k | } |
535 | | |
536 | 4 | bool TableInfo::AreAllTabletsHidden() const { |
537 | 4 | SharedLock<decltype(lock_)> l(lock_); |
538 | 12 | for (const auto& e : tablets_) { |
539 | 12 | if (!e.second->LockForRead()->is_hidden()) { |
540 | 0 | VLOG_WITH_PREFIX_AND_FUNC(4) << "Not hidden tablet: " << e.second->ToString(); |
541 | 0 | return false; |
542 | 0 | } |
543 | 12 | } |
544 | 4 | return true; |
545 | 4 | } |
546 | | |
547 | 16.5k | bool TableInfo::AreAllTabletsDeleted() const { |
548 | 16.5k | SharedLock<decltype(lock_)> l(lock_); |
549 | 42.7k | for (const auto& e : tablets_) { |
550 | 42.7k | if (!e.second->LockForRead()->is_deleted()) { |
551 | 8.14k | VLOG_WITH_PREFIX_AND_FUNC0 (4) << "Not deleted tablet: " << e.second->ToString()0 ; |
552 | 8.14k | return false; |
553 | 8.14k | } |
554 | 42.7k | } |
555 | 8.42k | return true; |
556 | 16.5k | } |
557 | | |
558 | 438k | bool TableInfo::IsCreateInProgress() const { |
559 | 438k | SharedLock<decltype(lock_)> l(lock_); |
560 | 991k | for (const auto& e : partitions_) { |
561 | 991k | auto tablet_info_lock = e.second->LockForRead(); |
562 | 991k | if (!tablet_info_lock->is_running() && tablet_info_lock->pb.split_depth() == 035.7k ) { |
563 | 31.3k | return true; |
564 | 31.3k | } |
565 | 991k | } |
566 | 407k | return false; |
567 | 438k | } |
568 | | |
569 | 947 | Status TableInfo::SetIsBackfilling() { |
570 | 947 | const auto table_lock = LockForRead(); |
571 | 947 | std::lock_guard<decltype(lock_)> l(lock_); |
572 | 947 | if (is_backfilling_) { |
573 | 41 | return STATUS(AlreadyPresent, "Backfill already in progress", id(), |
574 | 41 | MasterError(MasterErrorPB::SPLIT_OR_BACKFILL_IN_PROGRESS)); |
575 | 41 | } |
576 | | |
577 | 4.40k | for (const auto& tablet_it : partitions_)906 { |
578 | 4.40k | const auto& tablet = tablet_it.second; |
579 | 4.40k | if (tablet->LockForRead()->pb.state() != SysTabletsEntryPB::RUNNING) { |
580 | 0 | return STATUS_EC_FORMAT(IllegalState, |
581 | 0 | MasterError(MasterErrorPB::SPLIT_OR_BACKFILL_IN_PROGRESS), |
582 | 0 | "Some tablets are not running, table_id: $0 tablet_id: $1", |
583 | 0 | id(), tablet->tablet_id()); |
584 | 0 | } |
585 | 4.40k | } |
586 | 906 | is_backfilling_ = true; |
587 | 906 | return Status::OK(); |
588 | 906 | } |
589 | | |
590 | 8.30k | void TableInfo::SetCreateTableErrorStatus(const Status& status) { |
591 | 8.30k | std::lock_guard<decltype(lock_)> l(lock_); |
592 | 8.30k | create_table_error_ = status; |
593 | 8.30k | } |
594 | | |
595 | 40.2k | Status TableInfo::GetCreateTableErrorStatus() const { |
596 | 40.2k | SharedLock<decltype(lock_)> l(lock_); |
597 | 40.2k | return create_table_error_; |
598 | 40.2k | } |
599 | | |
600 | 77.1M | std::size_t TableInfo::NumLBTasks() const { |
601 | 77.1M | SharedLock<decltype(lock_)> l(lock_); |
602 | 77.1M | return std::count_if(pending_tasks_.begin(), |
603 | 77.1M | pending_tasks_.end(), |
604 | 77.1M | [](auto task) { return task->started_by_lb(); }270k ); |
605 | 77.1M | } |
606 | | |
607 | 0 | std::size_t TableInfo::NumTasks() const { |
608 | 0 | SharedLock<decltype(lock_)> l(lock_); |
609 | 0 | return pending_tasks_.size(); |
610 | 0 | } |
611 | | |
612 | 15.9M | bool TableInfo::HasTasks() const { |
613 | 15.9M | SharedLock<decltype(lock_)> l(lock_); |
614 | 18.4E | VLOG_WITH_PREFIX_AND_FUNC(3) << AsString(pending_tasks_); |
615 | 15.9M | return !pending_tasks_.empty(); |
616 | 15.9M | } |
617 | | |
618 | 10.8k | bool TableInfo::HasTasks(server::MonitoredTask::Type type) const { |
619 | 10.8k | SharedLock<decltype(lock_)> l(lock_); |
620 | 10.8k | for (auto task : pending_tasks_) { |
621 | 7.36k | if (task->type() == type) { |
622 | 6.88k | return true; |
623 | 6.88k | } |
624 | 7.36k | } |
625 | 3.99k | return false; |
626 | 10.8k | } |
627 | | |
628 | 421k | void TableInfo::AddTask(std::shared_ptr<server::MonitoredTask> task) { |
629 | 421k | bool abort_task = false; |
630 | 421k | { |
631 | 421k | std::lock_guard<decltype(lock_)> l(lock_); |
632 | 421k | if (!closing_421k ) { |
633 | 421k | pending_tasks_.insert(task); |
634 | 421k | if (tasks_tracker_) { |
635 | 421k | tasks_tracker_->AddTask(task); |
636 | 421k | } |
637 | 18.4E | } else { |
638 | 18.4E | abort_task = true; |
639 | 18.4E | } |
640 | 421k | } |
641 | | // We need to abort these tasks without holding the lock because when a task is destroyed it tries |
642 | | // to acquire the same lock to remove itself from pending_tasks_. |
643 | 421k | if (abort_task) { |
644 | 0 | task->AbortAndReturnPrevState(STATUS(Expired, "Table closing")); |
645 | 0 | } |
646 | 421k | } |
647 | | |
648 | 421k | bool TableInfo::RemoveTask(const std::shared_ptr<server::MonitoredTask>& task) { |
649 | 421k | bool result; |
650 | 421k | { |
651 | 421k | std::lock_guard<decltype(lock_)> l(lock_); |
652 | 421k | pending_tasks_.erase(task); |
653 | 421k | result = pending_tasks_.empty(); |
654 | 421k | } |
655 | 421k | VLOG(1) << "Removed task " << task.get() << " " << task->description()52 ; |
656 | 421k | return result; |
657 | 421k | } |
658 | | |
659 | | // Aborts tasks which have their rpc in progress, rest of them are aborted and also erased |
660 | | // from the pending list. |
661 | 13.9k | void TableInfo::AbortTasks() { |
662 | 13.9k | AbortTasksAndCloseIfRequested( /* close */ false); |
663 | 13.9k | } |
664 | | |
665 | 3.62k | void TableInfo::AbortTasksAndClose() { |
666 | 3.62k | AbortTasksAndCloseIfRequested( /* close */ true); |
667 | 3.62k | } |
668 | | |
669 | 17.5k | void TableInfo::AbortTasksAndCloseIfRequested(bool close) { |
670 | 17.5k | std::vector<std::shared_ptr<server::MonitoredTask>> abort_tasks; |
671 | 17.5k | { |
672 | 17.5k | std::lock_guard<decltype(lock_)> l(lock_); |
673 | 17.5k | if (close) { |
674 | 3.62k | closing_ = true; |
675 | 3.62k | } |
676 | 17.5k | abort_tasks.reserve(pending_tasks_.size()); |
677 | 17.5k | abort_tasks.assign(pending_tasks_.cbegin(), pending_tasks_.cend()); |
678 | 17.5k | } |
679 | 17.5k | if (abort_tasks.empty()) { |
680 | 17.5k | return; |
681 | 17.5k | } |
682 | 68 | auto status = close ? STATUS1 (Expired, "Table closing") : STATUS67 (Aborted, "Table closing"); |
683 | | // We need to abort these tasks without holding the lock because when a task is destroyed it tries |
684 | | // to acquire the same lock to remove itself from pending_tasks_. |
685 | 330 | for (const auto& task : abort_tasks) { |
686 | 330 | VLOG_WITH_FUNC0 (1) |
687 | 0 | << (close ? "Close and abort" : "Abort") << " task " << task.get() << " " |
688 | 0 | << task->description(); |
689 | 330 | task->AbortAndReturnPrevState(status); |
690 | 330 | } |
691 | 68 | } |
692 | | |
693 | 3.62k | void TableInfo::WaitTasksCompletion() { |
694 | 3.62k | int wait_time = 5; |
695 | 3.62k | while (1) { |
696 | 3.62k | std::vector<std::shared_ptr<server::MonitoredTask>> waiting_on_for_debug; |
697 | 3.62k | { |
698 | 3.62k | SharedLock<decltype(lock_)> l(lock_); |
699 | 3.62k | if (pending_tasks_.empty()) { |
700 | 3.62k | break; |
701 | 3.62k | } else if (VLOG_IS_ON(1))0 { |
702 | 0 | waiting_on_for_debug.reserve(pending_tasks_.size()); |
703 | 0 | waiting_on_for_debug.assign(pending_tasks_.cbegin(), pending_tasks_.cend()); |
704 | 0 | } |
705 | 3.62k | } |
706 | 0 | for (const auto& task : waiting_on_for_debug) { |
707 | 0 | VLOG(1) << "Waiting for Aborting task " << task.get() << " " << task->description(); |
708 | 0 | } |
709 | 0 | base::SleepForMilliseconds(wait_time); |
710 | 0 | wait_time = std::min(wait_time * 5 / 4, 10000); |
711 | 0 | } |
712 | 3.62k | } |
713 | | |
714 | 94.0M | std::unordered_set<std::shared_ptr<server::MonitoredTask>> TableInfo::GetTasks() { |
715 | 94.0M | SharedLock<decltype(lock_)> l(lock_); |
716 | 94.0M | return pending_tasks_; |
717 | 94.0M | } |
718 | | |
719 | 93.1M | std::size_t TableInfo::NumPartitions() const { |
720 | 93.1M | SharedLock<decltype(lock_)> l(lock_); |
721 | 93.1M | return partitions_.size(); |
722 | 93.1M | } |
723 | | |
724 | 0 | bool TableInfo::HasPartitions(const std::vector<PartitionKey> other) const { |
725 | 0 | SharedLock<decltype(lock_)> l(lock_); |
726 | 0 | if (partitions_.size() != other.size()) { |
727 | 0 | return false; |
728 | 0 | } |
729 | 0 | int i = 0; |
730 | 0 | for (const auto& entry : partitions_) { |
731 | 0 | if (entry.first != other[i++]) { |
732 | 0 | return false; |
733 | 0 | } |
734 | 0 | } |
735 | 0 | return true; |
736 | 0 | } |
737 | | |
738 | 94.7M | TabletInfos TableInfo::GetTablets(IncludeInactive include_inactive) const { |
739 | 94.7M | TabletInfos result; |
740 | 94.7M | SharedLock<decltype(lock_)> l(lock_); |
741 | 94.7M | if (include_inactive) { |
742 | 185k | result.reserve(tablets_.size()); |
743 | 1.04M | for (const auto& p : tablets_) { |
744 | 1.04M | result.push_back(p.second); |
745 | 1.04M | } |
746 | 94.5M | } else { |
747 | 94.5M | result.reserve(partitions_.size()); |
748 | 99.9M | for (const auto& p : partitions_) { |
749 | 99.9M | result.push_back(p.second); |
750 | 99.9M | } |
751 | 94.5M | } |
752 | 94.7M | return result; |
753 | 94.7M | } |
754 | | |
755 | 81 | TabletInfoPtr TableInfo::GetColocatedTablet() const { |
756 | 81 | SharedLock<decltype(lock_)> l(lock_); |
757 | 81 | if (colocated() && !partitions_.empty()) { |
758 | 81 | return partitions_.begin()->second; |
759 | 81 | } |
760 | 0 | return nullptr; |
761 | 81 | } |
762 | | |
763 | 6.48k | IndexInfo TableInfo::GetIndexInfo(const TableId& index_id) const { |
764 | 6.48k | auto l = LockForRead(); |
765 | 24.3k | for (const auto& index_info_pb : l->pb.indexes()) { |
766 | 24.3k | if (index_info_pb.table_id() == index_id) { |
767 | 6.48k | return IndexInfo(index_info_pb); |
768 | 6.48k | } |
769 | 24.3k | } |
770 | 0 | return IndexInfo(); |
771 | 6.48k | } |
772 | | |
773 | 1.77M | bool TableInfo::UsesTablespacesForPlacement() const { |
774 | 1.77M | auto l = LockForRead(); |
775 | | // Global transaction table is excluded due to not having a tablespace id set. |
776 | 1.77M | bool is_transaction_table_using_tablespaces = |
777 | 1.77M | l->pb.table_type() == TRANSACTION_STATUS_TABLE_TYPE && |
778 | 1.77M | l->pb.has_transaction_table_tablespace_id()232k ; |
779 | 1.77M | bool is_regular_pgsql_table = |
780 | 1.77M | l->pb.table_type() == PGSQL_TABLE_TYPE && !IsColocatedUserTable()723k && |
781 | 1.77M | l->namespace_id() != kPgSequencesDataNamespaceId723k && |
782 | 1.77M | !IsColocatedParentTable()709k ; |
783 | 1.77M | return is_transaction_table_using_tablespaces || is_regular_pgsql_table1.76M ; |
784 | 1.77M | } |
785 | | |
786 | 597k | bool TableInfo::IsTablegroupParentTable() const { |
787 | 597k | return id().find(master::kTablegroupParentTableIdSuffix) != std::string::npos; |
788 | 597k | } |
789 | | |
790 | 1.30M | bool TableInfo::IsColocatedParentTable() const { |
791 | 1.30M | return id().find(master::kColocatedParentTableIdSuffix) != std::string::npos; |
792 | 1.30M | } |
793 | | |
794 | 5.14M | bool TableInfo::IsColocatedUserTable() const { |
795 | 5.14M | return colocated() && !IsColocatedParentTable()80.9k && !IsTablegroupParentTable()75.8k ; |
796 | 5.14M | } |
797 | | |
798 | 48.4k | TablespaceId TableInfo::TablespaceIdForTableCreation() const { |
799 | 48.4k | SharedLock<decltype(lock_)> l(lock_); |
800 | 48.4k | return tablespace_id_for_table_creation_; |
801 | 48.4k | } |
802 | | |
803 | 186 | void TableInfo::SetTablespaceIdForTableCreation(const TablespaceId& tablespace_id) { |
804 | 186 | std::lock_guard<decltype(lock_)> l(lock_); |
805 | 186 | tablespace_id_for_table_creation_ = tablespace_id; |
806 | 186 | } |
807 | | |
808 | 47.5k | void PersistentTableInfo::set_state(SysTablesEntryPB::State state, const string& msg) { |
809 | 47.5k | VLOG_WITH_FUNC8 (2) << "Setting state for " << name() << " to " |
810 | 8 | << SysTablesEntryPB::State_Name(state) << " reason: " << msg; |
811 | 47.5k | pb.set_state(state); |
812 | 47.5k | pb.set_state_msg(msg); |
813 | 47.5k | } |
814 | | |
815 | 6 | bool PersistentTableInfo::is_index() const { |
816 | 6 | return !indexed_table_id().empty(); |
817 | 6 | } |
818 | | |
819 | 574k | const std::string& PersistentTableInfo::indexed_table_id() const { |
820 | 574k | static const std::string kEmptyString; |
821 | 574k | return pb.has_index_info() |
822 | 574k | ? pb.index_info().indexed_table_id()21.6k |
823 | 574k | : pb.has_indexed_table_id()552k ? pb.indexed_table_id()0 : kEmptyString552k ; |
824 | 574k | } |
825 | | |
826 | | |
827 | | // ================================================================================================ |
828 | | // DeletedTableInfo |
829 | | // ================================================================================================ |
830 | | |
831 | 0 | DeletedTableInfo::DeletedTableInfo(const TableInfo* table) : table_id_(table->id()) { |
832 | 0 | auto tablets = table->GetTablets(); |
833 | |
|
834 | 0 | for (const scoped_refptr<TabletInfo>& tablet : tablets) { |
835 | 0 | auto tablet_lock = tablet->LockForRead(); |
836 | 0 | auto replica_locations = tablet->GetReplicaLocations(); |
837 | |
|
838 | 0 | for (const TabletReplicaMap::value_type& r : *replica_locations) { |
839 | 0 | tablet_set_.insert(TabletSet::value_type( |
840 | 0 | r.second.ts_desc->permanent_uuid(), tablet->id())); |
841 | 0 | } |
842 | 0 | } |
843 | 0 | } |
844 | | |
845 | 0 | std::size_t DeletedTableInfo::NumTablets() const { |
846 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
847 | 0 | return tablet_set_.size(); |
848 | 0 | } |
849 | | |
850 | 0 | bool DeletedTableInfo::HasTablets() const { |
851 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
852 | 0 | return !tablet_set_.empty(); |
853 | 0 | } |
854 | | |
855 | 0 | void DeletedTableInfo::DeleteTablet(const TabletKey& key) { |
856 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
857 | 0 | tablet_set_.erase(key); |
858 | 0 | } |
859 | | |
860 | 0 | void DeletedTableInfo::AddTabletsToMap(DeletedTabletMap* tablet_map) { |
861 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
862 | 0 | for (const TabletKey& key : tablet_set_) { |
863 | 0 | tablet_map->insert(DeletedTabletMap::value_type(key, this)); |
864 | 0 | } |
865 | 0 | } |
866 | | |
867 | | // ================================================================================================ |
868 | | // NamespaceInfo |
869 | | // ================================================================================================ |
870 | | |
871 | 15.5k | NamespaceInfo::NamespaceInfo(NamespaceId ns_id) : namespace_id_(std::move(ns_id)) {} |
872 | | |
873 | 1.07M | const NamespaceName& NamespaceInfo::name() const { |
874 | 1.07M | return LockForRead()->pb.name(); |
875 | 1.07M | } |
876 | | |
877 | 233k | YQLDatabase NamespaceInfo::database_type() const { |
878 | 233k | return LockForRead()->pb.database_type(); |
879 | 233k | } |
880 | | |
881 | 17.7k | bool NamespaceInfo::colocated() const { |
882 | 17.7k | return LockForRead()->pb.colocated(); |
883 | 17.7k | } |
884 | | |
885 | 158k | ::yb::master::SysNamespaceEntryPB_State NamespaceInfo::state() const { |
886 | 158k | return LockForRead()->pb.state(); |
887 | 158k | } |
888 | | |
889 | 31.0k | string NamespaceInfo::ToString() const { |
890 | 31.0k | return Substitute("$0 [id=$1]", name(), namespace_id_); |
891 | 31.0k | } |
892 | | |
893 | | // ================================================================================================ |
894 | | // TablegroupInfo |
895 | | // ================================================================================================ |
896 | | |
897 | | TablegroupInfo::TablegroupInfo(TablegroupId tablegroup_id, NamespaceId namespace_id) : |
898 | 57 | tablegroup_id_(tablegroup_id), namespace_id_(namespace_id) {} |
899 | | |
900 | 92 | void TablegroupInfo::AddChildTable(const TableId& table_id, ColocationId colocation_id) { |
901 | 92 | std::lock_guard<simple_spinlock> l(lock_); |
902 | 92 | if (ContainsKey(table_map_.left, table_id)) { |
903 | 0 | LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " already contains a table with ID " |
904 | 0 | << table_id; |
905 | 92 | } else if (ContainsKey(table_map_.right, colocation_id)) { |
906 | 0 | LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " already contains a table with " |
907 | 0 | << "colocation ID " << colocation_id; |
908 | 92 | } else { |
909 | 92 | table_map_.insert(TableMap::value_type(table_id, colocation_id)); |
910 | 92 | } |
911 | 92 | } |
912 | | |
913 | 68 | void TablegroupInfo::DeleteChildTable(const TableId& table_id) { |
914 | 68 | std::lock_guard<simple_spinlock> l(lock_); |
915 | 68 | auto left_map = table_map_.left; |
916 | 68 | if (ContainsKey(left_map, table_id)) { |
917 | 68 | left_map.erase(table_id); |
918 | 68 | } else { |
919 | 0 | LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " does not contains a table with ID " |
920 | 0 | << table_id; |
921 | 0 | } |
922 | 68 | } |
923 | | |
924 | 0 | bool TablegroupInfo::HasChildTables() const { |
925 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
926 | 0 | return !table_map_.empty(); |
927 | 0 | } |
928 | | |
929 | | |
930 | 107 | bool TablegroupInfo::HasChildTable(ColocationId colocation_id) const { |
931 | 107 | std::lock_guard<simple_spinlock> l(lock_); |
932 | 107 | return ContainsKey(table_map_.right, colocation_id); |
933 | 107 | } |
934 | | |
935 | | |
936 | 40 | std::size_t TablegroupInfo::NumChildTables() const { |
937 | 40 | std::lock_guard<simple_spinlock> l(lock_); |
938 | 40 | return table_map_.size(); |
939 | 40 | } |
940 | | |
941 | 0 | std::unordered_set<TableId> TablegroupInfo::ChildTables() const { |
942 | 0 | std::lock_guard<simple_spinlock> l(lock_); |
943 | 0 | std::unordered_set<TableId> result; |
944 | 0 | for (auto iter = table_map_.left.begin(), iend = table_map_.left.end(); iter != iend; ++iter) { |
945 | 0 | result.insert(iter->first); |
946 | 0 | } |
947 | 0 | return result; |
948 | 0 | } |
949 | | |
950 | | // ================================================================================================ |
951 | | // UDTypeInfo |
952 | | // ================================================================================================ |
953 | | |
954 | 48 | UDTypeInfo::UDTypeInfo(UDTypeId udtype_id) : udtype_id_(std::move(udtype_id)) { } |
955 | | |
956 | 469 | const UDTypeName& UDTypeInfo::name() const { |
957 | 469 | return LockForRead()->pb.name(); |
958 | 469 | } |
959 | | |
960 | 227 | const NamespaceName& UDTypeInfo::namespace_id() const { |
961 | 227 | return LockForRead()->pb.namespace_id(); |
962 | 227 | } |
963 | | |
964 | 699 | int UDTypeInfo::field_names_size() const { |
965 | 699 | return LockForRead()->pb.field_names_size(); |
966 | 699 | } |
967 | | |
968 | 472 | const string& UDTypeInfo::field_names(int index) const { |
969 | 472 | return LockForRead()->pb.field_names(index); |
970 | 472 | } |
971 | | |
972 | 699 | int UDTypeInfo::field_types_size() const { |
973 | 699 | return LockForRead()->pb.field_types_size(); |
974 | 699 | } |
975 | | |
976 | 472 | const QLTypePB& UDTypeInfo::field_types(int index) const { |
977 | 472 | return LockForRead()->pb.field_types(index); |
978 | 472 | } |
979 | | |
980 | 141 | string UDTypeInfo::ToString() const { |
981 | 141 | auto l = LockForRead(); |
982 | 141 | return Format("$0 [id=$1] {metadata=$2} ", name(), udtype_id_, l->pb); |
983 | 141 | } |
984 | | |
985 | | DdlLogEntry::DdlLogEntry( |
986 | | HybridTime time, const TableId& table_id, const SysTablesEntryPB& table, |
987 | 7.60k | const std::string& action) { |
988 | 7.60k | pb_.set_time(time.ToUint64()); |
989 | 7.60k | pb_.set_table_type(table.table_type()); |
990 | 7.60k | pb_.set_namespace_name(table.namespace_name()); |
991 | 7.60k | pb_.set_namespace_id(table.namespace_id()); |
992 | 7.60k | pb_.set_table_name(table.name()); |
993 | 7.60k | pb_.set_table_id(table_id); |
994 | 7.60k | pb_.set_action(action); |
995 | 7.60k | } |
996 | | |
997 | 6.48k | const DdlLogEntryPB& DdlLogEntry::old_pb() const { |
998 | | // Since DDL log entry are always added, we don't have previous PB for the same entry. |
999 | 6.48k | static const DdlLogEntryPB kEmpty; |
1000 | 6.48k | return kEmpty; |
1001 | 6.48k | } |
1002 | | |
1003 | 6.48k | const DdlLogEntryPB& DdlLogEntry::new_pb() const { |
1004 | 6.48k | return pb_; |
1005 | 6.48k | } |
1006 | | |
1007 | 6.48k | std::string DdlLogEntry::id() const { |
1008 | 6.48k | return DocHybridTime(HybridTime(pb_.time()), kMaxWriteId).EncodedInDocDbFormat(); |
1009 | 6.48k | } |
1010 | | |
1011 | | } // namespace master |
1012 | | } // namespace yb |