Skip to content

Restore RBAC objects across different user_directories types - #1549

Open
Slach wants to merge 2 commits into
masterfrom
restore_rbac_different_storage
Open

Restore RBAC objects across different user_directories types#1549
Slach wants to merge 2 commits into
masterfrom
restore_rbac_different_storage

Conversation

@Slach

@Slach Slach commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

fix #881

RBAC objects live either in a local_directory user directory as <access_control_path>/<uuid>.sql files, or in a replicated one as znodes under <zookeeper_path>. A backup carries both shapes, but restore only ever routed each half into the storage it came from, so restoring onto a server with a different user_directories layout silently dropped half of the backup while still reporting success: a Keeper dump had no target and was skipped, and *.sql files were copied into a directory clickhouse-server does not read.

The serialized entity blob is byte identical in both storages (serializeAccessEntity in DiskAccessStorage.cpp and ZooKeeperReplicator.cpp), so the conversion is a file/znode move plus the <type char>/<escaped name> index znode, no SQL rewriting and no UUID remapping. Restore now converts whichever half has no matching target storage, and fails explicitly when the server has neither a local nor a replicated user directory instead of reporting success.

The local-directory probe in isRBACExists is gated on the presence of a local_directory user directory, so dropExistsRBAC can no longer remove *.sql files from a directory clickhouse-server does not read.

keeper gains WalkDumpFile, Upsert, EnsureNode and ResolvePath, shared by Restore, the conflict resolver and the new converters; this also fixes the legacy DumpNodeString fallback in Restore, which parsed old-format dumps but never copied the result back, restoring empty znodes.

RBAC objects live either in a `local_directory` user directory as
`<access_control_path>/<uuid>.sql` files, or in a `replicated` one as
znodes under `<zookeeper_path>`. A backup carries both shapes, but
restore only ever routed each half into the storage it came from, so
restoring onto a server with a different user_directories layout
silently dropped half of the backup while still reporting success:
a Keeper dump had no target and was skipped, and *.sql files were
copied into a directory clickhouse-server does not read.

The serialized entity blob is byte identical in both storages
(serializeAccessEntity in DiskAccessStorage.cpp and
ZooKeeperReplicator.cpp), so the conversion is a file/znode move plus
the `<type char>/<escaped name>` index znode, no SQL rewriting and no
UUID remapping. Restore now converts whichever half has no matching
target storage, and fails explicitly when the server has neither a
local nor a replicated user directory instead of reporting success.

The local-directory probe in isRBACExists is gated on the presence of a
`local_directory` user directory, so dropExistsRBAC can no longer remove
*.sql files from a directory clickhouse-server does not read.

keeper gains WalkDumpFile, Upsert, EnsureNode and ResolvePath, shared by
Restore, the conflict resolver and the new converters; this also fixes
the legacy DumpNodeString fallback in Restore, which parsed old-format
dumps but never copied the result back, restoring empty znodes.

fix #881

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Slach Slach added this to the 2.8.1 milestone Sep 11, 2026
Keep ReadMe.md focused on configuration and commands, the how-to text
belongs next to the other use cases in Examples.md, linked from the
ReadMe.md examples list like the rest of them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

allow to restore RBAC objects into different type of user_directories

1 participant