[BACKPORT 2025.2][#6640] YSQL: Support ALTER TABLESPACE SET/RESET for placement options (#31948)#32113
[BACKPORT 2025.2][#6640] YSQL: Support ALTER TABLESPACE SET/RESET for placement options (#31948)#32113kai-franz wants to merge 1 commit into
Conversation
…ESET for placement options (yugabyte#31948) This patch makes `ALTER TABLESPACE ... SET/RESET` work for the YB placement options (`replica_placement` and `read_replica_placement`), so an existing tablespace can be updated in place. This avoids the awkward evolution of tablespace definitions which require creating new ts, altering all relations that use it, and then deleting the old ts. tracking issue: yugabyte#6640 Some details: - `ALTER TABLESPACE` validates the final `spcoptions` the same way we validate `ALTER TABLE/INDEX/MATERIALIZED VIEW ... SET TABLESPACE`. - If the tablespace is already in use, the new placement has to be satisfiable - Existing objects are not moved synchronously. We keep using the current master tablespace refresh + load balancer path, so movement happens asynchronously after the new tablespace options are picked up - `read_replica_placement` still requires `replica_placement`, so `RESET (replica_placement)` fails if `read_replica_placement` is still set. Test coverage added for: - `ALTER TABLESPACE ... SET/RESET` regression cases - movement for tables, indexes, materialized views, and tablegroups - reset behavior - invalid placement / invalid JSON cases - read replica validation, including the `RESET (replica_placement)` case above Also includes YSQL docs for `ALTER TABLESPACE`. Tested successfully with: - `./yb_build.sh release --target postgres --skip-java --no-odyssey` - `JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test org.yb.pgsql.TestPgRegressTablespaces` - `JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#testAlterTablespacePlacementMovesExistingObjects'` - `JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#negativeTest'` - `JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#readReplicaWithTablespaces'` Practical testing with `ysqlsh`: ```sql yugabyte=# select spcname, spcoptions from pg_tablespace where spcname = 'ats_unused'; spcname | spcoptions ------------+------------ ats_unused | (1 row) yugabyte=# \set valid_placement '{"num_replicas":1,"placement_blocks":[{"cloud":"cloud1","region":"datacenter1","zone":"rack1","min_num_replicas":1}]}' yugabyte=# \echo :valid_placement {"num_replicas":1,"placement_blocks":[{"cloud":"cloud1","region":"datacenter1","zone":"rack1","min_num_replicas":1}]} yugabyte=# ALTER TABLESPACE ats_unused SET ( replica_placement=:'valid_placement', read_replica_placement=:'valid_placement' ); ALTER TABLESPACE yugabyte=# select spcname, spcoptions from pg_tablespace where spcname = 'ats_unused'; spcname | spcoptions ------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ats_unused | {"replica_placement={\"num_replicas\":1,\"placement_blocks\":[{\"cloud\":\"cloud1\",\"region\":\"datacenter1\",\"zone\":\"rack1\",\"min_num_replicas\":1}]}","read_replica_placement={\"num_replicas\":1,\"placement_blocks\":[{\"cloud\":\"cloud1\",\"region\":\"datacenter1\",\"zone\":\"rack1\",\"min_num_replicas\":1}]}"} (1 row) yugabyte=# ALTER TABLESPACE ats_unused RESET (replica_placement); ERROR: read_replica_placement option requires replica_placement to be set yugabyte=# ALTER TABLESPACE ats_unused RESET (read_replica_placement); ALTER TABLESPACE yugabyte=# select spcname, spcoptions from pg_tablespace where spcname = 'ats_unused'; spcname | spcoptions ------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------- ats_unused | {"replica_placement={\"num_replicas\":1,\"placement_blocks\":[{\"cloud\":\"cloud1\",\"region\":\"datacenter1\",\"zone\":\"rack1\",\"min_num_replicas\":1}]}"} (1 row) yugabyte=# ALTER TABLESPACE ats_unused RESET (replica_placement); ALTER TABLESPACE yugabyte=# select spcname, spcoptions from pg_tablespace where spcname = 'ats_unused'; spcname | spcoptions ------------+------------ ats_unused | (1 row) ``` Original commit: 0af82c6 / yugabyte#31948
|
Trigger Jenkins |
|
Jenkins build has been triggered. Results will be available in the CI checks. CSI |
There was a problem hiding this comment.
Code Review
This pull request implements support for the ALTER TABLESPACE statement in YugabyteDB, allowing users to change or reset replica and read-replica placement options. It includes validation of placement options, asynchronous data movement handling for dependent objects, comprehensive Java and regression tests, and updated documentation. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
DO NOT MERGE!! CSI ❌. Once CSI passes, comment
trigger jenkinsto clear this warning.This patch makes
ALTER TABLESPACE ... SET/RESETwork for the YBplacement options (
replica_placementandread_replica_placement), soan existing tablespace can be updated in place. This avoids the awkward
evolution of tablespace definitions which require creating new ts,
altering all relations that use it, and then deleting the old ts.
tracking issue: #6640
Some details:
ALTER TABLESPACEvalidates the finalspcoptionsthe same way wevalidate
ALTER TABLE/INDEX/MATERIALIZED VIEW ... SET TABLESPACE.satisfiable
current master tablespace refresh + load balancer path, so movement
happens asynchronously after the new tablespace options are picked up
read_replica_placementstill requiresreplica_placement, soRESET (replica_placement)fails ifread_replica_placementis still set.Test coverage added for:
ALTER TABLESPACE ... SET/RESETregression casesRESET (replica_placement)case above
Also includes YSQL docs for
ALTER TABLESPACE.Tested successfully with:
./yb_build.sh release --target postgres --skip-java --no-odysseyJAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test org.yb.pgsql.TestPgRegressTablespacesJAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#testAlterTablespacePlacementMovesExistingObjects'JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#negativeTest'JAVA_TOOL_OPTIONS='--add-opens=java.base/java.lang=ALL-UNNAMED' ./yb_build.sh release --java-test 'org.yb.pgsql.TestTablespaceProperties#readReplicaWithTablespaces'Practical testing with
ysqlsh:Original commit: 0af82c6 / #31948
Merge conflicts
docs/content/stable/api/ysql/the-sql-language/statements/_index.md— DDL statement-list table had diverged from master (2025.2 wraps statement links in backticks and omits trailing slashes; master had since dropped the backticks, added trailing slashes, and aDROP VIEWrow). Kept 2025.2's existing formatting and inserted only the single new row this change introduces —| [ALTER TABLESPACE](ddl_alter_tablespace) | Change tablespace placement options |— after theALTER TABLErow, without pulling in the unrelated reformatting.automated · Claude Code (Opus 4.8)