Поиск неисправностей шифрования InnoDB
Неправильные параметры создания
При использовании InnoDB таблиц с шифрованием в ряде случаев оператор CREATE TABLE или ALTER TABLE может генерировать ошибку 1005, из-за ошибки InnoDB 140, Wrong create options. Например,
CREATE TABLE `test`.`table1` ( `id` int(4) primary key , `name` varchar(50)); ERROR 1005 (HY000): Can't create table `test`.`table1` (errno: 140 "Wrong create options")
В таких случаях, вы можете получить дополнительную информацию о причине ошибки, выполнив оператор SHOW WARNINGS.
Эта ошибка может возникнуть в следующих случаях:
- При шифровании таблицы установкой параметра таблицы ENCRYPTED в значение
YESпри установленном значении innodb_file_per_table вOFF. В этом случае, SHOW WARNINGS вернёт следующее:
SHOW WARNINGS; +---------+------+---------------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------------+ | Warning | 140 | InnoDB: ENCRYPTED requires innodb_file_per_table | | Error | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") | | Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB | +---------+------+---------------------------------------------------------------------+ 3 rows in set (0.00 sec)
- При шифровании таблицы установкой параметра таблицы ENCRYPTED в значение
YES, и системной переменной innodb_default_encryption_key_id или параметра таблицы ENCRYPTION_KEY_ID ссылается на несуществующий идентификатор ключа. В этом случае, SHOW WARNINGS вернёт следующее:
SHOW WARNINGS; +---------+------+---------------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------------+ | Warning | 140 | InnoDB: ENCRYPTION_KEY_ID 500 not available | | Error | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") | | Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB | +---------+------+---------------------------------------------------------------------+ 3 rows in set (0.00 sec)
- В некоторых версиях это может произойти при создании таблицы с параметром ENCRYPTED таблицы, установленным в
DEFAULTпри установленном значении системной переменной innodb_encrypt_tables вOFF, и системной переменной innodb_default_encryption_key_id или параметра таблицы ENCRYPTION_KEY_ID не установлено в1. В этом случае, SHOW WARNINGS вернёт следующее:
SHOW WARNINGS; +---------+------+---------------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------------+ | Warning | 140 | InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1 | | Error | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") | | Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB | +---------+------+---------------------------------------------------------------------+ 3 rows in set (0.00 sec)
Начиная с MariaDB 10.1.39, MariaDB 10.2.23 и MariaDB 10.3.14, создание таблицы с параметром ENCRYPTED таблицы, установленным в DEFAULT при установленном значении системной переменной innodb_encrypt_tables в OFF, и системной переменной innodb_default_encryption_key_id или параметра таблицы ENCRYPTION_KEY_ID не установлено в 1 больше не будет завершаться ошибкой и не будет генерировать предупреждение.
Для получения дополнительной информации, см. MDEV-18601.
Установка идентификатора ключа шифрования для нешифрованной таблицы
Если вы установите параметр ENCRYPTION_KEY_ID таблицы для таблицы, которая не зашифрована, потому что системная переменная innodb_encrypt_tables установлена в OFF и параметр таблицы ENCRYPTED установлено в значение DEFAULT, этот идентификатор ключа шифрования будет сохранён в файле таблицы .frm, но сам ключ шифрования не будет сохранён в файле таблицы .ibd.
В качестве побочного эффекта, с текущей реализацией шифрования, если системная переменная innodb_encrypt_tables впоследствии будет установлена в ON, а InnoDB попытается зашифровать таблицу, то потоки фонового шифрования InnoDB не будут читать этот идентификатор ключа шифрования из файла .frm . Вместо этого, потоки могут зашифровать таблицу с ключом шифрования с идентификатором 1, который внутренне считается ключом шифрования по умолчанию, когда ключ не указан. Например:
SET GLOBAL innodb_encrypt_tables=OFF; CREATE TABLE tab1 ( id INT PRIMARY KEY, str VARCHAR(50) ) ENCRYPTION_KEY_ID=100; SET GLOBAL innodb_encrypt_tables=ON; SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID FROM information_schema.INNODB_TABLESPACES_ENCRYPTION WHERE NAME='db1/tab1'; +----------+-------------------+----------------+ | NAME | ENCRYPTION_SCHEME | CURRENT_KEY_ID | +----------+-------------------+----------------+ | db1/tab1 | 1 | 1 | +----------+-------------------+----------------+
Аналогичная проблема заключается в том, что если вы установите параметр ENCRYPTION_KEY_ID таблицы для таблицы, которая не зашифрована, потому что параметр таблицы ENCRYPTED установлено в значение NO, этот идентификатор ключа шифрования будет сохранён в файле таблицы .frm, но сам ключ шифрования не будет сохранён в файле таблицы .ibd.
Недавние версии MariaDB будут выдавать предупреждения в случае, когда параметр таблицы ENCRYPTED установлен в NO, но позволят операции успешно завершиться. Например:
CREATE TABLE tab1 ( id INT PRIMARY KEY, str VARCHAR(50) ) ENCRYPTED=NO ENCRYPTION_KEY_ID=100; Query OK, 0 rows affected, 1 warning (0.01 sec) SHOW WARNINGS; +---------+------+--------------------------------------------------+ | Level | Code | Message | +---------+------+--------------------------------------------------+ | Warning | 140 | InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 | +---------+------+--------------------------------------------------+ 1 row in set (0.00 sec)
Однако, в этом случае, если вы измените параметр таблицы ENCRYPTED на YES или DEFAULT с помощью ALTER TABLE, то будет использован правильный ключ. Например:
SET GLOBAL innodb_encrypt_tables=ON; ALTER TABLE tab1 ENCRYPTED=DEFAULT; SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID FROM information_schema.INNODB_TABLESPACES_ENCRYPTION WHERE NAME = 'db1/tab1'; +----------+-------------------+----------------+ | NAME | ENCRYPTION_SCHEME | CURRENT_KEY_ID | +----------+-------------------+----------------+ | db1/tab1 | 1 | 100 | +----------+-------------------+----------------+
Для получения дополнительной информации, см. MDEV-17230, MDEV-18601 и MDEV-19086.
Файлы таблиц, созданные в MySQL 5.1.47 или более ранних версиях
Реализация шифрования данных в состоянии покоя в MariaDB повторно использовала ранее неиспользуемые поля в страницах буфера пула InnoDB для идентификации версии ключа шифрования и контрольной суммы после шифрования. До MySQL 5.1.48 эти неиспользуемые поля не инициализировались в памяти из-за проблем с производительностью. Эти поля по большей части имели нулевые значения, но поскольку они не инициализировались явно, это означало, что эти поля могли иногда содержать ненулевые значения, которые могли быть записаны в файлы таблиц InnoDB. Если MariaDB столкнётся с незашифрованной страницей из файла таблиц, созданного в ранней версии MySQL, которая также имела ненулевые значения в этих полях, то она ошибочно посчитает, что страница зашифрована.
Исправление для MDEV-12112, включённое в MariaDB 10.1.38, MariaDB 10.2.20 и MariaDB 10.3.12 изменило способ различения MariaDB зашифрованных и незашифрованных страниц, чтобы уменьшить вероятность ошибочной интерпретации незашифрованной страницы как зашифрованной.
В MariaDB 10.4.3 и более поздних версиях, если innodb_checksum_algorithm установлен в full_crc32 или strict_full_crc32, и если таблица не использует ROW_FORMAT=COMPRESSED, то файлы данных будут гарантированно инициализированы нулями.
Для получения дополнительной информации, см. MDEV-18097.
Пространственные индексы
MariaDB 10.4.3 добавляет поддержку шифрования пространственных индексов. Для включения, установите innodb_checksum_algorithm в full_crc32 или в strict_full_crc32. Обратите внимание, что MariaDB шифрует только пространственные индексы, когда параметр таблицы ROW_FORMAT не установлен в COMPRESSED.
В более ранних версиях MariaDB шифрование пространственных индексов не поддерживается. Таблицы, содержащие пространственные индексы, хранят их незашифрованными.
Для получения дополнительной информации, см. MDEV-12026.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/innodb-encryption-troubleshooting/