备份和还原授权
升级后,如果 UDx 库的原型发生更改,Vertica 将丢弃对这些库的授权,因为它们在技术上不再具有相同的功能。要解决这些类型的问题,最佳实践是备份对这些库的授权,以便可以在升级后还原它们。
-
将以下 SQL 保存到名为
user_ddl.sql
的文件中。它创建一个名为 user_ddl 的视图,其中包含对数据库中所有对象的授权。CREATE OR REPLACE VIEW user_ddl AS ( SELECT 0 as grant_order, name principal_name, 'CREATE ROLE "' || name || '"' || ';' AS sql, 'NONE' AS object_type, 'NONE' AS object_name FROM v_internal.vs_roles vr WHERE NOT vr.predefined_role -- Exclude system roles AND ldapdn = '' -- Limit to NON-LDAP created roles ) UNION ALL ( SELECT 1, -- CREATE USERs user_name, 'CREATE USER "' || user_name || '"' || DECODE(is_locked, TRUE, ' ACCOUNT LOCK', '') || DECODE(grace_period, 'undefined', '', ' GRACEPERIOD ''' || grace_period || '''') || DECODE(idle_session_timeout, 'unlimited', '', ' IDLESESSIONTIMEOUT ''' || idle_session_timeout || '''') || DECODE(max_connections, 'unlimited', '', ' MAXCONNECTIONS ' || max_connections || ' ON ' || connection_limit_mode) || DECODE(memory_cap_kb, 'unlimited', '', ' MEMORYCAP ''' || memory_cap_kb || 'K''') || DECODE(profile_name, 'default', '', ' PROFILE ' || profile_name) || DECODE(resource_pool, 'general', '', ' RESOURCE POOL ' || resource_pool) || DECODE(run_time_cap, 'unlimited', '', ' RUNTIMECAP ''' || run_time_cap || '''') || DECODE(search_path, '', '', ' SEARCH_PATH ' || search_path) || DECODE(temp_space_cap_kb, 'unlimited', '', ' TEMPSPACECAP ''' || temp_space_cap_kb || 'K''') || ';' AS sql, 'NONE' AS object_type, 'NONE' AS object_name FROM v_catalog.users WHERE NOT is_super_user -- Exclude database superuser AND ldap_dn = '' -- Limit to NON-LDAP created users ) UNION ALL ( SELECT 2, -- GRANTs grantee, 'GRANT ' || REPLACE(TRIM(BOTH ' ' FROM words), '*', '') || CASE WHEN object_type = 'RESOURCEPOOL' THEN ' ON RESOURCE POOL ' WHEN object_type = 'STORAGELOCATION' THEN ' ON LOCATION ' WHEN object_type = 'CLIENTAUTHENTICATION' THEN 'AUTHENTICATION ' WHEN object_type IN ('DATABASE', 'LIBRARY', 'MODEL', 'SEQUENCE', 'SCHEMA') THEN ' ON ' || object_type || ' ' WHEN object_type = 'PROCEDURE' THEN (SELECT ' ON ' || CASE REPLACE(procedure_type, 'User Defined ', '') WHEN 'Transform' THEN 'TRANSFORM FUNCTION ' WHEN 'Aggregate' THEN 'AGGREGATE FUNCTION ' WHEN 'Analytic' THEN 'ANALYTIC FUNCTION ' ELSE UPPER(REPLACE(procedure_type, 'User Defined ', '')) || ' ' END FROM vs_procedures WHERE proc_oid = object_id) WHEN object_type = 'ROLE' THEN '' ELSE ' ON ' END || NVL2(object_schema, object_schema || '.', '') || CASE WHEN object_type = 'STORAGELOCATION' THEN (SELECT '''' || location_path || ''' ON ' || node_name FROM storage_locations WHERE location_id = object_id) ELSE object_name END || CASE WHEN object_type = 'PROCEDURE' THEN (SELECT CASE WHEN procedure_argument_types = '' OR procedure_argument_types = 'Any' THEN '()' ELSE '(' || procedure_argument_types || ')' END FROM vs_procedures WHERE proc_oid = object_id) ELSE '' END || ' TO ' || grantee || CASE WHEN INSTR(words, '*') > 0 THEN ' WITH GRANT OPTION' ELSE '' END || ';', object_type, object_name FROM (SELECT grantee, object_type, object_schema, object_name, object_id, v_txtindex.StringTokenizerDelim(DECODE(privileges_description, '', ',' , privileges_description), ',') OVER (PARTITION BY grantee, object_type, object_schema, object_name, object_id) FROM v_catalog.grants) foo ORDER BY CASE REPLACE(TRIM(BOTH ' ' FROM words), '*', '') WHEN 'USAGE' THEN 1 ELSE 2 END ) UNION ALL ( SELECT 3, -- Default ROLEs user_name, 'ALTER USER "' || user_name || '"' || DECODE(default_roles, '', '', ' DEFAULT ROLE ' || REPLACE(default_roles, '*', '')) || ';' , 'NONE' AS object_type, 'NONE' AS object_name FROM v_catalog.users WHERE default_roles <> '' ) UNION ALL -- GRANTs WITH ADMIN OPTION ( SELECT 4, user_name, 'GRANT ' || REPLACE(TRIM(BOTH ' ' FROM words), '*', '') || ' TO ' || user_name || ' WITH ADMIN OPTION;', 'NONE' AS object_type , 'NONE' AS object_name FROM (SELECT user_name, v_txtindex.StringTokenizerDelim(DECODE(all_roles, '', ',', all_roles), ',') OVER (PARTITION BY user_name) FROM v_catalog.users WHERE all_roles <> '') foo WHERE INSTR(words, '*') > 0 ) UNION ALL ( SELECT 5, 'public', 'ALTER SCHEMA ' || name || ' DEFAULT ' || CASE WHEN defaultinheritprivileges THEN 'INCLUDE PRIVILEGES;' ELSE 'EXCLUDE PRIVILEGES;' END, 'SCHEMA', name FROM v_internal.vs_schemata WHERE NOT issys -- Exclude system schemas ) UNION ALL ( SELECT 6, 'public', 'ALTER DATABASE ' || database_name || ' SET disableinheritedprivileges = ' || current_value || ';', 'DATABASE', database_name FROM v_internal.vs_configuration_parameters CROSS JOIN v_catalog.databases WHERE parameter_name = 'DisableInheritedPrivileges' ) UNION ALL -- TABLE PRIV INHERITENCE ( SELECT 7, 'public' , 'ALTER TABLE ' || table_schema || '.' || table_name || CASE WHEN inheritprivileges THEN ' INCLUDE PRIVILEGES;' ELSE ' EXCLUDE PRIVILEGES;' END, 'TABLE' AS object_type, table_schema || '.' || table_name AS object_name FROM v_internal.vs_tables JOIN v_catalog.tables ON (table_id = oid) ) UNION ALL -- VIEW PRIV INHERITENCE ( SELECT 8, 'public', 'ALTER VIEW ' || table_schema || '.' || table_name || CASE WHEN inherit_privileges THEN ' INCLUDE PRIVILEGES;' ELSE ' EXCLUDE PRIVILEGES; ' END, 'TABLE' AS object_type, table_schema || '.' || table_name AS object_name FROM v_catalog.views ) UNION ALL ( SELECT 9, owner_name, 'ALTER TABLE ' || table_schema || '.' || table_name || ' OWNER TO ' || owner_name || ';', 'TABLE', table_schema || '.' || table_name FROM v_catalog.tables ) UNION ALL ( SELECT 10, owner_name, 'ALTER VIEW ' || table_schema || '.' || table_name || ' OWNER TO ' || owner_name || ';', 'TABLE', table_schema || '.' || table_name FROM v_catalog.views );
-
从 Linux 命令行,运行
user_ddl.sql
文件中的脚本:$ vsql -f user_ddl.sql CREATE VIEW
-
使用 vsql 连接到 Vertica。
-
将 user_ddl 的 sql 列(该列按 grant_order 列排序)的内容导出到一个文件:
=> \o pre-upgrade.txt => SELECT sql FROM user_ddl ORDER BY grant_order ASC; => \o
-
使用相同的命令选择该视图的 SQL 列并将其保存到不同的文件中。
=> \o post-upgrade.txt => SELECT sql FROM user_ddl ORDER BY grant_order ASC; => \o
-
区别
pre-upgrade.txt
和post-upgrade.txt
。这会将丢失的授权收集到grants-list.txt
中。$ diff pre-upgrade.txt post-upgrade.txt > grants-list.txt
-
要还原丢失的任何授权,请运行
grants-list.txt
中的剩余授权(如果有):=> \i 'grants-list.txt'
注意
尝试使用 ANY 关键字还原对用户的授权会触发以下错误:
ERROR 4856: Syntax error at or near "Any" at character
为避免出现此错误,请使用 () 而不是 (ANY),如下例所示:
=> GRANT EXECUTE ON FUNCTION public.MapLookup() TO public;
GRANT PRIVILEGE