This post is the final one of a series of articles on extending MySQL with the Component Infrastructure:
- Extending MySQL using the Component Infrastructure – part 1
- Extending MySQL using the Component Infrastructure – part 2: building the server
- Extending MySQL using the Component Infrastructure – part 3: component services
- Extending MySQL using the Component Infrastructure – part 4: error logging
- Extending MySQL using the Component Infrastructure – part 5: privileges
- Extending MySQL using the Component Infrastructure – part 6: functions
- Extending MySQL using the Component Infrastructure – part 7: messages to users
- Extending MySQL using the Component Infrastructure – part 8: linking a third party library
- Extending MySQL using the Component Infrastructure – part 9: adding a new function
- Extending MySQL using the Component Infrastructure – part 10: status variables
- Extending MySQL using the Component Infrastructure – part 11: performance_schema table
- Extending MySQL using the Component Infrastructure – part 12: instrument your code
I received some questions related to the Component Infrastructure since I started the series. I will try to answer the most relevant in this article.
How can I see the loaded components ?
Loaded components are visible in the table mysql.component
:
SQL> select * from mysql.component; +---------+--------------------+-----------------------------------+ | comp_id | component_group_id | component_urn | +---------+--------------------+-----------------------------------+ | 2 | 2 | file://component_query_attributes | | 23 | 3 | file://component_viruscan | +---------+--------------------+-----------------------------------+
The components that can be loaded are in the folder specified with the plugin_dir
variable:
SQL> select @@plugin_dir; +--------------------------+ | @@plugin_dir | +--------------------------+ | /usr/lib64/mysql/plugin/ | +--------------------------+
Currently, all the components start with component_
:
[fred@imac /usr/lib64/mysql/plugin] $ ls -lh compon* -rwxr-xr-x 1 root root 22K Dec 17 18:33 component_audit_api_message_emit.so -rwxr-xr-x 1 root root 1.7M Dec 17 18:33 component_keyring_file.so -rwxr-xr-x 1 root root 30K Dec 17 18:33 component_log_filter_dragnet.so -rwxr-xr-x 1 root root 37K Dec 17 18:32 component_log_sink_json.so -rwxr-xr-x 1 root root 21K Dec 17 18:33 component_log_sink_syseventlog.so -rwxr-xr-x 1 root root 42K Dec 17 18:32 component_mysqlbackup.so -rwxr-xr-x 1 root root 17K Dec 17 18:33 component_query_attributes.so -rwxr-xr-x 1 root root 38K Dec 17 18:33 component_reference_cache.so -rwxr-xr-x 1 root root 50K Dec 17 18:33 component_validate_password.so -rwxr-xr-x 1 root root 417K Feb 16 13:22 component_viruscan.so
This is just because the cmake macro does this.
What happen to PRIVILEGES when the component is removed ?
The privilege stays for the users to who it was granted:
*************************** 2. row *************************** Grants for root@localhost: GRANT VIRUS_SCAN ON *.* TO `root`@`localhost`
And it has no effect. However if there is at least one use having this privilege after unloading the component and restarting the server, it will be possible to GRANT or REVOKE that privilege anyway.
In the following example, the component has been uninstalled and mysqld
restarted:
SQL> SELECT * FROM information_schema.user_privileges WHERE PRIVILEGE_TYPE='VIRUS_SCAN'; Empty set (0.0006 sec) SQL> GRANT VIRUS_SCAN on *.* TO root@localhost ; ERROR: 1149 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use SQL> REVOKE VIRUS_SCAN on *.* FROM meh; Query OK, 0 rows affected, 1 warning (0.0026 sec) Warning (code 3929): Dynamic privilege 'VIRUS_SCAN' is not registered with the server.
But now let’s load the component, grant the privilege, uninstall the module and restart mysqld
:
In fact, as long as there’s at least one grant of the dynamic privilege, even if the component is unloaded, that privilege is still grantable and revocable. This is by design.
Are loaded components still loaded after a restart of the server ?
Yes, all components that are loaded will be loaded again when MySQL starts.
Does MySQL start if a component was loaded when mysqld was stopped but the component file is removed ?
Yes, MySQL will start and a message will be written in error log:
2022-02-16T13:47:54.394735Z 0 [ERROR] [MY-013129] [Server] A message intended for a client cannot be sent there as no client-session is attached. Therefore, we're sending the information to the error-log instead: MY-001126 - Can't open shared library '/usr/lib64/mysql/plugin/component_viruscan.so' (errno: 0 /usr/lib64/mysql/plugin/component_viruscan.so: cannot open shared object file: No such file or directory)
If the component created performance_schema
tables, the tables will still be present.
Can we load the component in MySQL’s config file ?
No, it’s possible to set variables used by the component (prefixed with the component name with a dot, like viruscan.blabla
, but the component needs to be loaded at least once first. But it’s not possible to load the component from my.cnf
.
Where is the documentation related to the component services ?
The best place to find information is in the Component Services Inventory page. You can also find information in the component examples and tests that are part of the MySQL source code (in components
directory).
Which services are available ?
Unfortunately, as you may have noticed, not all services are already documented in the Services Inventory. If you go in the source code (include/mysql/components/services
), you can list all available services.
As MySQL 8.0.28, there are 137 services !
Run this command in the source code to list them all:
grep BEGIN_SERVICE_DEFINITION * -R | cut -d '(' -f 2 | sort | cut -d')' -f1
The component I plan to write requires a service that is not existing, what can I do ?
If you think that a service that could help you is missing, the best way to eventually get it added, is to submit a feature request in https://bugs.mysql.com. If the service is generic enough and could help multiple developers, there are chances that our team will add it. Eventually, the service exists already or the same result can be reached using another service.
I hope you enjoyed the full series on MySQL Component Architecture and that it will make you want to code to extend MySQL.
Hi,
I hit into this error. How can I fix it? I don’t need the component anymore.
mysql> select * from mysql.component;
+————–+——————–+————————————+
| component_id | component_group_id | component_urn |
+————–+——————–+————————————+
| 1 | 1 | file://component_validate_password |
+————–+——————–+————————————+
2024-01-16T06:09:17.050142Z 0 [ERROR] [MY-013129] [Server] A message intended for a client cannot be sent there as no client-session is attached. Therefore, we’re sending the information to the error-log instead: MY-003529 – Cannot load component from specified URN: ‘file://component_validate_password’.
Thanks
Hans
It seems you have removed the .so file manually. The best practice is to first uninstall the component before removing the .so file.
In your case:
MySQL> uninstall component "file://component_validate_password";
Now, if the file is not available anymore, you can manually delete it from `mysql.component` table:
MySQL> delete from mysql.component where component_urn='file://component_validate_password';