Skip to content

Commit

Permalink
[#10783] geo: Automatic creation of transaction status tables
Browse files Browse the repository at this point in the history
Summary:
Added attempt to automatically create local transaction status tables when a table is
created using a tablespace that has placement information set, if no such table has been created
for the tablespace yet; the transaction status table created will use the placement information
of the tablespace.

Depends on D13957.

Test Plan: Added GeoTransactionsTest.TestAutomaticLocalTransactionTableCreation; updated org.yb.pgsql.TestTablespaceProperties to check for placement of created transaction tables.

Reviewers: bogdan, mbautin, sergei, dsrinivasan

Reviewed By: sergei, dsrinivasan

Subscribers: sergei, rthallam, ybase

Differential Revision: https://phabricator.dev.yugabyte.com/D14255
  • Loading branch information
es1024 committed Feb 11, 2022
1 parent 959a82c commit add3cec
Show file tree
Hide file tree
Showing 10 changed files with 556 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.yb.AssertionWrappers.*;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
Expand Down Expand Up @@ -56,7 +57,13 @@ public class TestTablespaceProperties extends BasePgSQLTest {

private static final int MASTER_LOAD_BALANCER_WAIT_TIME_MS = 60 * 1000;

private List<Map<String, String>> perTserverZonePlacementFlags = Arrays.asList(
private static final int TRANSACTION_TABLE_NUM_TABLETS = 4;

private static final int LOAD_BALANCER_MAX_CONCURRENT = 10;

private static final String tablespaceName = "testTablespace";

private static final List<Map<String, String>> perTserverZonePlacementFlags = Arrays.asList(
ImmutableMap.of(
"placement_cloud", "cloud1",
"placement_region", "region1",
Expand All @@ -69,6 +76,7 @@ public class TestTablespaceProperties extends BasePgSQLTest {
"placement_cloud", "cloud3",
"placement_region", "region3",
"placement_zone", "zone3"));

@Override
public int getTestMethodTimeoutSec() {
return getPerfMaxRuntime(1500, 1700, 2000, 2000, 2000);
Expand All @@ -81,14 +89,37 @@ protected void customizeMiniClusterBuilder(MiniYBClusterBuilder builder) {
builder.addMasterFlag("vmodule", "sys_catalog=5,cluster_balance=1");
builder.addMasterFlag("ysql_tablespace_info_refresh_secs",
Integer.toString(MASTER_REFRESH_TABLESPACE_INFO_SECS));
builder.addMasterFlag("auto_create_local_transaction_tables", "true");
builder.addMasterFlag("TEST_name_transaction_tables_with_tablespace_id", "true");

// Default behavior is to scale based on number of CPU cores, which will make
// load balancing transaction tables too much time and time out tests.
builder.addMasterFlag("transaction_table_num_tablets",
Integer.toString(TRANSACTION_TABLE_NUM_TABLETS));

// We wait for the load balancer whenever it gets triggered anyways, so there's
// no concerns about the load balancer taking too many resources.
builder.addMasterFlag("load_balancer_max_concurrent_tablet_remote_bootstraps",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));
builder.addMasterFlag("load_balancer_max_concurrent_tablet_remote_bootstraps_per_table",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));
builder.addMasterFlag("load_balancer_max_concurrent_adds",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));
builder.addMasterFlag("load_balancer_max_concurrent_removals",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));
builder.addMasterFlag("load_balancer_max_concurrent_moves",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));
builder.addMasterFlag("load_balancer_max_concurrent_moves_per_table",
Integer.toString(LOAD_BALANCER_MAX_CONCURRENT));

builder.perTServerFlags(perTserverZonePlacementFlags);
}

@Before
public void setupTablespaces() throws Exception {
try (Statement setupStatement = connection.createStatement()) {
setupStatement.execute(
" CREATE TABLESPACE testTablespace " +
" CREATE TABLESPACE " + tablespaceName +
" WITH (replica_placement=" +
"'{\"num_replicas\":2, \"placement_blocks\":" +
"[{\"cloud\":\"cloud1\",\"region\":\"region1\",\"zone\":\"zone1\"," +
Expand Down Expand Up @@ -141,10 +172,11 @@ private void createTestData (String prefixName) throws Exception {
setupStatement.execute(
"CREATE TABLE " + tableInCustomTablegroup + "(a SERIAL) TABLEGROUP " + customTablegroup);
}
String transactionTableName = getTablespaceTransactionTableName();
tablesWithDefaultPlacement.addAll(Arrays.asList(defaultTable, defaultIndex,
defaultIndexCustomTable, tableInDefaultTablegroup));
tablesWithCustomPlacement.addAll(Arrays.asList(customTable, customIndex,
customIndexCustomTable, tableInCustomTablegroup));
customIndexCustomTable, tableInCustomTablegroup, transactionTableName));
}

private void addTserversAndWaitForLB() throws Exception {
Expand Down Expand Up @@ -522,6 +554,16 @@ void verifyDefaultPlacement(final String table) throws Exception {
}
}

public String getTablespaceTransactionTableName() throws Exception {
try (Statement setupStatement = connection.createStatement()) {
ResultSet s = setupStatement.executeQuery(
"SELECT oid FROM pg_catalog.pg_tablespace " +
"WHERE UPPER(spcname) = UPPER('" + tablespaceName + "')");
assertTrue(s.next());
return "transactions_" + s.getInt(1);
}
}

YBTable getTableFromName(final String table) throws Exception {
final YBClient client = miniCluster.getClient();
List<MasterDdlOuterClass.ListTablesResponsePB.TableInfo> tables =
Expand Down
12 changes: 10 additions & 2 deletions src/yb/master/catalog_entity_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <string>

#include "yb/common/doc_hybrid_time.h"
#include "yb/common/transaction.h"
#include "yb/common/wire_protocol.h"

#include "yb/master/master_client.pb.h"
Expand All @@ -45,6 +46,7 @@
#include "yb/util/atomic.h"
#include "yb/util/format.h"
#include "yb/util/status_format.h"
#include "yb/util/string_util.h"

using std::string;

Expand Down Expand Up @@ -768,8 +770,14 @@ IndexInfo TableInfo::GetIndexInfo(const TableId& index_id) const {

bool TableInfo::UsesTablespacesForPlacement() const {
auto l = LockForRead();
return l->pb.table_type() == PGSQL_TABLE_TYPE && !IsColocatedUserTable() &&
l->namespace_id() != kPgSequencesDataNamespaceId;
// Global transaction table is excluded due to not having a tablespace id set.
bool is_transaction_table_using_tablespaces =
l->pb.table_type() == TRANSACTION_STATUS_TABLE_TYPE &&
l->pb.has_transaction_table_tablespace_id();
bool is_regular_pgsql_table =
l->pb.table_type() == PGSQL_TABLE_TYPE && !IsColocatedUserTable() &&
l->namespace_id() != kPgSequencesDataNamespaceId;
return is_transaction_table_using_tablespaces || is_regular_pgsql_table;
}

bool TableInfo::IsTablegroupParentTable() const {
Expand Down
4 changes: 0 additions & 4 deletions src/yb/master/catalog_entity_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,6 @@ class TableInfo : public RefCountedThreadSafe<TableInfo>,
return GetTableType() == REDIS_TABLE_TYPE;
}

bool IsTransactionStatusTable() const {
return GetTableType() == TRANSACTION_STATUS_TABLE_TYPE;
}

// Add a tablet to this table.
void AddTablet(const TabletInfoPtr& tablet);

Expand Down
4 changes: 4 additions & 0 deletions src/yb/master/catalog_entity_info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ message SysTablesEntryPB {
repeated BackfillJobPB backfill_jobs = 32;

optional HideState hide_state = 33;

// Tablespace ID for use with transaction tables only. Normal YSQL tables do not set this field,
// and tablespace information for such tables are instead fetched by scanning the pg catalog.
optional bytes transaction_table_tablespace_id = 34;
}

// The on-disk entry in the sys.catalog table ("metadata" column) for
Expand Down
9 changes: 7 additions & 2 deletions src/yb/master/catalog_loaders.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,13 @@ Status TableLoader::Visit(const TableId& table_id, const SysTablesEntryPB& metad
// add Postgres tables to the name map as the table name is not unique in a namespace.
auto table_ids_map_checkout = catalog_manager_->table_ids_map_.CheckOut();
(*table_ids_map_checkout)[table->id()] = table;
if (l->table_type() != PGSQL_TABLE_TYPE && !l->started_deleting() && !l->started_hiding()) {
catalog_manager_->table_names_map_[{l->namespace_id(), l->name()}] = table;
if (!l->started_deleting() && !l->started_hiding()) {
if (l->table_type() != PGSQL_TABLE_TYPE) {
catalog_manager_->table_names_map_[{l->namespace_id(), l->name()}] = table;
}
if (l->table_type() == TRANSACTION_STATUS_TABLE_TYPE) {
catalog_manager_->transaction_table_ids_set_.insert(table_id);
}
}

l.Commit();
Expand Down
Loading

0 comments on commit add3cec

Please sign in to comment.