Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YSQL] Support DDL operations within transaction #1404

Open
ndeodhar opened this issue May 17, 2019 · 11 comments
Open

[YSQL] Support DDL operations within transaction #1404

ndeodhar opened this issue May 17, 2019 · 11 comments
Assignees
Labels
area/ysql Yugabyte SQL (YSQL) kind/enhancement This is an enhancement of an existing feature priority/medium Medium priority issue
Projects

Comments

@ndeodhar
Copy link
Contributor

ndeodhar commented May 17, 2019

Jira Link: DB-1367

In YSQL DDL execution mostly follows the same logic and code as in Postgres. However, there are several additional complexities

  1. the catalog metadata need to be safely replicated across multiple nodes and caches on all nodes appropriately invalidated
  2. storage (DocDB) objects (e.g. tablets and associated SST files, Raft groups, etc.) need to be created and modified
    This tracking issue covers the roadmap to getting Postgres-compatible behavior with respect to DDL transactions.

Phase 1: Limited Transactional DDL

In this stage, Postgres metadata changes are run in an autonomous transaction for each DDL statement. This means standalone DDL statements behaves essentially like postgres when it comes to the Postgres catalog modifications.
However:

  1. In specific cases, DocDB object modifications could fail without getting rolled back. These are done at the end (just before DDL transaction commit), but it is still possible for a failed DDL to not fully roll back DocDB changes (and require manual SQL commands to repair).
  2. For DDLs within transaction blocks, autonomous transaction means that in case the transaction block is rolled back, all executed DDL statements remain applied.
Status Task Comments
[YSQL] Limited transactional DDL: execute each DDL statement in its own separate transaction #3108 Done in b68b84b

Phase 2: Full DDL Atomicity

In this stage, storage (DocDB) object modifications are also associated with the DDL transaction and are automatically rolled back in case the parent DDL transaction fails for any reason. So this addresses limitation 1. above.

Status Task Comments
[YSQL] YSQL DDL Atomicity #13358 Done in multiple commits. Turned on by default in #22097.

Phase 3: Full transaction DDL

Transaction block of DDL and DML statements execute in the same transaction (like in Postgres). This addresses limitation 2. above.

Status Task Comments
🕓 [YSQL] Full transactional DDL: allow arbitrary mix of DDL and DML in transactions #3109 Currently in progress.
@ndeodhar ndeodhar self-assigned this May 17, 2019
@ndeodhar ndeodhar added the area/ysql Yugabyte SQL (YSQL) label May 17, 2019
@ndeodhar ndeodhar added this to To do in YSQL via automation May 17, 2019
@ndeodhar ndeodhar added this to the v2.0 milestone May 17, 2019
@rkarthik007
Copy link
Collaborator

This is being used by Hasura also IIRC, so good feature to add!

@mbautin mbautin assigned mbautin and unassigned ndeodhar Sep 9, 2019
mbautin added a commit to mbautin/yugabyte-db that referenced this issue Sep 11, 2019
Summary:
YSQL system catalog data is stored in the master Raft group. A "cotable id" is a UUID that is stored
as a prefix of all DocDB keys of a particular YSQL system table, to allow multiple such tables to
exist in the same RocksDB.  To support transactional YSQL DDL, we need to be able to correctly
generate the set of weak intents for a DocKey that includes a cotable id.

For example, if a SubDocKey is (cotable_id1, hash, (h1, h2), (r1, r2), (subkey1)), then the set of
weak intents that we generate is now as follows:

(cotable_id1)
(cotable_id1, hash, (h1, h2))
(cotable_id1, hash, (h1, h2), (r1))
(cotable_id1, hash, (h1, h2), (r1, r2))

Note that we are not generating an empty weak intent for a key with a cotable id anymore, because we
don't want to lock all YSQL system tables with such an intent, only a particular system table.

Test Plan: Jenkins

Reviewers: sergei, mihnea

Subscribers: yql

Differential Revision: https://phabricator.dev.yugabyte.com/D7178
mbautin added a commit that referenced this issue Sep 21, 2019
…sactional DDL)

Summary:
YSQL system catalog data is stored in the master Raft group. A "cotable id" is a UUID that is stored
as a prefix of all DocDB keys of a particular YSQL system table, to allow multiple such tables to
exist in the same RocksDB.  To support transactional YSQL DDL, we need to be able to correctly
generate the set of weak intents for a DocKey that includes a cotable id.

For example, if a SubDocKey is (cotable_id1, hash, (h1, h2), (r1, r2), (subkey1)), then the set of
weak intents that we generate is now as follows:

(cotable_id1)
(cotable_id1, hash, (h1, h2))
(cotable_id1, hash, (h1, h2), (r1))
(cotable_id1, hash, (h1, h2), (r1, r2))

Note that we are not generating an empty weak intent for a key with a cotable id anymore, because we
don't want to lock all YSQL system tables with such an intent, only a particular system table.

Also fix TestYsqlDump: ignore the differences in the version number and trailing whitespace and fix user name
to be yugabyte instead of postgres.

Test Plan: Jenkins

Reviewers: mihnea, sergei

Reviewed By: sergei

Subscribers: yql

Differential Revision: https://phabricator.dev.yugabyte.com/D7178
@rkarthik007 rkarthik007 removed this from the v2.0 milestone Jun 5, 2020
@sorenisanerd
Copy link

If not slated for v2.0, when can we expect to see this. Transactional DDL is a key feature of Postgres over e.g. Oracle.

What happens if I attemt to execute DDL inside a transaction with current yugabyte?

@sorenisanerd
Copy link

Does yugabyte suffer from this specific limitation, too? https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#schema-change-ddl-statements-inside-a-multi-statement-transaction-can-fail-while-other-statements-succeed

It violates the promises of a transaction.

@ndeodhar ndeodhar moved this from To do to Backlog in YSQL Aug 5, 2020
@sf-kansara
Copy link

A workaround for this would be to do DDL changes inside BEGIN block and "undo" all those changes in EXCEPTION block.

-- Setup
CREATE TABLE public.test_table_2
(
    id SERIAL,
    name VARCHAR(30),
    CONSTRAINT test_table_2_pkey PRIMARY KEY (id)
);
INSERT INTO public.test_table_2(name) VALUES ('John Doe');
INSERT INTO public.test_table_2(name) VALUES ('John Dough');

DDL change management

DO $$ 
BEGIN
	INSERT INTO public.test_table_2(name) VALUES ('abc');
	ALTER TABLE public.test_table_2 ADD COLUMN new_column VARCHAR(2) DEFAULT NULL;
	INSERT INTO public.test_table_2(name, new_column) VALUES ('abc', 'abcdefgh');
EXCEPTION WHEN OTHERS THEN
	ALTER TABLE public.test_table_2 DROP COLUMN new_column;
	RAISE EXCEPTION USING ERRCODE = SQLSTATE, MESSAGE = SQLERRM;
END $$;

Notice that first "legal" insert is also rolled back and we manually reverted DDL changes in EXCEPTION block.

@yugabyte-ci yugabyte-ci added kind/bug This issue is a bug priority/medium Medium priority issue labels Jun 8, 2022
@yugabyte-ci yugabyte-ci added kind/enhancement This is an enhancement of an existing feature and removed kind/bug This issue is a bug labels Oct 12, 2022
@sybbear
Copy link

sybbear commented Nov 30, 2022

Very much needed feature for intensely evolving DB schema.
Any plans to implement this in the near future?

@78bits
Copy link

78bits commented Feb 23, 2024

can we vote this issue up a bit ? Yugabyte is not usable when creeate/drop table operations can cause incosistent states for the database

@78bits
Copy link

78bits commented Apr 20, 2024

The task just links back to this thread. The lack of this feature renders Yugabyte unusable for every projects that rely on automigrations

@mrajcevic01
Copy link
Contributor

@78bits @sybbear @sorenisanerd we have updated this issue with additional insights into the work we have been putting into the phased approach of supporting DDL operations within transactions. Please let us know if you have additional questions.

@78bits
Copy link

78bits commented Jun 4, 2024

Great to hear, but it still does not work. I picked up on the good news and started a quick test :

  1. firing up a yugabyte instance from docker (version version 2.21.0.1 build 1)
  2. running this query
    ``create schema test;

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

rollback;
begin;

drop table if exists test.value_types cascade;
CREATE TABLE test.value_types (
id UUID NOT NULL DEFAULT uuid_generate_v4(),
type VARCHAR NOT NULL,
description VARCHAR NOT NULL,
CONSTRAINT "value_types_primary" PRIMARY KEY (id)
);

INSERT INTO
test.value_types (type, description)
VALUES
('int', 'Integer -2^32 .. +2^32'),
('float', 'Floating value'),
('string', 'String value');

drop table if exists test.entries;
CREATE TABLE test.entries (
id UUID NOT NULL DEFAULT uuid_generate_v4() PRIMARY KEY,
type_id UUID NOT null REFERENCES test.value_types (id)
);

commit;

select * from test.entries;```
The transaction fails, but the tables are created anyhow.

@mrajcevic01
Copy link
Contributor

mrajcevic01 commented Jun 4, 2024

@78bits did you enable the flags called out #22097 before attempting this? I am reaching out internally to confirm but it does not appear that these will be enabled by default until v2024.1 (which should be available here soon)

EDIT: I was able to confirm that we enabled this by default in v2024.1. We do not recommend using it in v2.20+ because some recent bug fixes were only made in 2024.1 but not backported earlier.

@78bits
Copy link

78bits commented Jun 5, 2024

Adding those flags (--ysql_yb_ddl_rollback_enabled,--report_ysql_ddl_txn_status_to_master,--ysql_ddl_transaction_wait_for_ddl_verification) made the script work. Thank you

@yugabyte-ci yugabyte-ci added kind/new-feature This is a request for a completely new feature kind/enhancement This is an enhancement of an existing feature and removed kind/enhancement This is an enhancement of an existing feature kind/new-feature This is a request for a completely new feature labels Jul 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ysql Yugabyte SQL (YSQL) kind/enhancement This is an enhancement of an existing feature priority/medium Medium priority issue
Projects
Status: No status
YSQL
  
Backlog
Development

No branches or pull requests