-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#19189] xClusterDDLRepl: Handle Create Index
Summary: Adding support for create index. Cleaning up handling of ddl_command_end event trigger on the source, swapping to use command_tags in pg_event_trigger_ddl_commands instead of the tag that EventTriggerData provides. This approach is more flexible for processing queries that produce multiple commands. Combining CREATE TABLE and CREATE INDEX processing as they share the same checks required for the extension (temp, primary indexes, colocated). Jira: DB-7982 Test Plan: ``` ybd --cxx-test xcluster_ddl_replication-test --gtest_filter "XClusterDDLReplicationTest.CreateIndex" ybd --java-test "org.yb.pgsql.TestPgRegressYbExtensionsYbXclusterDdlReplication" ``` Reviewers: hsunder, xCluster Reviewed By: hsunder Subscribers: ybase, yql Differential Revision: https://phorge.dev.yugabyte.com/D34683
- Loading branch information
Showing
13 changed files
with
313 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/postgres/yb-extensions/yb_xcluster_ddl_replication/expected/create_index.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
CALL TEST_reset(); | ||
SET yb_xcluster_ddl_replication.replication_role = DISABLED; | ||
CREATE SCHEMA create_index; | ||
SET search_path TO create_index; | ||
-- Test temp table and index. | ||
SET yb_xcluster_ddl_replication.replication_role = SOURCE; | ||
CREATE TEMP TABLE temp_foo(i int PRIMARY KEY, a int); | ||
CREATE INDEX foo_idx_temp on temp_foo(a); | ||
SELECT yb_data FROM yb_xcluster_ddl_replication.ddl_queue ORDER BY start_time; | ||
yb_data | ||
--------- | ||
(0 rows) | ||
|
||
SET yb_xcluster_ddl_replication.replication_role = BIDIRECTIONAL; | ||
-- Create base table. | ||
CREATE TABLE foo(i int PRIMARY KEY, a int, b text, c int); | ||
-- Create indexes. | ||
CREATE INDEX foo_idx_simple ON foo(a); | ||
CREATE UNIQUE INDEX foo_idx_unique ON foo(b); | ||
CREATE INDEX foo_idx_filtered ON foo(c ASC, a) WHERE a > c; | ||
CREATE INDEX foo_idx_include ON foo(lower(b)) INCLUDE (a) SPLIT INTO 2 TABLETS; | ||
SELECT yb_data FROM yb_xcluster_ddl_replication.ddl_queue ORDER BY start_time; | ||
yb_data | ||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
{"user": "yugabyte", "query": "CREATE TABLE foo(i int PRIMARY KEY, a int, b text, c int);", "schema": "create_index", "version": 1, "command_tag": "CREATE TABLE"} | ||
{"user": "yugabyte", "query": "CREATE INDEX foo_idx_simple ON foo(a);", "schema": "create_index", "version": 1, "command_tag": "CREATE INDEX"} | ||
{"user": "yugabyte", "query": "CREATE UNIQUE INDEX foo_idx_unique ON foo(b);", "schema": "create_index", "version": 1, "command_tag": "CREATE INDEX"} | ||
{"user": "yugabyte", "query": "CREATE INDEX foo_idx_filtered ON foo(c ASC, a) WHERE a > c;", "schema": "create_index", "version": 1, "command_tag": "CREATE INDEX"} | ||
{"user": "yugabyte", "query": "CREATE INDEX foo_idx_include ON foo(lower(b)) INCLUDE (a) SPLIT INTO 2 TABLETS;", "schema": "create_index", "version": 1, "command_tag": "CREATE INDEX"} | ||
(5 rows) | ||
|
||
SELECT * FROM yb_xcluster_ddl_replication.replicated_ddls ORDER BY start_time; | ||
start_time | query_id | yb_data | ||
------------+----------+---------------------------------------------------------------------------------------------- | ||
1 | 1 | {"query": "CREATE TABLE foo(i int PRIMARY KEY, a int, b text, c int);"} | ||
2 | 1 | {"query": "CREATE INDEX foo_idx_simple ON foo(a);"} | ||
3 | 1 | {"query": "CREATE UNIQUE INDEX foo_idx_unique ON foo(b);"} | ||
4 | 1 | {"query": "CREATE INDEX foo_idx_filtered ON foo(c ASC, a) WHERE a > c;"} | ||
5 | 1 | {"query": "CREATE INDEX foo_idx_include ON foo(lower(b)) INCLUDE (a) SPLIT INTO 2 TABLETS;"} | ||
(5 rows) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/postgres/yb-extensions/yb_xcluster_ddl_replication/source_ddl_end_handler.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright (c) YugaByte, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
// use this file except in compliance with the License. You may obtain a copy | ||
// of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations under | ||
// the License. | ||
|
||
#include "source_ddl_end_handler.h" | ||
|
||
#include "executor/spi.h" | ||
#include "lib/stringinfo.h" | ||
|
||
#include "extension_util.h" | ||
#include "pg_yb_utils.h" | ||
|
||
#define OBJID_COLUMN_ID 1 | ||
#define COMMAND_TAG_COLUMN_ID 2 | ||
|
||
bool | ||
ShouldReplicateCreateRelation(Oid rel_oid) | ||
{ | ||
Relation rel = RelationIdGetRelation(rel_oid); | ||
// Ignore temporary tables and primary indexes (same as main table). | ||
if (!IsYBBackedRelation(rel) || | ||
(rel->rd_rel->relkind == RELKIND_INDEX && rel->rd_index->indisprimary)) | ||
{ | ||
RelationClose(rel); | ||
return false; | ||
} | ||
|
||
// Also need to disallow colocated objects until that is supported. | ||
YbTableProperties table_props = YbGetTableProperties(rel); | ||
bool is_colocated = table_props->is_colocated; | ||
RelationClose(rel); | ||
if (is_colocated) | ||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), | ||
errmsg("Colocated objects are not yet supported by " | ||
"yb_xcluster_ddl_replication\n%s", | ||
kManualReplicationErrorMsg))); | ||
|
||
return true; | ||
} | ||
|
||
bool | ||
ProcessSourceEventTriggerDDLCommands(JsonbParseState *state) | ||
{ | ||
StringInfoData query_buf; | ||
initStringInfo(&query_buf); | ||
appendStringInfo(&query_buf, "SELECT objid, command_tag FROM " | ||
"pg_catalog.pg_event_trigger_ddl_commands()"); | ||
int exec_res = SPI_execute(query_buf.data, true, 0); | ||
if (exec_res != SPI_OK_SELECT) | ||
elog(ERROR, "SPI_exec failed (error %d): %s", exec_res, query_buf.data); | ||
|
||
TupleDesc spiTupDesc = SPI_tuptable->tupdesc; | ||
|
||
// As long as there is at least one command that needs to be replicated, we | ||
// will set this to true and replicate the entire query string. | ||
bool should_replicate_ddl = false; | ||
for (int row = 0; row < SPI_processed; row++) | ||
{ | ||
HeapTuple spiTuple = SPI_tuptable->vals[row]; | ||
bool is_null; | ||
Oid objid = DatumGetObjectId( | ||
SPI_getbinval(spiTuple, spiTupDesc, OBJID_COLUMN_ID, &is_null)); | ||
if (is_null) | ||
elog(ERROR, "Found NULL value when parsing objid"); | ||
|
||
const char *command_tag = | ||
SPI_getvalue(spiTuple, spiTupDesc, COMMAND_TAG_COLUMN_ID); | ||
|
||
if (strncmp(command_tag, "CREATE TABLE", 12) == 0 || | ||
strncmp(command_tag, "CREATE INDEX", 12) == 0) | ||
{ | ||
should_replicate_ddl |= ShouldReplicateCreateRelation(objid); | ||
} | ||
else | ||
{ | ||
elog(ERROR, "Unsupported DDL: %s\n%s", command_tag, | ||
kManualReplicationErrorMsg); | ||
} | ||
} | ||
|
||
return should_replicate_ddl; | ||
} |
34 changes: 34 additions & 0 deletions
34
src/postgres/yb-extensions/yb_xcluster_ddl_replication/source_ddl_end_handler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) YugaByte, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
// use this file except in compliance with the License. You may obtain a copy | ||
// of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations under | ||
// the License. | ||
|
||
#ifndef YB_XCLUSTER_DDL_REPLICATION_SOURCE_DDL_END | ||
#define YB_XCLUSTER_DDL_REPLICATION_SOURCE_DDL_END | ||
|
||
#include "postgres.h" | ||
#include "utils/jsonb.h" | ||
|
||
/* | ||
* Iterate over pg_catalog.pg_event_trigger_ddl_commands() and process each base | ||
* command (a single query may be composed of multiple base commands). | ||
* | ||
* There are three return cases for this function: | ||
* 1. The DDL contains some unsupported command - This function throws an error | ||
* which aborts the transaction. | ||
* 2. The DDL is valid but does not need to be replicated (eg all the objects in | ||
* the DDL are temp) - This function returns false. | ||
* 3. The DDL is valid and should be replicated - This function returns true. | ||
*/ | ||
bool ProcessSourceEventTriggerDDLCommands(JsonbParseState *state); | ||
|
||
#endif |
28 changes: 28 additions & 0 deletions
28
src/postgres/yb-extensions/yb_xcluster_ddl_replication/sql/create_index.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
CALL TEST_reset(); | ||
|
||
SET yb_xcluster_ddl_replication.replication_role = DISABLED; | ||
CREATE SCHEMA create_index; | ||
SET search_path TO create_index; | ||
|
||
-- Test temp table and index. | ||
SET yb_xcluster_ddl_replication.replication_role = SOURCE; | ||
CREATE TEMP TABLE temp_foo(i int PRIMARY KEY, a int); | ||
CREATE INDEX foo_idx_temp on temp_foo(a); | ||
|
||
SELECT yb_data FROM yb_xcluster_ddl_replication.ddl_queue ORDER BY start_time; | ||
SET yb_xcluster_ddl_replication.replication_role = BIDIRECTIONAL; | ||
|
||
-- Create base table. | ||
CREATE TABLE foo(i int PRIMARY KEY, a int, b text, c int); | ||
|
||
-- Create indexes. | ||
CREATE INDEX foo_idx_simple ON foo(a); | ||
|
||
CREATE UNIQUE INDEX foo_idx_unique ON foo(b); | ||
|
||
CREATE INDEX foo_idx_filtered ON foo(c ASC, a) WHERE a > c; | ||
|
||
CREATE INDEX foo_idx_include ON foo(lower(b)) INCLUDE (a) SPLIT INTO 2 TABLETS; | ||
|
||
SELECT yb_data FROM yb_xcluster_ddl_replication.ddl_queue ORDER BY start_time; | ||
SELECT * FROM yb_xcluster_ddl_replication.replicated_ddls ORDER BY start_time; |
3 changes: 1 addition & 2 deletions
3
src/postgres/yb-extensions/yb_xcluster_ddl_replication/yb_schedule
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
# contrib/yb_xcluster_ddl_replication/yb_schedule | ||
|
||
test: setup | ||
test: create_table | ||
test: create_index | ||
|
||
test: colocated_setup | ||
test: create_colocated_table |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.