付与後にフラッシュ特権に従う必要がありますか?

コンテンツソース:LinXiaobin「MySQLの実際の戦闘に関する45の講義」

MySQLでは、grantステートメントはユーザーに権限を付与するために使用されます。一部の操作ドキュメントでは、grantステートメントを有効にするには、grantの直後にflushprivilegesコマンドを実行する必要があると記載されています。MySQLを最初に使用したときは、操作ドキュメントの指示に従い、この順序に従いました。それで、フラッシュ特権は本当に付与後に実行される必要がありますか?flushコマンドが実行されない場合、empowerステートメントは実際に有効になりませんか?

最初にユーザーを作成します。「pa」で識別されるユーザー「ua」@「%」を作成します。

MySQLでは、ユーザー名(user)+アドレス(host)はユーザーを表すため、ua @ ip1とua @ ip2は2つの異なるユーザーを表します。このコマンドは2つのアクションを実行します。

  • ディスク上で、mysql.userテーブルに行を挿入します。指定された権限がないため、このデータ行のすべての権限フィールドの値はNです。
  • メモリ内で、acl_userオブジェクトを配列acl_usersに挿入します。このオブジェクトのアクセスフィールドは0です。

    

グローバル権限

MySQLインスタンス全体に作用して、これらの権限情報はmysqlライブラリのユーザーテーブルに保存されます。ユーザーuaに最高の権限を与えたい場合、文は次のよう
になります。*。*のすべての特権を 'ua' @ '%'にgrantオプションで付与します。

このgrantコマンドは、次の2つのアクションを実行します。

  • ディスクのmysql.userテーブルで、ユーザー「ua」@「%」の行の権限を示すすべてのフィールドの値を「Y」に変更します。
  • メモリ内で、配列acl_usersからこのユーザーに対応するオブジェクトを見つけ、アクセス値(許可ビット)をバイナリの「すべて1」に変更します。

grantコマンドの実行後、新しいクライアントがユーザー名uaで正常にログインすると、MySQLは新しい接続のスレッドオブジェクトを維持し、acl_users配列からユーザーのアクセス許可を確認し、アクセス許可の値をこのThreadオブジェクトにコピーします。 。これに関連して実行される後続のステートメントでは、グローバルパーミッションに関するすべての判断で、スレッドオブジェクト内に格納されているパーミッションビットが直接使用されます。

上記の分析に基づいて、次のことがわかります。

  • grantコマンドは、グローバルアクセス許可のためにディスクとメモリを同時に更新します。コマンドは完了後すぐに有効になり、新しく作成された接続は新しい権限を使用します。
  • 既存の接続の場合、そのグローバル権限はgrantコマンドの影響を受けません。

上記のgrantステートメントによって付与された権限を再利用する場合は、次のコマンドを使用できます。*。*のすべての権限を 'ua' @ '%'から取り消します。

この取り消しコマンドの使用法はgrantと同様であり、次の2つのアクションを実行します。

  • ディスクのmysql.userテーブルで、ユーザー「ua」@「%」の行の権限を示すすべてのフィールドの値を「N」に変更します。
  • メモリ内で、配列acl_usersからこのユーザーに対応するオブジェクトを見つけ、アクセスの値を0に変更します。

dbパーミッション

ユーザーuaにライブラリdb1のすべての権限を持たせたい場合は、次のコマンドを実行できます。db1。*のすべての権限をgrantオプションを使用して「ua」@「%」に付与します。

データベースベースのパーミッションレコードはmysql.dbテーブルに保存され、メモリ内の配列acl_dbsに保存されます。このgrantコマンドは、次の2つのアクションを実行します。

  • ディスク上で、レコードの行がmysql.dbテーブルに挿入され、すべてのアクセス許可ビットフィールドが「Y」に設定されました。
  • メモリ内で、配列acl_dbsにオブジェクトを追加します。このオブジェクトのパーミッションビットは「all1」です。

    

データベースに対するユーザーの読み取りおよび書き込みアクセス許可を決定する必要があるたびに、acl_dbs配列を一度トラバースし、ユーザー、ホスト、およびdbに従って一致するオブジェクトを見つけてから、のアクセス許可ビットに従って判断する必要があります。オブジェクト。つまり、grantがdb権限を変更すると、ディスクとメモリの両方で有効になります。

既存の接続に対する許可操作の影響は、グローバル権限とデータベースベースの権限で異なります。次に、制御された実験を行って、それぞれを調べます。

    

注:set global sync_binlogの操作には、スーパーパーミッションが必要です。

ユーザーuaのスーパーパーミッションはT3の取り消しステートメントによって回復されましたが、setglobalがT4で実行されたときにパーミッション検証に合格したことがわかります。これは、superがグローバル権限であり、この権限情報がスレッドオブジェクトにあり、取り消し操作がこのスレッドオブジェクトに影響を与えないためです。

T5でdb1ライブラリに対するuaのすべてのアクセス許可を削除した後、セッションBがT6でdb1ライブラリのテーブルを操作すると、エラー「アクセス許可が不十分です」が報告されます。これは、acl_dbsがグローバル配列であり、すべてのスレッドがこの配列を使用してdb権限を決定するため、取り消し操作がすぐにセッションBに影響するためです。

コードの実装には特別なロジックがあります。現在のセッションがすでに特定のデータベースにある場合、以前にライブラリが使用されたときに取得されたライブラリのアクセス許可がセッション変数に格納されます。

時間T6で、セッションCとセッションBがテーブルtで同じ操作ロジックを持っていることがわかります。ただし、セッションBはエラーを報告し、セッションCは正常に実行できます。これは、T2時にセッションCによって実行された使用db1がこのライブラリーの許可を取得したためです。db1ライブラリーから切り替える前は、セッションCは常にこのライブラリーに対する許可を持っていました。

テーブルのアクセス許可と列のアクセス許可

MySQLは、よりきめ細かいテーブル権限と列権限をサポートしています。その中で、テーブル権限定義はテーブルmysql.tables_privに格納され、列権限定義はテーブルmysql.columns_privに格納されます。これらの2種類の権限が組み合わされ、メモリハッシュ構造column_priv_hashに格納されます。

これら2種類の権限の許可コマンドは次のとおりです。

create table db1.t1(id int, a int);
grant all privileges on db1.t1 to 'ua'@'%' with grant option;
GRANT SELECT(id), INSERT (id,a) ON mydb.mytbl TO 'ua'@'%' with grant option;

dbパーミッションと同様に、これら2つのパーミッションは、付与するたびにデータテーブルを変更し、同時にメモリ内のハッシュ構造も変更します。したがって、これら2種類のアクセス許可に対する操作も、既存の接続にすぐに影響します。

フラッシュ特権 

特権のフラッシュコマンドは、acl_users配列をクリアしてから、mysql.userテーブルからデータを読み取り、それをリロードしてacl_users配列を再構築します。つまり、データテーブルのデータに基づいて、グローバルパーミッションメモリ配列が再度再ロードされます。同様に、MySQLは、データベースのアクセス許可、テーブルのアクセス許可、および列のアクセス許可についても同じことを行いました。

つまり、メモリとディスクデータテーブルの権限データが同じであれば、フラッシュ権限を実行する必要はありません。また、grant / revokeステートメントを使用して実行すると、メモリテーブルとデータテーブルは元々同期的に更新されたままになります。

したがって、通常の状況では、grantコマンドの後で、flushprivilegesコマンドを実行する必要はありません。

使用するシーン:

データテーブルの特権データがメモリの特権データと矛盾している場合、フラッシュ特権ステートメントを使用してメモリデータを再構築し、一貫性のある状態にすることができます。

この不整合は、DMLステートメントを直接使用して許可テーブルを操作するなどの不規則な操作によって引き起こされることがよくあります。これにより、データテーブルの許可データがメモリ内の許可データと不整合になります。

さらに、grantステートメントを使用して承認を付与する場合、次のような記述がよく見られます
。「pa」で識別される「ua」@「%」に*。*でsuperを付与します。

このコマンドは、「password」で識別される追加を行います。承認に加えて、ステートメントのロジックには次のものも含まれます。

  • ユーザー 'ua' @ '%'が存在しない場合は、このユーザーを作成します。パスワードはpaです。
  • ユーザーuaがすでに存在する場合は、パスワードをpaに変更します。

 

おすすめ

転載: blog.csdn.net/qq_24436765/article/details/112767915