/Users/deen/code/yugabyte-db/src/yb/yql/pgwrapper/geo_transactions-test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | |
13 | | #include <string> |
14 | | #include <vector> |
15 | | |
16 | | #include "yb/client/client_fwd.h" |
17 | | #include "yb/client/transaction.h" |
18 | | #include "yb/client/transaction_manager.h" |
19 | | #include "yb/client/transaction_pool.h" |
20 | | #include "yb/client/yb_table_name.h" |
21 | | |
22 | | #include "yb/common/common.pb.h" |
23 | | |
24 | | #include "yb/gutil/strings/join.h" |
25 | | |
26 | | #include "yb/master/catalog_entity_info.pb.h" |
27 | | #include "yb/master/catalog_manager.h" |
28 | | #include "yb/master/master_defaults.h" |
29 | | #include "yb/master/mini_master.h" |
30 | | |
31 | | #include "yb/tserver/mini_tablet_server.h" |
32 | | #include "yb/tserver/tablet_server.h" |
33 | | |
34 | | #include "yb/yql/pgwrapper/pg_mini_test_base.h" |
35 | | |
36 | | DECLARE_int32(ysql_tablespace_info_refresh_secs); |
37 | | DECLARE_int32(TEST_nodes_per_cloud); |
38 | | DECLARE_int32(load_balancer_max_concurrent_adds); |
39 | | DECLARE_int32(load_balancer_max_concurrent_removals); |
40 | | DECLARE_int32(load_balancer_max_concurrent_moves); |
41 | | DECLARE_int32(load_balancer_max_concurrent_moves_per_table); |
42 | | DECLARE_bool(enable_ysql_tablespaces_for_placement); |
43 | | DECLARE_bool(force_global_transactions); |
44 | | DECLARE_bool(auto_create_local_transaction_tables); |
45 | | DECLARE_bool(TEST_track_last_transaction); |
46 | | DECLARE_bool(TEST_name_transaction_tables_with_tablespace_id); |
47 | | DECLARE_string(placement_cloud); |
48 | | DECLARE_string(placement_region); |
49 | | DECLARE_string(placement_zone); |
50 | | |
51 | | namespace yb { |
52 | | |
53 | | namespace client { |
54 | | |
55 | | namespace { |
56 | | |
57 | | YB_DEFINE_ENUM(ExpectedLocality, (kLocal)(kGlobal)); |
58 | | YB_STRONGLY_TYPED_BOOL(SetGlobalTransactionsGFlag); |
59 | | YB_STRONGLY_TYPED_BOOL(SetGlobalTransactionSessionVar); |
60 | | YB_STRONGLY_TYPED_BOOL(WaitForHashChange); |
61 | | |
62 | | constexpr auto kDatabaseName = "yugabyte"; |
63 | | constexpr auto kTablePrefix = "test"; |
64 | | const auto kStatusTabletCacheRefreshTimeout = MonoDelta::FromMilliseconds(20000); |
65 | | const auto kWaitLoadBalancerTimeout = MonoDelta::FromMilliseconds(30000); |
66 | | |
67 | | } // namespace |
68 | | |
69 | | // Tests transactions using local transaction tables. |
70 | | // Locality is currently being determined using the placement_cloud/region/zone gflags, |
71 | | // which is shared for MiniCluster's tablet servers which run in the same process. This test |
72 | | // gets around this problem by setting these flags to that of the singular tablet server |
73 | | // which runs the postgres instance. |
74 | | class GeoTransactionsTest : public pgwrapper::PgMiniTestBase { |
75 | | public: |
76 | 0 | void SetUp() override { |
77 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_name_transaction_tables_with_tablespace_id) = true; |
78 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_enable_ysql_tablespaces_for_placement) = true; |
79 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_track_last_transaction) = true; |
80 | | // These don't get set in automatically in tests. |
81 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_placement_cloud) = "cloud0"; |
82 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_placement_region) = "rack1"; |
83 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_placement_zone) = "zone"; |
84 | | // Put everything in the same cloud. |
85 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_nodes_per_cloud) = 5; |
86 | | // Reduce time spent waiting for tablespace refresh. |
87 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_ysql_tablespace_info_refresh_secs) = 1; |
88 | | // We wait for the load balancer whenever it gets triggered anyways, so there's |
89 | | // no concerns about the load balancer taking too many resources. |
90 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_load_balancer_max_concurrent_adds) = 10; |
91 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_load_balancer_max_concurrent_removals) = 10; |
92 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_load_balancer_max_concurrent_moves) = 10; |
93 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_load_balancer_max_concurrent_moves_per_table) = 10; |
94 | |
|
95 | 0 | pgwrapper::PgMiniTestBase::SetUp(); |
96 | 0 | client_ = ASSERT_RESULT(cluster_->CreateClient()); |
97 | 0 | transaction_pool_ = nullptr; |
98 | 0 | for (size_t i = 0; i != cluster_->num_tablet_servers(); ++i) { |
99 | 0 | auto mini_ts = cluster_->mini_tablet_server(i); |
100 | 0 | if (AsString(mini_ts->bound_rpc_addr().address()) == pg_host_port().host()) { |
101 | 0 | transaction_pool_ = mini_ts->server()->TransactionPool(); |
102 | 0 | transaction_manager_ = mini_ts->server()->TransactionManager(); |
103 | 0 | break; |
104 | 0 | } |
105 | 0 | } |
106 | 0 | ASSERT_NE(transaction_pool_, nullptr); |
107 | | |
108 | | // Wait for system.transactions to be created. |
109 | 0 | WaitForStatusTabletsVersion(1); |
110 | 0 | } |
111 | | |
112 | 0 | virtual size_t NumTabletServers() override { |
113 | 0 | return 3; |
114 | 0 | } |
115 | | |
116 | 0 | void DoTearDown() override { |
117 | 0 | pgwrapper::PgMiniTestBase::DoTearDown(); |
118 | 0 | } |
119 | | |
120 | | protected: |
121 | | const std::shared_ptr<tserver::MiniTabletServer> PickPgTabletServer( |
122 | 0 | const MiniCluster::MiniTabletServers& servers) override { |
123 | | // Force postgres to run on first TS. |
124 | 0 | return servers[0]; |
125 | 0 | } |
126 | | |
127 | 0 | YBTableName TableName(int region) { |
128 | 0 | return YBTableName( |
129 | 0 | YQLDatabase::YQL_DATABASE_PGSQL, kDatabaseName, |
130 | 0 | strings::Substitute("$0$1", kTablePrefix, region)); |
131 | 0 | } |
132 | | |
133 | 0 | void CreateTransactionTable(int region) { |
134 | 0 | auto current_version = transaction_manager_->GetLoadedStatusTabletsVersion(); |
135 | |
|
136 | 0 | std::string name = strings::Substitute("transactions_region$0", region); |
137 | 0 | ASSERT_OK(client_->CreateTransactionsStatusTable(name)); |
138 | |
|
139 | 0 | WaitForStatusTabletsVersion(current_version + 1); |
140 | |
|
141 | 0 | YBTableName table_name(YQL_DATABASE_CQL, yb::master::kSystemNamespaceName, name); |
142 | 0 | auto replicas = new master::PlacementInfoPB; |
143 | 0 | replicas->set_num_replicas(1); |
144 | 0 | auto pb = replicas->add_placement_blocks(); |
145 | 0 | pb->mutable_cloud_info()->set_placement_cloud("cloud0"); |
146 | 0 | pb->mutable_cloud_info()->set_placement_region(strings::Substitute("rack$0", region)); |
147 | 0 | pb->mutable_cloud_info()->set_placement_zone("zone"); |
148 | 0 | pb->set_min_num_replicas(1); |
149 | 0 | ASSERT_OK(client_->ModifyTablePlacementInfo(table_name, replicas)); |
150 | |
|
151 | 0 | WaitForStatusTabletsVersion(current_version + 2); |
152 | 0 | } |
153 | | |
154 | 0 | void CreateMultiRegionTransactionTable() { |
155 | 0 | auto current_version = transaction_manager_->GetLoadedStatusTabletsVersion(); |
156 | |
|
157 | 0 | std::string name = strings::Substitute("transactions_multiregion"); |
158 | 0 | ASSERT_OK(client_->CreateTransactionsStatusTable(name)); |
159 | |
|
160 | 0 | WaitForStatusTabletsVersion(current_version + 1); |
161 | |
|
162 | 0 | YBTableName table_name(YQL_DATABASE_CQL, yb::master::kSystemNamespaceName, name); |
163 | 0 | auto replicas = new master::PlacementInfoPB; |
164 | 0 | replicas->set_num_replicas(3); |
165 | 0 | auto pb = replicas->add_placement_blocks(); |
166 | 0 | pb->mutable_cloud_info()->set_placement_cloud("cloud0"); |
167 | 0 | pb->mutable_cloud_info()->set_placement_region("rack1"); |
168 | 0 | pb->mutable_cloud_info()->set_placement_zone("zone"); |
169 | 0 | pb->set_min_num_replicas(1); |
170 | 0 | pb = replicas->add_placement_blocks(); |
171 | 0 | pb->mutable_cloud_info()->set_placement_cloud("cloud0"); |
172 | 0 | pb->mutable_cloud_info()->set_placement_region("rack2"); |
173 | 0 | pb->mutable_cloud_info()->set_placement_zone("zone"); |
174 | 0 | pb->set_min_num_replicas(1); |
175 | 0 | ASSERT_OK(client_->ModifyTablePlacementInfo(table_name, replicas)); |
176 | |
|
177 | 0 | WaitForStatusTabletsVersion(current_version + 2); |
178 | 0 | } |
179 | | |
180 | 0 | void SetupTables() { |
181 | | // Create tablespaces and tables. |
182 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_force_global_transactions) = true; |
183 | 0 | auto conn = ASSERT_RESULT(Connect()); |
184 | 0 | bool wait_for_hash = ANNOTATE_UNPROTECTED_READ(FLAGS_auto_create_local_transaction_tables); |
185 | 0 | auto current_version = transaction_manager_->GetLoadedStatusTabletsVersion(); |
186 | 0 | for (size_t i = 1; i <= NumTabletServers(); ++i) { |
187 | 0 | ASSERT_OK(conn.ExecuteFormat(R"#( |
188 | 0 | CREATE TABLESPACE tablespace$0 WITH (replica_placement='{ |
189 | 0 | "num_replicas": 1, |
190 | 0 | "placement_blocks":[{ |
191 | 0 | "cloud": "cloud0", |
192 | 0 | "region": "rack$0", |
193 | 0 | "zone": "zone", |
194 | 0 | "min_num_replicas": 1 |
195 | 0 | }] |
196 | 0 | }') |
197 | 0 | )#", i)); |
198 | 0 | ASSERT_OK(conn.ExecuteFormat( |
199 | 0 | "CREATE TABLE $0$1(value int) TABLESPACE tablespace$1", kTablePrefix, i)); |
200 | |
|
201 | 0 | if (wait_for_hash) { |
202 | 0 | WaitForStatusTabletsVersion(current_version + 1); |
203 | 0 | ++current_version; |
204 | 0 | } |
205 | 0 | } |
206 | 0 | } |
207 | | |
208 | 0 | void SetupTablesWithAlter() { |
209 | | // Create tablespaces and tables. |
210 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_force_global_transactions) = true; |
211 | 0 | auto conn = ASSERT_RESULT(Connect()); |
212 | 0 | bool wait_for_version = ANNOTATE_UNPROTECTED_READ(FLAGS_auto_create_local_transaction_tables); |
213 | 0 | auto current_version = transaction_manager_->GetLoadedStatusTabletsVersion(); |
214 | 0 | for (size_t i = 1; i <= NumTabletServers(); ++i) { |
215 | 0 | ASSERT_OK(conn.ExecuteFormat(R"#( |
216 | 0 | CREATE TABLESPACE tablespace$0 WITH (replica_placement='{ |
217 | 0 | "num_replicas": 1, |
218 | 0 | "placement_blocks":[{ |
219 | 0 | "cloud": "cloud0", |
220 | 0 | "region": "rack$0", |
221 | 0 | "zone": "zone", |
222 | 0 | "min_num_replicas": 1 |
223 | 0 | }] |
224 | 0 | }') |
225 | 0 | )#", i)); |
226 | 0 | ASSERT_OK(conn.ExecuteFormat( |
227 | 0 | "CREATE TABLE $0$1(value int)", kTablePrefix, i)); |
228 | 0 | ASSERT_OK(conn.ExecuteFormat( |
229 | 0 | "ALTER TABLE $0$1 SET TABLESPACE tablespace$1", kTablePrefix, i)); |
230 | |
|
231 | 0 | WaitForLoadBalanceCompletion(); |
232 | 0 | if (wait_for_version) { |
233 | 0 | WaitForStatusTabletsVersion(current_version + 1); |
234 | 0 | ++current_version; |
235 | 0 | } |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | 0 | void DropTables() { |
240 | | // Drop tablespaces and tables. |
241 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_force_global_transactions) = true; |
242 | 0 | auto conn = ASSERT_RESULT(Connect()); |
243 | 0 | bool wait_for_hash = ANNOTATE_UNPROTECTED_READ(FLAGS_auto_create_local_transaction_tables); |
244 | 0 | uint64_t current_version = transaction_manager_->GetLoadedStatusTabletsVersion(); |
245 | 0 | for (size_t i = 1; i <= NumTabletServers(); ++i) { |
246 | 0 | auto table_id = ASSERT_RESULT(GetTableIdForRegion(i)); |
247 | 0 | ASSERT_OK(conn.ExecuteFormat("DROP TABLE $0$1", kTablePrefix, i)); |
248 | 0 | ASSERT_OK(conn.ExecuteFormat("DROP TABLESPACE tablespace$0", i)); |
249 | |
|
250 | 0 | if (wait_for_hash) { |
251 | 0 | WaitForStatusTabletsVersion(current_version + 1); |
252 | 0 | ++current_version; |
253 | 0 | } |
254 | 0 | } |
255 | 0 | } |
256 | | |
257 | 0 | Result<TableId> GetTableIdForRegion(size_t region) { |
258 | 0 | auto conn = VERIFY_RESULT(Connect()); |
259 | 0 | uint32_t database_oid = VERIFY_RESULT(conn.FetchValue<int32_t>(strings::Substitute( |
260 | 0 | "SELECT oid FROM pg_catalog.pg_database WHERE datname = '$0'", kDatabaseName))); |
261 | 0 | uint32_t table_oid = VERIFY_RESULT(conn.FetchValue<int32_t>(strings::Substitute( |
262 | 0 | "SELECT oid FROM pg_catalog.pg_class WHERE relname = '$0$1'", kTablePrefix, region))); |
263 | 0 | return GetPgsqlTableId(database_oid, table_oid); |
264 | 0 | } |
265 | | |
266 | 0 | Result<uint32_t> GetTablespaceOidForRegion(int region) { |
267 | 0 | auto conn = EXPECT_RESULT(Connect()); |
268 | 0 | uint32_t tablespace_oid = EXPECT_RESULT(conn.FetchValue<int32_t>(strings::Substitute( |
269 | 0 | "SELECT oid FROM pg_catalog.pg_tablespace WHERE spcname = 'tablespace$0'", region))); |
270 | 0 | return tablespace_oid; |
271 | 0 | } |
272 | | |
273 | 0 | Result<std::vector<TabletId>> GetStatusTablets(int region, bool global) { |
274 | 0 | YBTableName table_name; |
275 | 0 | if (global) { |
276 | 0 | table_name = YBTableName( |
277 | 0 | YQL_DATABASE_CQL, master::kSystemNamespaceName, kGlobalTransactionsTableName); |
278 | 0 | } else if (ANNOTATE_UNPROTECTED_READ(FLAGS_auto_create_local_transaction_tables)) { |
279 | 0 | auto tablespace_oid = EXPECT_RESULT(GetTablespaceOidForRegion(region)); |
280 | 0 | table_name = YBTableName( |
281 | 0 | YQL_DATABASE_CQL, master::kSystemNamespaceName, |
282 | 0 | yb::Format("transactions_$0", tablespace_oid)); |
283 | 0 | } else { |
284 | 0 | table_name = YBTableName( |
285 | 0 | YQL_DATABASE_CQL, master::kSystemNamespaceName, |
286 | 0 | yb::Format("transactions_region$0", region)); |
287 | 0 | } |
288 | 0 | std::vector<TabletId> tablet_uuids; |
289 | 0 | RETURN_NOT_OK(client_->GetTablets( |
290 | 0 | table_name, 1000 /* max_tablets */, &tablet_uuids, nullptr /* ranges */)); |
291 | 0 | return tablet_uuids; |
292 | 0 | } |
293 | | |
294 | | void CheckInsert(int to_region, SetGlobalTransactionsGFlag set_global_transactions_gflag, |
295 | 0 | SetGlobalTransactionSessionVar session_var, ExpectedLocality expected) { |
296 | 0 | auto expected_status_tablets = ASSERT_RESULT(GetStatusTablets( |
297 | 0 | to_region, expected != ExpectedLocality::kLocal)); |
298 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_force_global_transactions) = |
299 | 0 | (set_global_transactions_gflag == SetGlobalTransactionsGFlag::kTrue); |
300 | |
|
301 | 0 | auto conn = ASSERT_RESULT(Connect()); |
302 | 0 | ASSERT_OK(conn.ExecuteFormat("SET force_global_transaction = $0", ToString(session_var))); |
303 | 0 | ASSERT_OK(conn.StartTransaction(IsolationLevel::SERIALIZABLE_ISOLATION)); |
304 | 0 | ASSERT_OK(conn.ExecuteFormat("INSERT INTO $0$1(value) VALUES (0)", kTablePrefix, to_region)); |
305 | 0 | ASSERT_OK(conn.CommitTransaction()); |
306 | |
|
307 | 0 | auto last_transaction = transaction_pool_->TEST_GetLastTransaction(); |
308 | 0 | auto metadata = last_transaction->GetMetadata().get(); |
309 | 0 | ASSERT_OK(metadata); |
310 | 0 | ASSERT_FALSE(expected_status_tablets.empty()); |
311 | 0 | ASSERT_TRUE(std::find(expected_status_tablets.begin(), |
312 | 0 | expected_status_tablets.end(), |
313 | 0 | metadata->status_tablet) != expected_status_tablets.end()); |
314 | 0 | } |
315 | | |
316 | | void CheckAbort(int to_region, SetGlobalTransactionsGFlag set_global_transactions_gflag, |
317 | 0 | SetGlobalTransactionSessionVar session_var, size_t num_aborts) { |
318 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_force_global_transactions) = set_global_transactions_gflag; |
319 | |
|
320 | 0 | auto conn = ASSERT_RESULT(Connect()); |
321 | 0 | ASSERT_OK(conn.ExecuteFormat("SET force_global_transaction = $0", ToString(session_var))); |
322 | 0 | for (size_t i = 0; i < num_aborts; ++i) { |
323 | 0 | ASSERT_OK(conn.StartTransaction(IsolationLevel::SERIALIZABLE_ISOLATION)); |
324 | 0 | ASSERT_NOK(conn.ExecuteFormat("INSERT INTO $0$1(value) VALUES (0)", kTablePrefix, to_region)); |
325 | 0 | ASSERT_OK(conn.RollbackTransaction()); |
326 | 0 | } |
327 | 0 | } |
328 | | |
329 | 0 | void WaitForStatusTabletsVersion(uint64_t version) { |
330 | 0 | constexpr auto error = |
331 | 0 | "Timed out waiting for transaction manager to update status tablet cache version to $0"; |
332 | 0 | ASSERT_OK(WaitFor( |
333 | 0 | [this, version] { |
334 | 0 | return transaction_manager_->GetLoadedStatusTabletsVersion() == version; |
335 | 0 | }, |
336 | 0 | kStatusTabletCacheRefreshTimeout, |
337 | 0 | strings::Substitute(error, version))); |
338 | 0 | } |
339 | | |
340 | 0 | void WaitForLoadBalanceCompletion() { |
341 | 0 | ASSERT_OK(WaitFor([&]() -> Result<bool> { |
342 | 0 | bool is_idle = VERIFY_RESULT(client_->IsLoadBalancerIdle()); |
343 | 0 | return !is_idle; |
344 | 0 | }, kWaitLoadBalancerTimeout, "Timeout waiting for load balancer to start")); |
345 | |
|
346 | 0 | ASSERT_OK(WaitFor([&]() -> Result<bool> { |
347 | 0 | return client_->IsLoadBalancerIdle(); |
348 | 0 | }, kWaitLoadBalancerTimeout, "Timeout waiting for load balancer to go idle")); |
349 | 0 | } |
350 | | |
351 | | private: |
352 | | std::unique_ptr<YBClient> client_; |
353 | | TransactionManager* transaction_manager_; |
354 | | TransactionPool* transaction_pool_; |
355 | | }; |
356 | | |
357 | 0 | TEST_F(GeoTransactionsTest, YB_DISABLE_TEST_IN_TSAN(TestTransactionTabletSelection)) { |
358 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_auto_create_local_transaction_tables) = false; |
359 | 0 | SetupTables(); |
360 | | |
361 | | // No local transaction tablets yet. |
362 | 0 | CheckInsert( |
363 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
364 | 0 | ExpectedLocality::kGlobal); |
365 | 0 | CheckInsert( |
366 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
367 | 0 | ExpectedLocality::kGlobal); |
368 | 0 | CheckInsert( |
369 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
370 | 0 | ExpectedLocality::kGlobal); |
371 | 0 | CheckInsert( |
372 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
373 | 0 | ExpectedLocality::kGlobal); |
374 | 0 | CheckInsert( |
375 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
376 | 0 | ExpectedLocality::kGlobal); |
377 | 0 | CheckInsert( |
378 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
379 | 0 | ExpectedLocality::kGlobal); |
380 | 0 | CheckInsert( |
381 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
382 | 0 | ExpectedLocality::kGlobal); |
383 | 0 | CheckInsert( |
384 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
385 | 0 | ExpectedLocality::kGlobal); |
386 | | |
387 | | // Create region 2 local transaction table. |
388 | 0 | CreateTransactionTable(2); |
389 | | |
390 | | // No local transaction tablets in region, but local transaction tablets exist in general. |
391 | 0 | CheckInsert( |
392 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
393 | 0 | ExpectedLocality::kGlobal); |
394 | 0 | CheckInsert( |
395 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
396 | 0 | ExpectedLocality::kGlobal); |
397 | 0 | CheckInsert( |
398 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
399 | 0 | ExpectedLocality::kGlobal); |
400 | 0 | CheckInsert( |
401 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
402 | 0 | ExpectedLocality::kGlobal); |
403 | 0 | CheckInsert( |
404 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
405 | 0 | ExpectedLocality::kGlobal); |
406 | 0 | CheckInsert( |
407 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
408 | 0 | ExpectedLocality::kGlobal); |
409 | 0 | CheckInsert( |
410 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
411 | 0 | ExpectedLocality::kGlobal); |
412 | 0 | CheckInsert( |
413 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
414 | 0 | ExpectedLocality::kGlobal); |
415 | | |
416 | | // Create region 1 local transaction table. |
417 | 0 | CreateTransactionTable(1); |
418 | | |
419 | | // Local transaction tablets exist in region. |
420 | | // The case of connecting to TS2 with force_global_transactions = false will error out |
421 | | // because it is a global transaction, see #10537. |
422 | 0 | CheckInsert( |
423 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
424 | 0 | ExpectedLocality::kLocal); |
425 | 0 | CheckAbort( |
426 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
427 | 0 | 1 /* num_aborts */); |
428 | 0 | CheckInsert( |
429 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
430 | 0 | ExpectedLocality::kGlobal); |
431 | 0 | CheckInsert( |
432 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
433 | 0 | ExpectedLocality::kGlobal); |
434 | 0 | CheckInsert( |
435 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
436 | 0 | ExpectedLocality::kGlobal); |
437 | 0 | CheckInsert( |
438 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
439 | 0 | ExpectedLocality::kGlobal); |
440 | 0 | CheckInsert( |
441 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
442 | 0 | ExpectedLocality::kGlobal); |
443 | 0 | CheckInsert( |
444 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
445 | 0 | ExpectedLocality::kGlobal); |
446 | 0 | } |
447 | | |
448 | 0 | TEST_F(GeoTransactionsTest, YB_DISABLE_TEST_IN_TSAN(TestNonlocalAbort)) { |
449 | 0 | constexpr size_t kNumAborts = 1000; |
450 | |
|
451 | 0 | SetupTables(); |
452 | |
|
453 | 0 | CheckInsert( |
454 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
455 | 0 | ExpectedLocality::kGlobal); |
456 | | |
457 | | // Create region 1 local transaction table. |
458 | 0 | CreateTransactionTable(1); |
459 | |
|
460 | 0 | CheckAbort( |
461 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, kNumAborts); |
462 | 0 | } |
463 | | |
464 | 0 | TEST_F(GeoTransactionsTest, YB_DISABLE_TEST_IN_TSAN(TestMultiRegionTransactionTable)) { |
465 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_auto_create_local_transaction_tables) = false; |
466 | |
|
467 | 0 | SetupTables(); |
468 | |
|
469 | 0 | CreateMultiRegionTransactionTable(); |
470 | | |
471 | | // Should be treated the same as no transaction table. |
472 | 0 | CheckInsert( |
473 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
474 | 0 | ExpectedLocality::kGlobal); |
475 | 0 | CheckInsert( |
476 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
477 | 0 | ExpectedLocality::kGlobal); |
478 | 0 | CheckInsert( |
479 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
480 | 0 | ExpectedLocality::kGlobal); |
481 | 0 | CheckInsert( |
482 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
483 | 0 | ExpectedLocality::kGlobal); |
484 | 0 | CheckInsert( |
485 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
486 | 0 | ExpectedLocality::kGlobal); |
487 | 0 | CheckInsert( |
488 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
489 | 0 | ExpectedLocality::kGlobal); |
490 | 0 | CheckInsert( |
491 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
492 | 0 | ExpectedLocality::kGlobal); |
493 | 0 | CheckInsert( |
494 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
495 | 0 | ExpectedLocality::kGlobal); |
496 | 0 | } |
497 | | |
498 | 0 | TEST_F(GeoTransactionsTest, YB_DISABLE_TEST_IN_TSAN(TestAutomaticLocalTransactionTableCreation)) { |
499 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_auto_create_local_transaction_tables) = true; |
500 | 0 | SetupTables(); |
501 | | |
502 | | // The case of connecting to TS2 with force_global_transactions = false will error out |
503 | | // because it is a global transaction, see #10537. |
504 | 0 | CheckInsert( |
505 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
506 | 0 | ExpectedLocality::kLocal); |
507 | 0 | CheckInsert( |
508 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
509 | 0 | ExpectedLocality::kGlobal); |
510 | 0 | CheckInsert( |
511 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
512 | 0 | ExpectedLocality::kGlobal); |
513 | 0 | CheckInsert( |
514 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
515 | 0 | ExpectedLocality::kGlobal); |
516 | 0 | CheckInsert( |
517 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
518 | 0 | ExpectedLocality::kGlobal); |
519 | 0 | CheckInsert( |
520 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
521 | 0 | ExpectedLocality::kGlobal); |
522 | 0 | CheckInsert( |
523 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
524 | 0 | ExpectedLocality::kGlobal); |
525 | |
|
526 | 0 | DropTables(); |
527 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_auto_create_local_transaction_tables) = false; |
528 | 0 | SetupTables(); |
529 | | |
530 | | // Transaction tables created earlier should no longer have a placement and should be unused. |
531 | 0 | CheckInsert( |
532 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
533 | 0 | ExpectedLocality::kGlobal); |
534 | 0 | CheckInsert( |
535 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
536 | 0 | ExpectedLocality::kGlobal); |
537 | 0 | CheckInsert( |
538 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
539 | 0 | ExpectedLocality::kGlobal); |
540 | 0 | CheckInsert( |
541 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
542 | 0 | ExpectedLocality::kGlobal); |
543 | 0 | CheckInsert( |
544 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
545 | 0 | ExpectedLocality::kGlobal); |
546 | 0 | CheckInsert( |
547 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
548 | 0 | ExpectedLocality::kGlobal); |
549 | 0 | CheckInsert( |
550 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
551 | 0 | ExpectedLocality::kGlobal); |
552 | 0 | CheckInsert( |
553 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
554 | 0 | ExpectedLocality::kGlobal); |
555 | 0 | } |
556 | | |
557 | | TEST_F(GeoTransactionsTest, |
558 | 0 | YB_DISABLE_TEST_IN_TSAN(TestAutomaticLocalTransactionTableCreationWithAlter)) { |
559 | 0 | ANNOTATE_UNPROTECTED_WRITE(FLAGS_auto_create_local_transaction_tables) = true; |
560 | 0 | SetupTablesWithAlter(); |
561 | | |
562 | | // The case of connecting to TS2 with force_global_transactions = false will error out |
563 | | // because it is a global transaction, see #10537. |
564 | 0 | CheckInsert( |
565 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kFalse, |
566 | 0 | ExpectedLocality::kLocal); |
567 | 0 | CheckInsert( |
568 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
569 | 0 | ExpectedLocality::kGlobal); |
570 | 0 | CheckInsert( |
571 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kFalse, |
572 | 0 | ExpectedLocality::kGlobal); |
573 | 0 | CheckInsert( |
574 | 0 | 1, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
575 | 0 | ExpectedLocality::kGlobal); |
576 | 0 | CheckInsert( |
577 | 0 | 2, SetGlobalTransactionsGFlag::kFalse, SetGlobalTransactionSessionVar::kTrue, |
578 | 0 | ExpectedLocality::kGlobal); |
579 | 0 | CheckInsert( |
580 | 0 | 1, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
581 | 0 | ExpectedLocality::kGlobal); |
582 | 0 | CheckInsert( |
583 | 0 | 2, SetGlobalTransactionsGFlag::kTrue, SetGlobalTransactionSessionVar::kTrue, |
584 | 0 | ExpectedLocality::kGlobal); |
585 | 0 | } |
586 | | |
587 | | } // namespace client |
588 | | } // namespace yb |