21.5.12 使用共享授权 table 的分布式特权

NDB Cluster 支持在 NDB Cluster 中的所有 SQL 节点之间分配 MySQL 用户和特权。默认情况下,不启用此支持。您应该按照本节中概述的步骤进行操作。

通常,mysql数据库中每个 MySQL 服务器的用户权限 table 必须使用MyISAM存储引擎,这意味着在一个 SQL 节点上创建的用户帐户及其关联的特权在群集的其他 SQL 节点上不可用。可以在 MySQL 安装目录的share目录中找到 NDB 群集发行版随附的 SQL 文件ndb_dist_priv.sql

启用分布式特权的第一步是将该脚本加载到充当 SQL 节点的 MySQL 服务器中(此后称为目标 SQL 节点或 MySQL Server)。您可以通过在目标 SQL 节点上更改其 MySQL 安装目录(其中* options *table 示连接到此 SQL 节点所需的任何其他选项)后,从目标 SQL 节点上的系统 Shell 执行以下命令来执行此操作:

shell> mysql options -uroot < share/ndb_dist_priv.sql

导入ndb_dist_priv.sql会在目标 SQL 节点上的mysql数据库中创建许多存储例程(六个存储过程和一个存储函数)。连接到mysqlClient 端中的 SQL 节点(以 MySQL root用户身份)后,您可以验证是否已按以下所示创建了这些节点:

mysql> SELECT ROUTINE_NAME, ROUTINE_SCHEMA, ROUTINE_TYPE
    ->     FROM INFORMATION_SCHEMA.ROUTINES
    ->     WHERE ROUTINE_NAME LIKE 'mysql_cluster%'
    ->     ORDER BY ROUTINE_TYPE;
+---------------------------------------------+----------------+--------------+
| ROUTINE_NAME                                | ROUTINE_SCHEMA | ROUTINE_TYPE |
+---------------------------------------------+----------------+--------------+
| mysql_cluster_privileges_are_distributed    | mysql          | FUNCTION     |
| mysql_cluster_backup_privileges             | mysql          | PROCEDURE    |
| mysql_cluster_move_grant_tables             | mysql          | PROCEDURE    |
| mysql_cluster_move_privileges               | mysql          | PROCEDURE    |
| mysql_cluster_restore_local_privileges      | mysql          | PROCEDURE    |
| mysql_cluster_restore_privileges            | mysql          | PROCEDURE    |
| mysql_cluster_restore_privileges_from_local | mysql          | PROCEDURE    |
+---------------------------------------------+----------------+--------------+
7 rows in set (0.01 sec)

名为mysql_cluster_move_privileges的存储过程将创建现有特权 table 的备份副本,然后将其转换为NDB

mysql_cluster_move_privileges分两个步骤执行备份和转换。第一步是调用mysql_cluster_backup_privileges,这将在mysql数据库中创建两组副本:

  • 一组使用MyISAM存储引擎的本地副本。通过将后缀_backup添加到原始特权 table 名称中来生成它们的名称。

  • 使用NDBCLUSTER存储引擎的一组分布式副本。这些 table 通过在原始 table 的名称前加上ndb_并在其后加上_backup来命名。

创建副本后,mysql_cluster_move_privileges调用mysql_cluster_move_grant_tables,其中包含将 mysql 系统 table 转换为NDBALTER TABLE ...引擎= NDB语句。

通常,您不应该手动调用mysql_cluster_backup_privilegesmysql_cluster_move_grant_tables。这些存储过程仅供mysql_cluster_move_privileges使用。

尽管原始特权 table 是自动备份的,但是在 continue 操作之前,最好在所有受影响的 SQL 节点上手动创建现有特权 table 的备份,这是一个好主意。您可以使用mysqldump来执行此操作,其方式类似于此处所示:

shell> mysqldump options -uroot \
    mysql user db tables_priv columns_priv procs_priv proxies_priv > backup_file

要执行转换,必须使用mysqlClient 端(再次以 MySQL root用户身份)连接到目标 SQL 节点。像这样调用存储过程:

mysql> CALL mysql.mysql_cluster_move_privileges();
Query OK, 0 rows affected (22.32 sec)

根据特权 table 中的行数,此过程可能需要一些时间才能执行。如果某些特权 table 为空,则您可能会看到一个或多个无数据-mysql_cluster_move_privileges返回时,已提取,选择或处理了零行警告。在这种情况下,可以安全地忽略警告。要验证转换是否成功,可以使用存储的函数mysql_cluster_privileges_are_distributed,如下所示:

mysql> SELECT CONCAT(
    ->    'Conversion ',
    ->    IF(mysql.mysql_cluster_privileges_are_distributed(), 'succeeded', 'failed'),
    ->    '.')
    ->    AS Result;
+-----------------------+
| Result                |
+-----------------------+
| Conversion succeeded. |
+-----------------------+
1 row in set (0.00 sec)

mysql_cluster_privileges_are_distributed检查是否存在分布式特权 table,如果所有特权 table 都已分发,则返回1;否则,返回0

您可以使用以下查询来验证是否已创建备份:

mysql> SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLES
    ->     WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME LIKE '%backup'
    ->     ORDER BY ENGINE;
+-------------------------+------------+
| TABLE_NAME              | ENGINE     |
+-------------------------+------------+
| db_backup               | MyISAM     |
| user_backup             | MyISAM     |
| columns_priv_backup     | MyISAM     |
| tables_priv_backup      | MyISAM     |
| proxies_priv_backup     | MyISAM     |
| procs_priv_backup       | MyISAM     |
| ndb_columns_priv_backup | ndbcluster |
| ndb_user_backup         | ndbcluster |
| ndb_tables_priv_backup  | ndbcluster |
| ndb_proxies_priv_backup | ndbcluster |
| ndb_procs_priv_backup   | ndbcluster |
| ndb_db_backup           | ndbcluster |
+-------------------------+------------+
12 rows in set (0.00 sec)

转换为分布式特权后,无论何时在任何 SQL 节点上创建,删除或更新其特权的 MySQL 用户帐户,更改都将在连接到群集的所有其他 MySQL 服务器上立即生效。特权分配后,连接到群集的所有新 MySQL 服务器将自动参与分配。

Note

对于在执行mysql_cluster_move_privileges时连接到 SQL 节点的 Client 端,您可能需要在这些 SQL 节点上执行FLUSH PRIVILEGES,或者先断开连接再重新连接 Client 端,以便那些 Client 端能够看到特权的更改。

所有 MySQL 用户权限分布在所有连接的 MySQL 服务器上。这包括与视图和存储的例程相关联的任何特权,即使当前不支持分发视图和存储的例程本身。

如果mysql_cluster_move_privileges运行时 SQL 节点与群集断开连接,则在重新连接到群集后,必须使用诸如如果存在 table,则删除 tablemysql.user mysql.db mysql.tables_priv mysql.columns_priv mysql.procs_priv之类的语句删除其特权 table。这将导致 SQL 节点使用共享特权 table,而不是它们自己的本地特权 table。首次将新的 SQL 节点连接到群集时,不需要这样做。

如果最初重新启动整个集群(所有数据节点都关闭,然后使用--initial重新启动),则共享特权 table 将丢失。如果发生这种情况,则可以使用原始目标 SQL 节点从mysql_cluster_move_privileges进行的备份或使用mysqldump创建的转储文件中还原它们。如果需要使用新的 MySQL Server 进行还原,则在首次连接到群集时,应使用--skip-grant-tables启动它;之后,您可以在本地还原特权 table,然后使用mysql_cluster_move_privileges再次分发它们。在还原和分发 table 之后,您应该重新启动不带--skip-grant-tables选项的 MySQL 服务器。

您还可以从ndb_mgmClient 端中使用START BACKUP进行的备份中使用ndb_restore --restore-privilege-tables还原分布式 table。 (由START BACKUP命令不备份由mysql_cluster_move_privileges创建的MyISAMtable。)ndb_restore默认情况下不还原特权 table;默认情况下,它不还原特权 table。 --restore-privilege-tables选项导致它这样做。

您可以使用两个过程之一来恢复 SQL 节点的本地特权。 mysql_cluster_restore_privileges的工作方式如下:

  • 如果mysql.ndb_*_backuptable 的副本可用,请尝试从中还原系统 table。

  • 否则,请尝试从名为*_backup(没有ndb_前缀)的本地备份中还原系统 table。

另一个名为mysql_cluster_restore_local_privileges的过程仅从本地备份还原系统 table,而不检查ndb_*备份。

mysql_cluster_restore_privilegesmysql_cluster_restore_local_privileges重新创建的系统 table 使用 MySQL 服务器默认存储引擎;它们不以任何方式共享或分发,并且不使用 NDB Cluster 的NDB存储引擎。

附加存储过程mysql_cluster_restore_privileges_from_localmysql_cluster_restore_privilegesmysql_cluster_restore_local_privileges使用。不应直接调用它。

Important

直接访问 NDB 群集数据的应用程序,包括 NDB API 和 ClusterJ 应用程序,不受 MySQL 特权系统的约束。这意味着,一旦分发了授权 table,此类应用程序就可以自由访问它们,就像其他任何NDBtable 一样。特别要注意的是,* NDB API 和 ClusterJ 应用程序可以读写用户名,主机名,密码哈希和分布式授权 table 的任何其他内容,而没有任何限制*。