YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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