MySQL Parameters のデータの作り方
MySQL Parameters のデータの作り方
これは MySQL Advent Calendar 2020 の 25日目の記事です。
MySQL Parameters というページのメンテをしてます。
MySQL Paramters は MySQL のバージョン間の差分を表示できるものです。
現在次のバージョンを比較できます。
- 5.0.96
- 5.1.72
- 5.5.58〜62
- 5.6.34〜50
- 5.7.16〜32
- 8.0.11〜22
比較できる値の種類は次のものです。
- mysqld のコマンドラインパラメータ
- mysql のコマンドラインパラメータ
- システム変数
- ステータス変数
- キャラクタセット
- コレーション
- 権限
- 関数/演算子
- information_schema データベースのテーブル名とカラム名
- performance_schema データベースのテーブル名とカラム名
- エラーメッセージ
たとえばシステム変数の 8.0.* のバージョン間の差分は https://mysql-params.tmtms.net/variable/?vers=8.0.11,8.0.12,8.0.13,8.0.14,8.0.15,8.0.16,8.0.17,8.0.18,8.0.19,8.0.20,8.0.21,8.0.22&diff=true で表示できます。
黄色のセルはその左隣のセルの値と違いがあることを示しています。
元々 Vue.js の勉強のつもりで作ってて、だいたいそのままなのでフロントエンドは酷い作りです。作り直したい。
フロントエンドには触れたくないので、データをどのように作ってるのかを説明します。
mysqld のコマンドラインパラメータ
基本的には mysqld --no-defaults --user mysql --help -v
の出力の後半からパラメータ名と値を拾ってます。
Variables (--variable-name=value)
and boolean options {FALSE|TRUE} Value (after reading options)
------------------------------------------------------------ -------------
abort-slave-event-count 0
activate-all-roles-on-login FALSE
admin-address (No default value)
admin-port 33062
admin-ssl TRUE
admin-ssl-ca (No default value)
admin-ssl-capath (No default value)
admin-ssl-cert (No default value)
admin-ssl-cipher (No default value)
admin-ssl-crl (No default value)
admin-ssl-crlpath (No default value)
...
--plugin-load
でできるだけ多くのプラグインを読み込んで値を表示してるので、 example ストレージエンジンのようなパラメータも表示されてます。
mysql のコマンドラインパラメータ
mysqld と同じように mysql --no-defaults --help -v
の出力の後半を使用しています。
Variables (--variable-name=value)
and boolean options {FALSE|TRUE} Value (after reading options)
--------------------------------- ----------------------------------------
auto-rehash TRUE
auto-vertical-output FALSE
bind-address (No default value)
binary-as-hex FALSE
character-sets-dir (No default value)
column-type-info FALSE
comments FALSE
compress FALSE
database (No default value)
default-character-set auto
delimiter ;
...
システム変数
mysqld --help -v
で出力されるパラメータと、mysqld 起動後に SHOW VARIABLES
で表示される変数がビミョーに異なっているので、追加しました。
mysqld 起動後に全プラグインとコンポーネントを読み込んでから、SHOW GLOBAL VARIABLES
の出力を使用しています。
activate_all_roles_on_login OFF
admin_address
admin_port 33062
admin_ssl_ca
admin_ssl_capath
admin_ssl_cert
admin_ssl_cipher
admin_ssl_crl
admin_ssl_crlpath
admin_ssl_key
admin_tls_ciphersuites
admin_tls_version TLSv1,TLSv1.1,TLSv1.2,TLSv1.3
auto_generate_certs ON
auto_increment_increment 1
auto_increment_offset 1
autocommit ON
...
ステータス変数
SHOW GLOBAL STATUS
の出力の1番目のカラムだけを使用しています。
Aborted_clients 0
Aborted_connects 0
Acl_cache_items_count 0
Audit_null_authorization_column 0
Audit_null_authorization_db 0
Audit_null_authorization_procedure 0
Audit_null_authorization_proxy 0
Audit_null_authorization_table 0
Audit_null_authorization_user 0
Audit_null_called 2222
Audit_null_command_end 8
Audit_null_command_start 9
Audit_null_connection_change_user 0
Audit_null_connection_connect 2
Audit_null_connection_disconnect 1
...
キャラクタセット
mysql --no-defaults -e 'SHOW CHARSET'
の出力の1番目のカラムを使用しています。
Charset Description Default collation Maxlen
armscii8 ARMSCII-8 Armenian armscii8_general_ci 1
ascii US ASCII ascii_general_ci 1
big5 Big5 Traditional Chinese big5_chinese_ci 2
binary Binary pseudo charset binary 1
cp1250 Windows Central European cp1250_general_ci 1
cp1251 Windows Cyrillic cp1251_general_ci 1
cp1256 Windows Arabic cp1256_general_ci 1
cp1257 Windows Baltic cp1257_general_ci 1
cp850 DOS West European cp850_general_ci 1
cp852 DOS Central European cp852_general_ci 1
cp866 DOS Russian cp866_general_ci 1
...
コレーション
mysql --no-defaults -e 'SHOW COLLATION'
の出力の1番目のカラムを使用しています。
Collation Charset Id Default Compiled Sortlen Pad_attribute
armscii8_bin armscii8 64 Yes 1 PAD SPACE
armscii8_general_ci armscii8 32 Yes Yes 1 PAD SPACE
ascii_bin ascii 65 Yes 1 PAD SPACE
ascii_general_ci ascii 11 Yes Yes 1 PAD SPACE
big5_bin big5 84 Yes 1 PAD SPACE
big5_chinese_ci big5 1 Yes Yes 1 PAD SPACE
binary binary 63 Yes Yes 1 NO PAD
cp1250_bin cp1250 66 Yes 1 PAD SPACE
cp1250_croatian_ci cp1250 44 Yes 1 PAD SPACE
cp1250_czech_cs cp1250 34 Yes 2 PAD SPACE
cp1250_general_ci cp1250 26 Yes Yes 1 PAD SPACE
cp1250_polish_ci cp1250 99 Yes 1 PAD SPACE
cp1251_bin cp1251 50 Yes 1 PAD SPACE
cp1251_bulgarian_ci cp1251 14 Yes 1 PAD SPACE
...
権限
DESC mysql.user
のカラム名(*_priv
)から権限を得ています。
Field Type Null Key Default Extra
Host char(255) NO PRI
User char(32) NO PRI
Select_priv enum('N','Y') NO N
Insert_priv enum('N','Y') NO N
Update_priv enum('N','Y') NO N
Delete_priv enum('N','Y') NO N
Create_priv enum('N','Y') NO N
Drop_priv enum('N','Y') NO N
Reload_priv enum('N','Y') NO N
...
カラム名と権限名がビミョーに異なるので(Create_tmp_table
→ CREATE TEMPORARY TABLES
等)補正したりしてます。
あと 8.0 では PROXY
という権限があるんですが、これは mysql.user
に含まれていないので、mysql.proxies_priv
を見ています。
Field Type Null Key Default Extra
Host char(255) NO PRI
User char(32) NO PRI
Proxied_host char(255) NO PRI
Proxied_user char(32) NO PRI
...
さらに 8.0 では動的権限(Dynamic Privileges)という(個人的には名前が良くないと思う)、プラグインやコンポーネントによって追加される権限があります。
これは ALL 権限をつけたユーザーを作って SHOW GRANTS FOR ユーザー名
で出力されるのでそれを使用しています。
Grants for test@%
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `test`@`%` WITH GRANT OPTION
GRANT APPLICATION_PASSWORD_ADMIN,AUDIT_ADMIN,BACKUP_ADMIN,BINLOG_ADMIN,BINLOG_ENCRYPTION_ADMIN,CLONE_ADMIN,CONNECTION_ADMIN,ENCRYPTION_KEY_ADMIN,GROUP_REPLICATION_ADMIN,INNODB_REDO_LOG_ARCHIVE,INNODB_REDO_LOG_ENABLE,PERSIST_RO_VARIABLES_ADMIN,REPLICATION_APPLIER,REPLICATION_SLAVE_ADMIN,RESOURCE_GROUP_ADMIN,RESOURCE_GROUP_USER,ROLE_ADMIN,SERVICE_CONNECTION_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,SHOW_ROUTINE,SYSTEM_USER,SYSTEM_VARIABLES_ADMIN,TABLE_ENCRYPTION_ADMIN,XA_RECOVER_ADMIN ON *.* TO `test`@`%` WITH GRANT OPTION
実はこの出力にすべての権限が含まれてるので mysql.user
を見なくても良さそうなもんなのですが、このような出力は 8.0 だけで、5.7 以下だと次のように出力されるので、これだけじゃわからないのでした。
Grants for test@%
GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION
関数/演算子
mysql で help Functions
でカテゴリが表示され、さらにそのカテゴリ名を help すると関数名の一覧が表示されます。
mysql> help Functions;
You asked for help about help category: "Functions"
For more information, type 'help <item>', where <item> is one of the following
categories:
Aggregate Functions and Modifiers
Bit Functions
Cast Functions and Operators
Comparison Operators
Control Flow Functions
Date and Time Functions
Encryption Functions
Enterprise Encryption Functions
...
mysql> help Aggregate Functions and Modifiers;
You asked for help about help category: "Aggregate Functions and Modifiers"
For more information, type 'help <item>', where <item> is one of the following
topics:
AVG
BIT_AND
BIT_OR
BIT_XOR
COUNT
COUNT DISTINCT
GROUP_CONCAT
JSON_ARRAYAGG
JSON_OBJECTAGG
MAX
...
初めはこれを使ってたんですが、出力のパースが面倒だったので、今は mysql.help_category
と mysql.help_topic
テーブルから名前を得ています。
mysql> select help_category_id,name,parent_category_id from mysql.help_category;
+------------------+---------------------------------+--------------------+
| help_category_id | name | parent_category_id |
+------------------+---------------------------------+--------------------+
| 0 | Contents | 0 |
| 1 | Help Metadata | 0 |
| 2 | Data Types | 0 |
| 3 | Administration | 0 |
| 4 | Functions | 0 |
...
mysql> select help_topic_id,name,help_category_id from mysql.help_topic;
+---------------+----------------------------+------------------+
| help_topic_id | name | help_category_id |
+---------------+----------------------------+------------------+
| 0 | HELP_DATE | 1 |
| 1 | HELP_VERSION | 1 |
| 2 | AUTO_INCREMENT | 2 |
| 3 | HELP COMMAND | 3 |
| 4 | ASYMMETRIC_DECRYPT | 5 |
| 5 | ASYMMETRIC_DERIVE | 5 |
| 6 | ASYMMETRIC_ENCRYPT | 5 |
| 7 | ASYMMETRIC_SIGN | 5 |
...
この中から関数/演算子っぽいカテゴリ配下にある name
を次のクエリで取り出しています。
select t.name from mysql.help_topic t join mysql.help_category c using (help_category_id)
where c.name rlike "functions|operators|geometry (constructors|relations)|properties|mbr|wkt|wkb|xml|gtid"
and c.name != "user-defined functions" and t.name not rlike "definition"
order by t.name
information_schema データベースのテーブル名とカラム名
SELECT TABLE_NAME,COLUMN_NAME FROM COLUMNS WHERE TABLE_SCHEMA='information_schema'
の出力を使用しています。
ADMINISTRABLE_ROLE_AUTHORIZATIONS GRANTEE
ADMINISTRABLE_ROLE_AUTHORIZATIONS GRANTEE_HOST
ADMINISTRABLE_ROLE_AUTHORIZATIONS HOST
ADMINISTRABLE_ROLE_AUTHORIZATIONS IS_DEFAULT
ADMINISTRABLE_ROLE_AUTHORIZATIONS IS_GRANTABLE
ADMINISTRABLE_ROLE_AUTHORIZATIONS IS_MANDATORY
ADMINISTRABLE_ROLE_AUTHORIZATIONS ROLE_HOST
ADMINISTRABLE_ROLE_AUTHORIZATIONS ROLE_NAME
ADMINISTRABLE_ROLE_AUTHORIZATIONS USER
APPLICABLE_ROLES GRANTEE
APPLICABLE_ROLES GRANTEE_HOST
APPLICABLE_ROLES HOST
APPLICABLE_ROLES IS_DEFAULT
...
performance_schema データベースのテーブル名とカラム名
SELECT TABLE_NAME,COLUMN_NAME FROM COLUMNS WHERE TABLE_SCHEMA='performance_schema'
の出力を使用しています。
accounts CURRENT_CONNECTIONS
accounts HOST
accounts TOTAL_CONNECTIONS
accounts USER
binary_log_transaction_compression_stats COMPRESSED_BYTES_COUNTER
binary_log_transaction_compression_stats COMPRESSION_PERCENTAGE
binary_log_transaction_compression_stats COMPRESSION_TYPE
binary_log_transaction_compression_stats FIRST_TRANSACTION_COMPRESSED_BYTES
binary_log_transaction_compression_stats FIRST_TRANSACTION_ID
binary_log_transaction_compression_stats FIRST_TRANSACTION_TIMESTAMP
binary_log_transaction_compression_stats FIRST_TRANSACTION_UNCOMPRESSED_BYTES
binary_log_transaction_compression_stats LAST_TRANSACTION_COMPRESSED_BYTES
binary_log_transaction_compression_stats LAST_TRANSACTION_ID
binary_log_transaction_compression_stats LAST_TRANSACTION_TIMESTAMP
binary_log_transaction_compression_stats LAST_TRANSACTION_UNCOMPRESSED_BYTES
...
エラーメッセージ
エラーメッセージは perror
コマンドで出力されます。
% perror 1022
MySQL error code MY-001022 (ER_DUP_KEY): Can't write; duplicate key in table '%-.192s'
ですが、エラー番号の一覧はわからないので、ソースコードを見るしかないかと思ってたのですが、include/mysqld_error.h
から取れることがわかりました。
//#define OBSOLETE_ER_HASHCHK 1000
//#define OBSOLETE_ER_NISAMCHK 1001
#define ER_NO 1002
#define ER_YES 1003
#define ER_CANT_CREATE_FILE 1004
#define ER_CANT_CREATE_TABLE 1005
#define ER_CANT_CREATE_DB 1006
#define ER_DB_CREATE_EXISTS 1007
#define ER_DB_DROP_EXISTS 1008
//#define OBSOLETE_ER_DB_DROP_DELETE 1009
#define ER_DB_DROP_RMDIR 1010
//#define OBSOLETE_ER_CANT_DELETE_FILE 1011
これを使ってひたすら perror
を実行して出力を得ています。
おわり
とまあ、こんなことを MySQL がリリースされる3ヶ月毎にやってます。
元々作り始めたのは 8.0 GA リリースよりも前だったのですが、これを作っておいたおかげで、パッチレベルリリースなのになぜか色々変更される MySQL 8.0.x の差分を確認することが簡単にできるようになりました。(GA とはいったい…?)
投げ銭はこのページの右の「¥サポートする」から受け付けております。
Discussion