[MDEV-11581] Mariadb starts innodb encryption threads when key has not changed or data scrubbing turned off Created: 2016-12-15 Updated: 2020-08-25 Resolved: 2017-03-14 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Encryption, Storage Engine - InnoDB, Storage Engine - XtraDB |
| Affects Version/s: | 10.1.16, 10.1.19 |
| Fix Version/s: | 10.1.23 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Kishor Grandhe | Assignee: | Jan Lindström (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||
| Sprint: | 10.1.21 | ||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
We migrated our application from MySQL 5.6.21 to Mariadb 10.1.16 to use Data at Rest Encryption (DARE) and it caused a major issues and application started stalling for no reason. When we use DARE on INNODB tables, using the out of the box plugin file_key_management using the configuration on this page https://mariadb.com/kb/en/mariadb/data-at-rest-encryption/, we encountered periodic (in regular intervals i.e. every hour) high CPU and it stalled the system for any use. Even when there is no user/application connections to the server, the CPU spikes happened regularly. No indication in any logs or anywhere on what was happening. It was a debugging nightmare. We were using innodb_encryption_threads = 4 as indicated in the above page. On extensive analysis, following was discovered Mariadb starts the background threads as specified in the innodb_encryption_threads to perform 2 things - data scrubbing i.e. to remove deleted data and to re-encrypt data pages when key is changed. The issue noted here is even when scrubbing for compressed and uncompressed is turned off and also when there is no key changed for re-encrypt, the background threads starts periodically as defined in the innodb-background-scrub-data-check-interval and hogs the CPU as high as 200% on a 2 core system for nearly 20+ minutes (depending on the data volume) doing "NOTHING" or to say "NOTHING TO BE DONE", and this stalls the CPU and the system is unusable. Suspect following critical issues Below is the config out of box for scrubbing
2. There is no check to see if the encryption key has changed to start the new threads. Also per the documentation "This plugin does not support key rotation — all keys always have the version 1.", so it gives more reason not to start the encryption threads until a key change is detected. 3. Encryption/Scrubbing Threads are behaving like high priority threads i.e. it hogs the CPU stalling the system i.e. generally any background processes work on low priority threads such that the core DB functionality is not affected. 4. No information noted in any of the system tables or in the processlist, that the Encryption threads are running and status of processing Link to a similar high CPU issue has been noted in this ticket We temporarily solved the problem by setting innodb_encryption_threads = 0 |
| Comments |
| Comment by Jan Lindström (Inactive) [ 2016-12-16 ] |
|
There is two things user need to carefully configure if key rotation is needed:
If you have innodb-encrypt-tables=OFF, you can set --innodb-encryption-threads=0. If you have innodb-encrypt-tables=ON|FORCE you still may configure --innodb-encryption-threads=0 but then you may not dynamically set encryption ON|OFF. These threads are also used to convert encrypted tables to unencrypted and unencrypted tables to encrypted if needed. Remember also that new tables using default mode i.e. create table t10() engine=innodb; Maybe we should have a new configuration variable to disable key rotation in case user does not really need it, scrubbing is already controlled by configuration variables. |
| Comment by Jan Lindström (Inactive) [ 2016-12-16 ] |
|
As key rotation is based on key ages, only way to know does tablespace need key rotation or not is to iterate all tablespaces after certain times. Thus, if key rotation is not needed user may set number of background threads to 0 to disable it. That can't be done by default as AWS key management plugin does support key rotation and in InnoDB code base we do not know what plugin is used and does it support key rotation or not. In my opinion current behavior is as designed. |
| Comment by Geoff Montee (Inactive) [ 2016-12-16 ] |
|
Hi jplindst,
I submitted |
| Comment by Rasmus Johansson (Inactive) [ 2016-12-20 ] |
|
Correcting resolution |
| Comment by Rasmus Johansson (Inactive) [ 2016-12-20 ] |
|
By design. A new variable can be implemented as an improvement stated in a previous comment. |
| Comment by Kishor Grandhe [ 2017-01-04 ] |
|
Re-Tested with 10.1.20, CPU usage still high. The issue identified in |
| Comment by Jan Lindström (Inactive) [ 2017-01-05 ] |
|
Why you can't set innodb-encryption-threads=0 ? This does not mean that your tables are not encrypted. |
| Comment by Kishor Grandhe [ 2017-01-05 ] |
|
Based on your statement - "Remember also that new tables using default mode i.e. create table t10() engine=innodb; |
| Comment by Jan Lindström (Inactive) [ 2017-01-10 ] |
|
If you think too much resources are used you can use innodb-encryption-threads=[1|2] but that will make CPU spike longer. Fine encrypting those default mode new tables do take CPU and it happens on background not immediately. Let me see if we can do something better in case where nothing really happens inside InnoDB i.e. no new tables, no new rows and no selects. |
| Comment by Jan Lindström (Inactive) [ 2017-01-10 ] |
|
Re-opened because of user request. |
| Comment by Marko Mäkelä [ 2017-01-31 ] |
|
We are also unnecessarily creating a redo log checkpoint at startup, which could slow down startup after crash recovery. |
| Comment by Jan Lindström (Inactive) [ 2017-03-14 ] |
|
commit 50eb40a2a8aa3af6cc271f6028f4d6d74301d030 Background: Key rotation is based on background threads This patch re-purposes innodb-encryption-rotate-key-age=0 fil0fil.cc: Added functions fil_space_acquire_low() fil_node_open_file(): After page 0 is read read also btr_scrub_lock_dict_func() buf_page_decrypt_after_read(): fil0crypt.cc/fil0fil.h: Lot of changes. Pass fil_space_t* directly fil_space_create(): Inform key rotation that there could fsp_header_init(): Acquire fil_space_t*, write crypt_data check_table_options() i_s.cc: Added ROTATING_OR_FLUSHING field to |