diff --git a/CMakeLists.txt b/CMakeLists.txt index 48015fa29d0..053f2d4ec25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,7 +230,6 @@ MARK_AS_ADVANCED(WITH_FAST_MUTEXES) OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP}) IF (WITH_INNODB_DISALLOW_WRITES) - MESSAGE(STATUS "INNODB_DISALLOW_WRITES") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWITH_INNODB_DISALLOW_WRITES") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_INNODB_DISALLOW_WRITES") ENDIF() diff --git a/cmake/abi_check.cmake b/cmake/abi_check.cmake index aff6c437c3b..8a7e14b6f2d 100644 --- a/cmake/abi_check.cmake +++ b/cmake/abi_check.cmake @@ -44,7 +44,7 @@ IF(CMAKE_COMPILER_IS_GNUCC AND RUN_ABI_CHECK) ${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h ${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h ${CMAKE_SOURCE_DIR}/include/mysql/plugin_password_validation.h - ${CMAKE_SOURCE_DIR}/include/mysql/plugin_encryption_key_management.h + ${CMAKE_SOURCE_DIR}/include/mysql/plugin_encryption.h ) ADD_CUSTOM_TARGET(abi_check ALL diff --git a/cmake/check_compiler_flag.cmake b/cmake/check_compiler_flag.cmake index 8eb6ed2176e..4a029659f43 100644 --- a/cmake/check_compiler_flag.cmake +++ b/cmake/check_compiler_flag.cmake @@ -37,16 +37,16 @@ FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag) ENDIF() MY_CHECK_C_COMPILER_FLAG(${flag} HAVE_C_${flag}) MY_CHECK_CXX_COMPILER_FLAG(${flag} HAVE_CXX_${flag}) - IF (HAVE_C_${flag} AND HAVE_CXX_${flag}) - IF(ARGN) - FOREACH(type ${ARGN}) - SET(CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}} ${flag}" PARENT_SCOPE) - SET(CMAKE_CXX_FLAGS_${type} "${CMAKE_CXX_FLAGS_${type}} ${flag}" PARENT_SCOPE) - ENDFOREACH() - ELSE() - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE) + FOREACH(lang C CXX) + IF (HAVE_${lang}_${flag}) + IF(ARGN) + FOREACH(type ${ARGN}) + SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag}" PARENT_SCOPE) + ENDFOREACH() + ELSE() + SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${flag}" PARENT_SCOPE) + ENDIF() ENDIF() - ENDIF() + ENDFOREACH() ENDFUNCTION() diff --git a/debian/dist/Debian/mariadb-server-10.1.files.in b/debian/dist/Debian/mariadb-server-10.1.files.in index a81549d66bf..f6ffbc3388c 100644 --- a/debian/dist/Debian/mariadb-server-10.1.files.in +++ b/debian/dist/Debian/mariadb-server-10.1.files.in @@ -1,5 +1,6 @@ usr/lib/mysql/plugin/auth_pam.so usr/lib/mysql/plugin/auth_socket.so +usr/lib/mysql/plugin/file_key_management.so usr/lib/mysql/plugin/ha_archive.so usr/lib/mysql/plugin/ha_blackhole.so usr/lib/mysql/plugin/ha_federated.so diff --git a/debian/dist/Ubuntu/mariadb-server-10.1.files.in b/debian/dist/Ubuntu/mariadb-server-10.1.files.in index 534ccf84896..0e07df3e05f 100644 --- a/debian/dist/Ubuntu/mariadb-server-10.1.files.in +++ b/debian/dist/Ubuntu/mariadb-server-10.1.files.in @@ -1,5 +1,6 @@ usr/lib/mysql/plugin/auth_pam.so usr/lib/mysql/plugin/auth_socket.so +usr/lib/mysql/plugin/file_key_management.so usr/lib/mysql/plugin/ha_archive.so usr/lib/mysql/plugin/ha_blackhole.so usr/lib/mysql/plugin/ha_federated.so diff --git a/debian/mariadb-test-10.1.files b/debian/mariadb-test-10.1.files index 767f040b45a..dbb551a9407 100644 --- a/debian/mariadb-test-10.1.files +++ b/debian/mariadb-test-10.1.files @@ -1,3 +1,5 @@ +usr/lib/mysql/plugin/debug_key_management.so +usr/lib/mysql/plugin/example_key_management.so usr/lib/mysql/plugin/dialog_examples.so usr/lib/mysql/plugin/auth_test_plugin.so usr/lib/mysql/plugin/qa_auth_interface.so diff --git a/include/my_aes.h b/include/my_aes.h deleted file mode 100644 index 057fa1e9860..00000000000 --- a/include/my_aes.h +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright (c) 2002, 2006 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -/* Header file for my_aes.c */ -/* Wrapper to give simple interface for MySQL to AES standard encryption */ - -#ifndef MY_AES_INCLUDED -#define MY_AES_INCLUDED - -/* We expect same result code from encryption functions as in my_aes.h */ -typedef int Crypt_result; - -#define AES_OK 0 -#define AES_BAD_DATA -1 -#define AES_BAD_IV -2 -#define AES_INVALID -3 -#define AES_OPENSSL_ERROR -4 -#define AES_BAD_KEYSIZE -5 -#define AES_KEY_CREATION_FAILED -10 - -#define CRYPT_KEY_OK 0 -#define CRYPT_BUFFER_TO_SMALL -11 -#define CRYPT_KEY_UNKNOWN -48 - -/* The max block sizes of all supported algorithms */ -#define MY_AES_BLOCK_SIZE 16 - -/* The max key length of all supported algorithms */ -#define MY_AES_MAX_KEY_LENGTH 32 - - -#include "rijndael.h" - -C_MODE_START - -#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */ - -/** - Crypt buffer with AES dynamic (defined at startup) encryption algorithm. - - SYNOPSIS - my_aes_encrypt_dynamic() - @param source [in] Pointer to data for encryption - @param source_length [in] Size of encryption data - @param dest [out] Buffer to place encrypted data (must be large enough) - @param dest_length [out] Pointer to size of encrypted data - @param key [in] Key to be used for encryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set, algorithm specific padding behaviour is used - - Method used defined by calling my_aes_init_dynamic_encrypt() at startup. - - @return - != 0 error - 0 no error -*/ - -typedef int (*my_aes_encrypt_dynamic_type)(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const uchar* key, uint8 key_length, - const uchar* iv, uint8 iv_length, - uint noPadding); - -extern MYSQL_PLUGIN_IMPORT my_aes_encrypt_dynamic_type my_aes_encrypt_dynamic; - -/** - AES decryption AES dynamic (defined at startup) encryption algorithm. - - SYNOPSIS - my_aes_decrypt_dynamic() - @param source [in] Pointer to data to decrypt - @param source_length [in] Size of data - @param dest [out] Buffer to place decrypted data (must be large enough) - @param dest_length [out] Pointer to size of decrypted data - @param key [in] Key to be used for decryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set, algorithm specific padding behaviour is used - - @return - != 0 error - 0 no error - - Method used defined by calling my_aes_init_dynamic_encrypt() at startup. -*/ - -typedef int (*my_aes_decrypt_dynamic_type)(const uchar *source, - uint32 source_length, - uchar *dest, uint32 *dest_length, - const uchar *key, uint8 key_length, - const uchar *iv, uint8 iv_length, - uint noPadding); -extern MYSQL_PLUGIN_IMPORT my_aes_decrypt_dynamic_type my_aes_decrypt_dynamic; - -/** - Initialize dynamic crypt functions -*/ - -enum enum_my_aes_encryption_algorithm -{ - MY_AES_ALGORITHM_NONE, MY_AES_ALGORITHM_ECB, MY_AES_ALGORITHM_CBC, - MY_AES_ALGORITHM_CTR -}; - -my_aes_decrypt_dynamic_type get_aes_decrypt_func(enum enum_my_aes_encryption_algorithm method); -my_aes_encrypt_dynamic_type get_aes_encrypt_func(enum enum_my_aes_encryption_algorithm method); - - -my_bool my_aes_init_dynamic_encrypt(enum enum_my_aes_encryption_algorithm method); - -extern MYSQL_PLUGIN_IMPORT enum enum_my_aes_encryption_algorithm current_aes_dynamic_method; - - - -/** - Calculate key and iv from a given salt and secret as it is handled in openssl - encrypted files via console - - SYNOPSIS - my_bytes_to_key() - - @param salt [in] the given salt as extracted from the encrypted file - @param secret [in] the given secret as String, provided by the user - @param key [out] 32 Bytes of key are written to this pointer - @param iv [out] 16 Bytes of iv are written to this pointer - */ - -void my_bytes_to_key(const uchar *salt, - const char *secret, uchar *key, - uchar *iv); - -/** - Decode Hexencoded String to uint8[]. - - SYNOPSIS - my_aes_hex2uint() - @param iv [in] Pointer to hexadecimal encoded IV String - @param dest [out] Pointer to output uint8 array. Memory needs to be - allocated by caller - @param iv_length [in] Size of destination array. - */ - -void my_aes_hex2uint(const char *in, uchar *out, int dest_length); - -/** - Crypt buffer with AES encryption algorithm. - - SYNOPSIS - my_aes_encrypt() - - @param source Pointer to data for encryption - @param source_length Size of encryption data - @param dest Buffer to place encrypted data (must be large enough) - @param key Key to be used for encryption - @param kel_length Length of the key. Will handle keys of any length - - @return Size of encrypted data, or negative in case of error. -*/ - -int my_aes_encrypt(const uchar *source, int source_length, uchar *dest, - const char *key, int key_length); - -/** - DeCrypt buffer with AES encryption algorithm. - - SYNOPSIS - my_aes_decrypt() - - @param source Pointer to data for decryption - @param source_length size of encrypted data - @param dest buffer to place decrypted data (must be large enough) - @param key Key to be used for decryption - @param kel_length Length of the key. Will handle keys of any length - - @return size of original data, or negative in case of error. -*/ - - -int my_aes_decrypt(const uchar *source, int source_length, uchar *dest, - const char *key, int key_length); - -/** - get size of buffer which will be large enough for encrypted data - - SYNOPSIS - my_aes_get_size() - @param source_length Length of data to be encrypted - - @return Size of buffer required to store encrypted data -*/ - -int my_aes_get_size(int source_length); - -C_MODE_END - -#endif /* MY_AES_INCLUDED */ diff --git a/include/my_base.h b/include/my_base.h index 3f34adcef6d..a52ad51485e 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -354,8 +354,7 @@ enum ha_base_keytype { #define HA_CREATE_DELAY_KEY_WRITE 64 #define HA_CREATE_RELIES_ON_SQL_LAYER 128 #define HA_CREATE_INTERNAL_TABLE 256 -#define HA_CREATE_ENCRYPTED 512 -#define HA_INSERT_ORDER 1024 +#define HA_PRESERVE_INSERT_ORDER 512 /* Flags used by start_bulk_insert */ diff --git a/include/my_crypt.h b/include/my_crypt.h index ea095e11fa9..b760af75bfa 100644 --- a/include/my_crypt.h +++ b/include/my_crypt.h @@ -1,40 +1,87 @@ -// TODO: Add Windows support +/* + Copyright (c) 2014 Google Inc. + Copyright (c) 2014, 2015 MariaDB Corporation -#ifndef MYSYS_MY_CRYPT_H_ -#define MYSYS_MY_CRYPT_H_ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. -#include + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -#if !defined(HAVE_YASSL) && defined(HAVE_OPENSSL) + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -C_MODE_START -Crypt_result my_aes_encrypt_ctr(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding); +#ifndef MY_CRYPT_INCLUDED +#define MY_CRYPT_INCLUDED -Crypt_result my_aes_decrypt_ctr(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding); -C_MODE_END +#include -Crypt_result EncryptAes128Ctr(const uchar* key, - const uchar* iv, int iv_size, - const uchar* plaintext, int plaintext_size, - uchar* ciphertext, int* ciphertext_used); +#ifdef __cplusplus +extern "C" { +#endif -Crypt_result DecryptAes128Ctr(const uchar* key, - const uchar* iv, int iv_size, - const uchar* ciphertext, int ciphertext_size, - uchar* plaintext, int* plaintext_used); +/* return values from my_aes_encrypt/my_aes_decrypt functions */ +#define MY_AES_OK 0 +#define MY_AES_BAD_DATA -1 +#define MY_AES_OPENSSL_ERROR -2 +#define MY_AES_BAD_KEYSIZE -3 -#endif /* !defined(HAVE_YASSL) && defined(HAVE_OPENSSL) */ +/* The block size for all supported algorithms */ +#define MY_AES_BLOCK_SIZE 16 -C_MODE_START -Crypt_result my_random_bytes(uchar* buf, int num); -C_MODE_END +/* The max key length of all supported algorithms */ +#define MY_AES_MAX_KEY_LENGTH 32 -#endif /* MYSYS_MY_CRYPT_H_ */ +#ifdef HAVE_EncryptAes128Ctr + +int my_aes_encrypt_ctr(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +int my_aes_decrypt_ctr(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +#endif + +int my_aes_encrypt_cbc(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +int my_aes_decrypt_cbc(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +int my_aes_encrypt_ecb(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +int my_aes_decrypt_ecb(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding); + +int my_random_bytes(uchar* buf, int num); + +int my_aes_get_size(int source_length); + +#ifdef __cplusplus +} +#endif + +#endif /* MY_CRYPT_INCLUDED */ diff --git a/include/my_dbug.h b/include/my_dbug.h index 8d8d4fabd6c..bcf2015466d 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -176,9 +176,6 @@ extern void _db_suicide_(); #define DBUG_SYNC_POINT(lock_name,lock_timeout) \ debug_sync_point(lock_name,lock_timeout) void debug_sync_point(const char* lock_name, uint lock_timeout); - -/* Extern function for debugging */ -extern void dump_buffer(FILE *stream, unsigned n, const unsigned char* buf); #else #define DBUG_SYNC_POINT(lock_name,lock_timeout) #endif /* EXTRA_DEBUG */ diff --git a/include/my_md5.h b/include/my_md5.h index 34d3e931811..141ea309cae 100644 --- a/include/my_md5.h +++ b/include/my_md5.h @@ -28,7 +28,7 @@ extern "C" { #endif -#define compute_md5_hash(A,B,C) my_md5((unsigned char *)A,B,C) +#define compute_md5_hash(A,B,C) my_md5(A,B,C) /* Convert an array of bytes to a hexadecimal representation. diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 6a4e5448fa9..09026514a88 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -92,7 +92,7 @@ typedef struct st_mysql_xid MYSQL_XID; /* MariaDB plugin types */ #define MariaDB_PASSWORD_VALIDATION_PLUGIN 8 -#define MariaDB_ENCRYPTION_KEY_MANAGEMENT_PLUGIN 9 +#define MariaDB_ENCRYPTION_PLUGIN 9 /* We use the following strings to define licenses for plugins */ #define PLUGIN_LICENSE_PROPRIETARY 0 diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 8a04186ff77..7346c4f29b0 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -197,19 +197,22 @@ int thd_key_create(MYSQL_THD_KEY_T *key); void thd_key_delete(MYSQL_THD_KEY_T *key); void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key); int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value); -#include -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); +#include +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; +extern struct encryption_service_st encryption_handler; struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 8fbd7cd38c2..1df73b0a41e 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -197,19 +197,22 @@ int thd_key_create(MYSQL_THD_KEY_T *key); void thd_key_delete(MYSQL_THD_KEY_T *key); void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key); int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value); -#include -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); +#include +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; +extern struct encryption_service_st encryption_handler; struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_encryption.h b/include/mysql/plugin_encryption.h new file mode 100644 index 00000000000..90979017101 --- /dev/null +++ b/include/mysql/plugin_encryption.h @@ -0,0 +1,73 @@ +#ifndef MYSQL_PLUGIN_ENCRYPTION_INCLUDED +/* Copyright (C) 2014, 2015 Sergei Golubchik and MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + @file + + Encryption Plugin API. + + This file defines the API for server plugins that manage encryption + keys for MariaDB on-disk data encryption. +*/ + +#define MYSQL_PLUGIN_ENCRYPTION_INCLUDED + +#include + +#define MariaDB_ENCRYPTION_INTERFACE_VERSION 0x0200 + +/** + Encryption plugin descriptor +*/ +struct st_mariadb_encryption +{ + int interface_version; /**< version plugin uses */ + + /** + function returning latest key version for a given key id + + @return a version or ENCRYPTION_KEY_VERSION_INVALID to indicate an error. + */ + unsigned int (*get_latest_key_version)(unsigned int key_id); + + /** + function returning a key for a key version + + @param version the requested key version + @param key the key will be stored there. Can be NULL - + in which case no key will be returned + @param key_length in: key buffer size + out: the actual length of the key + + This method can be used to query the key length - the required + buffer size - by passing key==NULL. + + If the buffer size is less than the key length the content of the + key buffer is undefined (the plugin is free to partially fill it with + the key data or leave it untouched). + + @return 0 on success, or + ENCRYPTION_KEY_VERSION_INVALID, ENCRYPTION_KEY_BUFFER_TOO_SMALL + or any other non-zero number for errors + */ + unsigned int (*get_key)(unsigned int key_id, unsigned int version, + unsigned char *key, unsigned int *key_length); + + encrypt_decrypt_func encrypt; + encrypt_decrypt_func decrypt; +}; +#endif + diff --git a/include/mysql/plugin_encryption_key_management.h.pp b/include/mysql/plugin_encryption.h.pp similarity index 91% rename from include/mysql/plugin_encryption_key_management.h.pp rename to include/mysql/plugin_encryption.h.pp index fc162e143c6..2cf344864e4 100644 --- a/include/mysql/plugin_encryption_key_management.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -197,19 +197,22 @@ int thd_key_create(MYSQL_THD_KEY_T *key); void thd_key_delete(MYSQL_THD_KEY_T *key); void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key); int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value); -#include -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); +#include +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; +extern struct encryption_service_st encryption_handler; struct st_mysql_xid { long formatID; long gtrid_length; @@ -366,12 +369,12 @@ void *thd_get_ha_data(const void* thd, const struct handlerton *hton); void thd_set_ha_data(void* thd, const struct handlerton *hton, const void *ha_data); void thd_wakeup_subsequent_commits(void* thd, int wakeup_error); -struct st_mariadb_encryption_key_management +struct st_mariadb_encryption { int interface_version; - unsigned int (*get_latest_key_version)(); - unsigned int (*has_key_version)(unsigned int version); - unsigned int (*get_key_size)(unsigned int version); - int (*get_key)(unsigned int version, unsigned char* key, unsigned int keybufsize); - int (*get_iv)(unsigned int version, unsigned char* iv, unsigned int ivbufsize); + unsigned int (*get_latest_key_version)(unsigned int key_id); + unsigned int (*get_key)(unsigned int key_id, unsigned int version, + unsigned char *key, unsigned int *key_length); + encrypt_decrypt_func encrypt; + encrypt_decrypt_func decrypt; }; diff --git a/include/mysql/plugin_encryption_key_management.h b/include/mysql/plugin_encryption_key_management.h deleted file mode 100644 index af7730e5ee7..00000000000 --- a/include/mysql/plugin_encryption_key_management.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef MYSQL_PLUGIN_ENCRYPTION_KEY_MANAGEMENT_INCLUDED -/* Copyright (C) 2014 Sergei Golubchik and MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/** - @file - - Encryption key Management Plugin API. - - This file defines the API for server plugins that manage encryption - keys for MariaDB on-disk data encryption. -*/ - -#define MYSQL_PLUGIN_ENCRYPTION_KEY_MANAGEMENT_INCLUDED - -#include - -#define MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION 0x0100 - -#define BAD_ENCRYPTION_KEY_VERSION (UINT_MAX32) - -/** - Encryption key management plugin descriptor -*/ -struct st_mariadb_encryption_key_management -{ - int interface_version; /**< version plugin uses */ - - /** - function returning latest key version. - - @return a version or BAD_ENCRYPTION_KEY_VERSION to indicate an error. - */ - unsigned int (*get_latest_key_version)(); - - /** function returning if a key of the given version exists */ - unsigned int (*has_key_version)(unsigned int version); - - /** function returning the key size in bytes */ - unsigned int (*get_key_size)(unsigned int version); - - /** - function returning a key for a key version - - the key is put in 'key' buffer, that has size of 'keybufsize' bytes. - - @return 0 on success, non-zero on failure - */ - int (*get_key)(unsigned int version, unsigned char* key, unsigned int keybufsize); - - /** - function returning an IV for a key version - - the IV is put in 'iv' buffer, that has size of 'ivbufsize' bytes. - - @return 0 on success, non-zero on failure - */ - int (*get_iv)(unsigned int version, unsigned char* iv, unsigned int ivbufsize); -}; -#endif - diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 16374df7936..ee8ebc4299c 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -197,19 +197,22 @@ int thd_key_create(MYSQL_THD_KEY_T *key); void thd_key_delete(MYSQL_THD_KEY_T *key); void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key); int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value); -#include -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); +#include +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; +extern struct encryption_service_st encryption_handler; struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 2902a368985..e7dcc44f07a 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -197,19 +197,22 @@ int thd_key_create(MYSQL_THD_KEY_T *key); void thd_key_delete(MYSQL_THD_KEY_T *key); void* thd_getspecific(void* thd, MYSQL_THD_KEY_T key); int thd_setspecific(void* thd, MYSQL_THD_KEY_T key, void *value); -#include -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); +#include +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; +extern struct encryption_service_st encryption_handler; struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/service_cryptokeys.h b/include/mysql/service_cryptokeys.h deleted file mode 100644 index d5321e2f257..00000000000 --- a/include/mysql/service_cryptokeys.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MYSQL_SERVICE_CRYPTOKEYS_INCLUDED -/* Copyright (c) 2015, MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/** - @file - cryptokeys service - - Functions get cryptographical keys and IV from the cryptokey management plugin -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern struct cryptokeys_service_st { - unsigned int (*get_latest_crypto_key_version_func)(); - unsigned int (*has_crypto_key_func)(unsigned int); - unsigned int (*get_crypto_key_size_func)(unsigned int); - int (*get_crypto_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_crypto_iv_func)(unsigned int, unsigned char*, unsigned int); -} *cryptokeys_service; - -#ifdef MYSQL_DYNAMIC_PLUGIN - -#define get_latest_crypto_key_version() cryptokeys_service->get_latest_crypto_key_version_func() -#define has_crypto_key(V) cryptokeys_service->has_crypto_key_func(V) -#define get_crypto_key_size(V) cryptokeys_service->get_crypto_key_size_func(V) -#define get_crypto_key(V,K,S) cryptokeys_service->get_crypto_key_func((V), (K), (S)) -#define get_crypto_iv(V, I, S) cryptokeys_service->get_crypto_iv_func((V), (I), (S)) - -#else - -unsigned int get_latest_crypto_key_version(); -unsigned int has_crypto_key(unsigned int version); -unsigned int get_crypto_key_size(unsigned int version); -int get_crypto_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_crypto_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); - -#endif - -#ifdef __cplusplus -} -#endif - -#define MYSQL_SERVICE_CRYPTOKEYS_INCLUDED -#endif - diff --git a/include/mysql/service_encryption.h b/include/mysql/service_encryption.h new file mode 100644 index 00000000000..2ed29d594a6 --- /dev/null +++ b/include/mysql/service_encryption.h @@ -0,0 +1,82 @@ +#ifndef MYSQL_SERVICE_ENCRYPTION_INCLUDED +/* Copyright (c) 2015, MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + @file + encryption service + + Functions to support data encryption and encryption key management. + They are normally implemented in an encryption plugin, so this service + connects encryption *consumers* (storage engines) to the encryption + *provider* (encryption plugin). +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* returned from encryption_key_get_latest_version() */ +#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0) +#define ENCRYPTION_KEY_NOT_ENCRYPTED (0) + +/* returned from encryption_key_get() */ +#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100) + +typedef int (*encrypt_decrypt_func)(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int key_id, + unsigned int key_version); + +struct encryption_service_st { + unsigned int (*encryption_key_get_latest_version_func)(unsigned int); + unsigned int (*encryption_key_id_exists_func)(unsigned int); + unsigned int (*encryption_key_version_exists_func)(unsigned int, unsigned int); + unsigned int (*encryption_key_get_func)(unsigned int, unsigned int, unsigned char*, unsigned int*); + encrypt_decrypt_func encryption_encrypt_func; + encrypt_decrypt_func encryption_decrypt_func; +}; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +extern struct encryption_service_st *encryption_service; + +#define encryption_key_get_latest_version(KI) encryption_service->encryption_key_get_latest_version_func(KI) +#define encryption_key_id_exists(KI) encryption_service->encryption_key_id_exists_func((KI)) +#define encryption_key_version_exists(KI,KV) encryption_service->encryption_key_version_exists_func((KI),(KV)) +#define encryption_key_get(KI,KV,K,S) encryption_service->encryption_key_get_func((KI),(KV),(K),(S)) +#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV)) +#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_service->encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV)) +#else + +extern struct encryption_service_st encryption_handler; + +#define encryption_key_get_latest_version(KI) encryption_handler.encryption_key_get_latest_version_func(KI) +#define encryption_key_id_exists(KI) encryption_handler.encryption_key_id_exists_func((KI)) +#define encryption_key_version_exists(KI,KV) encryption_handler.encryption_key_version_exists_func((KI),(KV)) +#define encryption_key_get(KI,KV,K,S) encryption_handler.encryption_key_get_func((KI),(KV),(K),(S)) +#define encryption_encrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_encrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV)) +#define encryption_decrypt(S,SL,D,DL,K,KL,I,IL,NP,KI,KV) encryption_handler.encryption_decrypt_func((S),(SL),(D),(DL),(K),(KL),(I),(IL),(NP),(KI),(KV)) +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_ENCRYPTION_INCLUDED +#endif + diff --git a/include/mysql/service_encryption_keys.h b/include/mysql/service_encryption_keys.h deleted file mode 100644 index 69cbcb70592..00000000000 --- a/include/mysql/service_encryption_keys.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MYSQL_SERVICE_ENCRYPTION_KEYS_INCLUDED -/* Copyright (c) 2015, MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/** - @file - encryption keys service - - Functions to get encryption keys and IV from the encryption key management plugin -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern struct encryption_keys_service_st { - unsigned int (*get_latest_encryption_key_version_func)(); - unsigned int (*has_encryption_key_func)(unsigned int); - unsigned int (*get_encryption_key_size_func)(unsigned int); - int (*get_encryption_key_func)(unsigned int, unsigned char*, unsigned int); - int (*get_encryption_iv_func)(unsigned int, unsigned char*, unsigned int); -} *encryption_keys_service; - -#ifdef MYSQL_DYNAMIC_PLUGIN - -#define get_latest_encryption_key_version() encryption_keys_service->get_latest_encryption_key_version_func() -#define has_encryption_key(V) encryption_keys_service->has_encryption_key_func(V) -#define get_encryption_key_size(V) encryption_keys_service->get_encryption_key_size_func(V) -#define get_encryption_key(V,K,S) encryption_keys_service->get_encryption_key_func((V), (K), (S)) -#define get_encryption_iv(V, I, S) encryption_keys_service->get_encryption_iv_func((V), (I), (S)) - -#else - -unsigned int get_latest_encryption_key_version(); -unsigned int has_encryption_key(unsigned int version); -unsigned int get_encryption_key_size(unsigned int version); -int get_encryption_key(unsigned int version, unsigned char* key, unsigned int keybufsize); -int get_encryption_iv(unsigned int version, unsigned char* iv, unsigned int ivbufsize); - -#endif - -#ifdef __cplusplus -} -#endif - -#define MYSQL_SERVICE_ENCRYPTION_KEYS_INCLUDED -#endif - diff --git a/include/mysql/service_sha1.h b/include/mysql/service_sha1.h index 609e173e8ce..e000c898dd7 100644 --- a/include/mysql/service_sha1.h +++ b/include/mysql/service_sha1.h @@ -44,10 +44,10 @@ extern struct my_sha1_service_st { #define my_sha1(A,B,C) my_sha1_service->my_sha1_type(A,B,C) #define my_sha1_multi my_sha1_service->my_sha1_multi_type -#define my_sha1_context_size_type() my_sha1_service->my_sha1_context_size_type() -#define my_sha1_init_type(A) my_sha1_service->my_sha1_init_type(A) -#define my_sha1_input_type(A,B,C) my_sha1_service->my_sha1_input_type(A,B,C) -#define my_sha1_result_type(A,B) my_sha1_service->my_sha1_result_type(A,B) +#define my_sha1_context_size() my_sha1_service->my_sha1_context_size_type() +#define my_sha1_init(A) my_sha1_service->my_sha1_init_type(A) +#define my_sha1_input(A,B,C) my_sha1_service->my_sha1_input_type(A,B,C) +#define my_sha1_result(A,B) my_sha1_service->my_sha1_result_type(A,B) #else diff --git a/include/mysql/service_thd_alloc.h b/include/mysql/service_thd_alloc.h index 645fb310cbc..e92f81b52c3 100644 --- a/include/mysql/service_thd_alloc.h +++ b/include/mysql/service_thd_alloc.h @@ -16,7 +16,7 @@ /** @file - This service provdes functions to allocate memory in a connection local + This service provides functions to allocate memory in a connection local memory pool. The memory allocated there will be automatically freed at the end of the statement, don't use it for allocations that should live longer than that. For short living allocations this is more efficient than diff --git a/include/mysql/services.h b/include/mysql/services.h index 764e05b4dd1..f8f41b19bd9 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -32,7 +32,7 @@ extern "C" { #include #include #include -#include +#include /*#include */ #ifdef __cplusplus diff --git a/include/service_versions.h b/include/service_versions.h index 3d85be92519..0f3d8af5723 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -35,5 +35,5 @@ #define VERSION_thd_autoinc 0x0100 #define VERSION_thd_error_context 0x0100 #define VERSION_thd_specifics 0x0100 -#define VERSION_encryption_keys 0x0100 +#define VERSION_encryption 0x0200 diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 3472ee85f2f..93ed96321d5 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -106,7 +106,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/compat56.cc ../sql/table_cache.cc ../sql/item_inetfunc.cc - ../sql/wsrep_dummy.cc ../sql/encryption_keys.cc + ../sql/wsrep_dummy.cc ../sql/encryption.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 74055ee5b11..1dc472612e6 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -28,7 +28,7 @@ SET(MYSQLSERVICES_SOURCES my_sha1_service.c my_md5_service.c wsrep_service.c - encryption_keys_service.c + encryption_service.c kill_statement_service.c logger_service.c) diff --git a/libservices/encryption_keys_service.c b/libservices/encryption_keys_service.c deleted file mode 100644 index 81fc7def201..00000000000 --- a/libservices/encryption_keys_service.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2015 MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include -SERVICE_VERSION encryption_keys_service= (void*)VERSION_encryption_keys; diff --git a/libservices/cryptokeys_service.c b/libservices/encryption_service.c similarity index 92% rename from libservices/cryptokeys_service.c rename to libservices/encryption_service.c index 1af64aab450..f57575ae3e8 100644 --- a/libservices/cryptokeys_service.c +++ b/libservices/encryption_service.c @@ -14,4 +14,4 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include -SERVICE_VERSION cryptokeys_service= (void*)VERSION_cryptokeys; +SERVICE_VERSION encryption_service= (void*)VERSION_encryption; diff --git a/mysql-test/include/encryption_algorithms.combinations b/mysql-test/include/encryption_algorithms.combinations index 09c1e91e1cd..f8598401e5f 100644 --- a/mysql-test/include/encryption_algorithms.combinations +++ b/mysql-test/include/encryption_algorithms.combinations @@ -1,8 +1,5 @@ [cbc] -encryption-algorithm=aes_cbc - -[ecb] -encryption-algorithm=aes_ecb +file-key-management-encryption-algorithm=aes_cbc [ctr] -encryption-algorithm=aes_ctr +file-key-management-encryption-algorithm=aes_ctr diff --git a/mysql-test/include/have_example_key_management_plugin.inc b/mysql-test/include/have_example_key_management_plugin.inc index 3bb4529b623..a87d3256ee0 100644 --- a/mysql-test/include/have_example_key_management_plugin.inc +++ b/mysql-test/include/have_example_key_management_plugin.inc @@ -1,7 +1,4 @@ --- source encryption_algorithms.inc - -if (`select count(*) = 0 from information_schema.plugins - where plugin_name = 'example_key_management_plugin' and plugin_status='active'`) +if (!$EXAMPLE_KEY_MANAGEMENT_SO) { - --skip Needs example_key_management_plugin + --skip Needs example_key_management } diff --git a/mysql-test/include/have_example_key_management_plugin.opt b/mysql-test/include/have_example_key_management_plugin.opt index 581ee1c73b9..ce7f1ddef7e 100644 --- a/mysql-test/include/have_example_key_management_plugin.opt +++ b/mysql-test/include/have_example_key_management_plugin.opt @@ -1,2 +1,2 @@ ---plugin-load-add=$EXAMPLE_KEY_MANAGEMENT_PLUGIN_SO ---loose-example-key-management-plugin +--plugin-load-add=$EXAMPLE_KEY_MANAGEMENT_SO +--loose-example-key-management diff --git a/mysql-test/include/have_file_key_management_plugin.inc b/mysql-test/include/have_file_key_management_plugin.inc index 3b3eb036ede..baada3a7d47 100644 --- a/mysql-test/include/have_file_key_management_plugin.inc +++ b/mysql-test/include/have_file_key_management_plugin.inc @@ -1,7 +1,6 @@ --- source encryption_algorithms.inc +--source encryption_algorithms.inc -if (`select count(*) = 0 from information_schema.plugins - where plugin_name = 'file_key_management_plugin' and plugin_status='active'`) +if (!$FILE_KEY_MANAGEMENT_SO) { - --skip Needs file_key_management_plugin + --skip Needs file_key_management } diff --git a/mysql-test/include/have_file_key_management_plugin.opt b/mysql-test/include/have_file_key_management_plugin.opt index 5aa1ce18b00..76808d02a7a 100644 --- a/mysql-test/include/have_file_key_management_plugin.opt +++ b/mysql-test/include/have_file_key_management_plugin.opt @@ -1,4 +1,4 @@ ---plugin-load-add=$FILE_KEY_MANAGEMENT_PLUGIN_SO ---loose-file-key-management-plugin ---loose-file-key-management-plugin-filename=$MYSQL_TEST_DIR/std_data/keys.txt +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index 0d09cdcd36e..84237026ed0 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -60,12 +60,12 @@ perl; use strict; - my $search_file= $ENV{'SEARCH_FILE'} or die "SEARCH_FILE not set"; - my $search_pattern= $ENV{'SEARCH_PATTERN'} or die "SEARCH_PATTERN not set"; - my $search_range= $ENV{'SEARCH_RANGE'}; + my $search_file= $ENV{'SEARCH_FILE'} or die "SEARCH_FILE not set"; + my $search_pattern= $ENV{'SEARCH_PATTERN'} or die "SEARCH_PATTERN not set"; + my $search_range= $ENV{'SEARCH_RANGE'}; my $file_content; $search_range= 50000 unless $search_range =~ /-?[0-9]+/; - open(FILE, "$search_file") or die("Unable to open '$search_file': $!\n"); + open(FILE, '<', $search_file) or die("Unable to open '$search_file': $!\n"); if ($search_range >= 0) { read(FILE, $file_content, $search_range, 0); } else { @@ -75,7 +75,10 @@ perl; read(FILE, $file_content, -$search_range, 0); } close(FILE); - if ( not $file_content =~ m{$search_pattern} ) { - die("# ERROR: The file '$search_file' does not contain the expected pattern $search_pattern\n->$file_content<-\n"); + $search_file =~ s{^.*?([^/\\]+)$}{$1}; + if ($file_content =~ m{$search_pattern}) { + print "FOUND /$search_pattern/ in $search_file\n" + } else { + print "NOT FOUND /$search_pattern/ in $search_file\n" } EOF diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 97348cd39fc..60535a2009b 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -618,7 +618,7 @@ sub make_combinations($$@) if (My::Options::is_set($test->{master_opt}, $comb->{comb_opt}) && My::Options::is_set($test->{slave_opt}, $comb->{comb_opt}) ){ - delete $test_combs->{$comb->{name}}; + $test_combs->{$comb->{name}} = 2; # Add combination name short name push @{$test->{combinations}}, $comb->{name}; @@ -627,8 +627,9 @@ sub make_combinations($$@) } # Skip all other combinations, if this combination is forced - if (delete $test_combs->{$comb->{name}}) { + if ($test_combs->{$comb->{name}}) { @combinations = ($comb); # run the loop below only for this combination + $test_combs->{$comb->{name}} = 2; last; } } @@ -858,9 +859,10 @@ sub collect_one_test_case { { @cases = map make_combinations($_, \%test_combs, @{$comb}), @cases; } - if (keys %test_combs) { + my @no_combs = grep { $test_combs{$_} == 1 } keys %test_combs; + if (@no_combs) { mtr_error("Could not run $name with '".( - join(',', sort keys %test_combs))."' combination(s)"); + join(',', sort @no_combs))."' combination(s)"); } for $tinfo (@cases) { diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 544e64e6373..b8ca95c3b45 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2007,3 +2007,22 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e; ALTER TABLE t1 MODIFY i FLOAT; DROP TABLE t1; +# +# Start of 10.1 tests +# +# +# MDEV-7816 ALTER with DROP INDEX and ADD INDEX .. COMMENT='comment2' ignores the new comment +# +CREATE TABLE t1(a INT); +CREATE INDEX i1 ON t1(a) COMMENT 'comment1'; +ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + KEY `i1` (`a`) COMMENT 'comment2' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +# +# Start of 10.1 tests +# diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 7d59ecd1dc2..3bd5e296ec9 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -165,10 +165,6 @@ The following options may be given as the first argument: --encrypt-tmp-disk-tables Encrypt tmp disk tables (created as part of query execution) - --encryption-algorithm=name - Which encryption algorithm to use for table encryption. - aes_cbc is the recommended one.. One of: none, aes_ecb, - aes_cbc, aes_ctr --enforce-storage-engine=name Force the use of a storage engine for new tables --event-scheduler[=name] @@ -1151,7 +1147,6 @@ delayed-insert-timeout 300 delayed-queue-size 1000 div-precision-increment 4 encrypt-tmp-disk-tables FALSE -encryption-algorithm none enforce-storage-engine (No default value) event-scheduler OFF expensive-subquery-limit 100 diff --git a/mysql-test/r/partition_example.result b/mysql-test/r/partition_example.result index 7b6e9aa5213..2129eea0818 100644 --- a/mysql-test/r/partition_example.result +++ b/mysql-test/r/partition_example.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ @@ -20,7 +20,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index d9838175349..9f4aff6bae9 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -127,7 +127,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,f,f,f' -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 drop table t1; SET @OLD_SQL_MODE=@@SQL_MODE; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; @@ -142,7 +142,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS #alter table alter table t1 ULL=10000000; Warnings: @@ -152,7 +152,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 alter table t1 change a a int complex='c,c,c'; Warnings: Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> 'c,c,c' @@ -161,14 +161,14 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,c,c', `b` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 alter table t1 one_or_two=two; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,c,c', `b` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 `one_or_two`=two +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `ULL`=10000000 `one_or_two`=two drop table t1; #illegal value error SET SQL_MODE=''; @@ -183,11 +183,11 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 SET example_varopt_default=33; select create_options from information_schema.tables where table_schema='test' and table_name='t1'; create_options -`ULL`=4660 `VAROPT`='5' +`ULL`=4660 ALTER TABLE t1 ULL=DEFAULT; Warnings: Note 1105 EXAMPLE DEBUG: ULL 4660 -> 4294967295 @@ -195,14 +195,14 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 DROP TABLE t1; create table t1 (a int) engine=example; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`=33 drop table t1; create table t1 (a int) engine=example varopt=15; show create table t1; @@ -215,7 +215,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`=33 drop table t1; SET @@SQL_MODE=@OLD_SQL_MODE; select 1; diff --git a/mysql-test/r/table_options-5867.result b/mysql-test/r/table_options-5867.result index 21041c7c5c3..f915c2740ae 100644 --- a/mysql-test/r/table_options-5867.result +++ b/mysql-test/r/table_options-5867.result @@ -14,7 +14,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,f,f,f' `invalid`=3 -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=10000 `str`='dskj' `one_or_two`='one' `yesno`=0 `foobar`=barfoo `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=10000 `str`='dskj' `one_or_two`='one' `yesno`=0 `foobar`=barfoo show create table t2; Table Create Table t2 CREATE TABLE `t2` ( @@ -26,7 +26,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,f,f,f' /* `invalid`=3 */ -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=10000 `str`='dskj' `one_or_two`='one' `yesno`=0 /* `foobar`=barfoo */ `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=10000 `str`='dskj' `one_or_two`='one' `yesno`=0 /* `foobar`=barfoo */ show create table t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 083ed9686d4..abb9c6240d3 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5395,6 +5395,7 @@ DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1, t2; create view v1 as select 1; +FOUND /mariadb-version/ in v1.frm drop view v1; # # MDEV-7260: Crash in get_best_combination when executing multi-table diff --git a/mysql-test/std_data/keys.txt b/mysql-test/std_data/keys.txt index 419b76f698f..e511521d7ab 100644 --- a/mysql-test/std_data/keys.txt +++ b/mysql-test/std_data/keys.txt @@ -1,6 +1,12 @@ -1;F5502320F8429037B8DAEF761B189D12;770A8A65DA156D24EE2A093277530142 -2;35B2FF0795FB84BBD666DB8430CA214E;4D92199549E0F2EF009B4160F3582E5528A11A45017F3EF8 -3;7E892875A52C59A3B588306B13C31FBD;B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF -4;021B0663D4DD7B54E2EBC852677E40BD;18420B5CBA31CCDFFE9716E91EB61374D05914F3ADE23E03 -5;9BF92CEA026CE732DA80821122A8CE97;966050D7777350B6FD5CCB3E5F648DA45C63BEFB6DEDDFA13443F156B7D35C84 -6;BC44D4AFD2D9FCD82A679E4DC6700D06;B5EA210C8C09EF20DB95EC584714A89F +# +# this is a comment +# +1;770A8A65DA156D24EE2A093277530142 +2;4D92199549E0F2EF009B4160F3582E5528A11A45017F3EF8 + # another comment +33;B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF +4;18420B5CBA31CCDFFE9716E91EB61374D05914F3ADE23E03 --> ignored + +5;966050D7777350B6FD5CCB3E5F648DA45C63BEFB6DEDDFA13443F156B7D35C84 +6;B5EA210C8C09EF20DB95EC584714A89F # and yet another + diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm index 220c15eb172..5eafd4e2ffd 100644 --- a/mysql-test/suite.pm +++ b/mysql-test/suite.pm @@ -70,12 +70,6 @@ sub skip_combinations { unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ and $1 ge "1.0.1"; - $skip{'include/have_example_key_management_plugin.inc'} = 'no example_key_management_plugin' - unless $ENV{EXAMPLE_KEY_MANAGEMENT_PLUGIN_SO}; - - $skip{'include/have_file_key_management_plugin.inc'} = 'no file_key_management_plugin' - unless $ENV{FILE_KEY_MANAGEMENT_PLUGIN_SO}; - %skip; } diff --git a/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result b/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result index cc2a0373444..07e13008e27 100644 --- a/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result +++ b/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result @@ -33,6 +33,7 @@ INSERT INTO t1 VALUES(1,'X',1); SET DEBUG_DBUG='+d,crash_after_log_ibuf_upd_inplace'; SELECT b FROM t1 LIMIT 3; ERROR HY000: Lost connection to MySQL server during query +FOUND /Wrote log record for ibuf update in place operation/ in my_restart.err CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK diff --git a/mysql-test/suite/innodb/r/innodb-page_encryption-32k.result b/mysql-test/suite/innodb/r/innodb-page_encryption-32k.result new file mode 100644 index 00000000000..6aa98a2fc68 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-page_encryption-32k.result @@ -0,0 +1,125 @@ +call mtr.add_suppression("InnoDB: Warning: innodb_page_size has been changed from default value *"); +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=3 +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num, substring(MD5(RAND()), -150)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(5000); +commit; +set autocommit=1; +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; +drop table innodb_redundant; diff --git a/mysql-test/suite/innodb/r/innodb-page_encryption.result b/mysql-test/suite/innodb/r/innodb-page_encryption.result index dfc93508b90..2a52d1a07b3 100644 --- a/mysql-test/suite/innodb/r/innodb-page_encryption.result +++ b/mysql-test/suite/innodb/r/innodb-page_encryption.result @@ -1,42 +1,44 @@ SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1; -create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed page_encryption=1 page_encryption_key=2; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=3; -create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_encryption=1 page_encryption_key=4; -SET GLOBAL innodb_default_page_encryption_key = 5; -create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb page_encryption=1; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +ERROR HY000: Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +set innodb_default_encryption_key_id = 5; +create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb encrypted=yes; show create table innodb_defkey; Table Create Table innodb_defkey CREATE TABLE `innodb_defkey` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_encryption`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `ENCRYPTION_KEY_ID`=5 show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `page_encryption`=1 `page_encryption_key`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 show create table innodb_compressed; Table Create Table innodb_compressed CREATE TABLE `innodb_compressed` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `page_encryption`=1 `page_encryption_key`=2 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `encrypted`=yes `encryption_key_id`=2 show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `page_encryption`=1 `page_encryption_key`=3 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=33 show create table innodb_redundant; Table Create Table innodb_redundant CREATE TABLE `innodb_redundant` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `page_encryption`=1 `page_encryption_key`=4 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 create procedure innodb_insert_proc (repeat_count int) begin declare current_num int; @@ -97,15 +99,12 @@ select count(*) from innodb_defkey t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; update innodb_normal set c1 = c1 +1; @@ -149,37 +148,34 @@ select count(*) from innodb_defkey t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -alter table innodb_compressed engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compressed; Table Create Table innodb_compressed CREATE TABLE `innodb_compressed` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC -alter table innodb_redundant engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_redundant; Table Create Table innodb_redundant CREATE TABLE `innodb_redundant` ( @@ -217,7 +213,7 @@ Table Create Table innodb_defkey CREATE TABLE `innodb_defkey` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_encryption`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `ENCRYPTION_KEY_ID`=5 update innodb_normal set c1 = c1 +1; update innodb_compact set c1 = c1 + 1; update innodb_compressed set c1 = c1 + 1; @@ -251,13 +247,10 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value = 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -variable_value = 0 -1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value = 0 1 drop procedure innodb_insert_proc; diff --git a/mysql-test/suite/innodb/r/innodb-page_encryption_compression.result b/mysql-test/suite/innodb/r/innodb-page_encryption_compression.result index 781a29cb276..02a13b3c13c 100644 --- a/mysql-test/suite/innodb/r/innodb-page_encryption_compression.result +++ b/mysql-test/suite/innodb/r/innodb-page_encryption_compression.result @@ -2,8 +2,8 @@ SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1 page_compressed=1; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=2 page_compressed=1; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1 page_compressed=1; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=2 page_compressed=1; show warnings; Level Code Message show create table innodb_normal; @@ -17,13 +17,13 @@ Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `page_encryption`=1 `page_encryption_key`=1 `page_compressed`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 `page_compressed`=1 show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `page_encryption`=1 `page_encryption_key`=2 `page_compressed`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=2 `page_compressed`=1 create procedure innodb_insert_proc (repeat_count int) begin declare current_num int; @@ -60,21 +60,16 @@ select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 5000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; variable_value >= 0 -1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; variable_value >= 0 -1 SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; @@ -98,21 +93,16 @@ select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 5000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -variable_value > 0 -1 -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; -variable_value > 0 -1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; +variable_value >= 0 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; +variable_value >= 0 alter table innodb_normal engine=innodb page_compressed=DEFAULT; show create table innodb_normal; Table Create Table @@ -120,14 +110,14 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT page_compressed=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT page_compressed=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( @@ -174,21 +164,16 @@ select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 5000 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value = 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value = 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; variable_value = 0 -1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; variable_value = 0 -1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; -variable_value = 0 -1 drop procedure innodb_insert_proc; drop table innodb_normal; drop table innodb_compact; diff --git a/mysql-test/suite/innodb/r/innodb-page_encryption_log_encryption.result b/mysql-test/suite/innodb/r/innodb-page_encryption_log_encryption.result index 3830bfee22b..5a3a46e3620 100644 --- a/mysql-test/suite/innodb/r/innodb-page_encryption_log_encryption.result +++ b/mysql-test/suite/innodb/r/innodb-page_encryption_log_encryption.result @@ -4,34 +4,34 @@ call mtr.add_suppression("InnoDB: Redo log crypto: Can't initialize to key versi SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1; -create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed page_encryption=1 page_encryption_key=2; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=3; -create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_encryption=1 page_encryption_key=4; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `page_encryption`=1 `page_encryption_key`=1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 show create table innodb_compressed; Table Create Table innodb_compressed CREATE TABLE `innodb_compressed` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `page_encryption`=1 `page_encryption_key`=2 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `encrypted`=yes `encryption_key_id`=2 show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `page_encryption`=1 `page_encryption_key`=3 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=33 show create table innodb_redundant; Table Create Table innodb_redundant CREATE TABLE `innodb_redundant` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `page_encryption`=1 `page_encryption_key`=4 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 create procedure innodb_insert_proc (repeat_count int) begin declare current_num int; @@ -83,15 +83,12 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; update innodb_normal set c1 = c1 +1; @@ -127,37 +124,34 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -alter table innodb_compressed engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compressed; Table Create Table innodb_compressed CREATE TABLE `innodb_compressed` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_dynamic; Table Create Table innodb_dynamic CREATE TABLE `innodb_dynamic` ( `c1` bigint(20) NOT NULL, `b` char(200) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC -alter table innodb_redundant engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_redundant; Table Create Table innodb_redundant CREATE TABLE `innodb_redundant` ( @@ -223,13 +217,10 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value = 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -variable_value = 0 -1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value = 0 1 drop procedure innodb_insert_proc; diff --git a/mysql-test/suite/innodb/r/innodb_encryption-page-compression.result b/mysql-test/suite/innodb/r/innodb_encryption-page-compression.result index d4a049d36d0..c46cfebd7d2 100644 --- a/mysql-test/suite/innodb/r/innodb_encryption-page-compression.result +++ b/mysql-test/suite/innodb/r/innodb_encryption-page-compression.result @@ -1,9 +1,3 @@ SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; -create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; -ERROR HY000: Can't create table `test`.`innodb_normal` (errno: 140 "Wrong create options") -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_compressed=1; -ERROR HY000: Can't create table `test`.`innodb_compact` (errno: 140 "Wrong create options") -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_compressed=1; -ERROR HY000: Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") diff --git a/mysql-test/suite/innodb/r/innodb_encryption.result b/mysql-test/suite/innodb/r/innodb_encryption.result index 040cbd294f9..283c78e33d3 100644 --- a/mysql-test/suite/innodb/r/innodb_encryption.result +++ b/mysql-test/suite/innodb/r/innodb_encryption.result @@ -1,7 +1,7 @@ SET @start_global_value = @@global.innodb_encryption_threads; SHOW VARIABLES LIKE 'innodb_encrypt%'; Variable_name Value -innodb_encrypt_log OFF +innodb_encrypt_log ON innodb_encrypt_tables ON innodb_encryption_rotate_key_age 15 innodb_encryption_rotation_iops 100 @@ -44,7 +44,7 @@ SET GLOBAL innodb_encryption_threads=@start_global_value; # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 SHOW VARIABLES LIKE 'innodb_encrypt%'; Variable_name Value -innodb_encrypt_log OFF +innodb_encrypt_log ON innodb_encrypt_tables OFF innodb_encryption_rotate_key_age 15 innodb_encryption_rotation_iops 100 diff --git a/mysql-test/suite/innodb/r/innodb_encryption_debug.result b/mysql-test/suite/innodb/r/innodb_encryption_debug.result new file mode 100644 index 00000000000..45d629e52e6 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_encryption_debug.result @@ -0,0 +1,19 @@ +show variables like 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log ON +innodb_encrypt_tables ON +innodb_encryption_rotate_key_age 2 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 4 +select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; +space name current_key_version +0 NULL 1 +1 mysql/innodb_table_stats 1 +2 mysql/innodb_index_stats 1 +set global debug_key_management_version=10; +select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; +space name current_key_version +0 NULL 10 +1 mysql/innodb_table_stats 10 +2 mysql/innodb_index_stats 10 +set global debug_key_management_version=1; diff --git a/mysql-test/suite/innodb/r/innodb_encryption_force.result b/mysql-test/suite/innodb/r/innodb_encryption_force.result new file mode 100644 index 00000000000..8e129899275 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_encryption_force.result @@ -0,0 +1,47 @@ +select @@innodb_encrypt_tables; +@@innodb_encrypt_tables +FORCE +create table t1 (a int) engine=innodb encrypted=yes; +create table t2 (a int) engine=innodb encrypted=default; +create table t3 (a int) engine=innodb encrypted=no; +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") +set global innodb_encrypt_tables='ON'; +create table t3 (a int) engine=innodb encrypted=no; +set global innodb_encrypt_tables='FORCE'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=no +alter table t1 encrypted=no; +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +alter table t2 encrypted=yes; +alter table t3 encrypted=default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +drop table t2; +drop table t3; diff --git a/mysql-test/suite/innodb/r/innodb_encryption_tables.result b/mysql-test/suite/innodb/r/innodb_encryption_tables.result index f07aa62837c..ee5be0bfdd3 100644 --- a/mysql-test/suite/innodb/r/innodb_encryption_tables.result +++ b/mysql-test/suite/innodb/r/innodb_encryption_tables.result @@ -91,15 +91,12 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 -1 SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; variable_value >= 0 1 @@ -144,21 +141,18 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; count(*) 2000 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; variable_value >= 0 1 -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; variable_value >= 0 1 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -variable_value = 0 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +variable_value >= 0 1 -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -variable_value > 0 -0 -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; -variable_value > 0 -0 drop procedure innodb_insert_proc; drop table innodb_normal; drop table innodb_compact; diff --git a/mysql-test/suite/innodb/r/innodb_monitor.result b/mysql-test/suite/innodb/r/innodb_monitor.result index 02e72ae6a80..0977c8b8594 100644 --- a/mysql-test/suite/innodb/r/innodb_monitor.result +++ b/mysql-test/suite/innodb/r/innodb_monitor.result @@ -180,9 +180,8 @@ compress_page_compressed_trim_op disabled compress_page_compressed_trim_op_saved disabled compress_pages_page_decompressed disabled compress_pages_page_compression_error disabled -compress_pages_page_encrypted disabled -compress_pages_page_decrypted disabled -compress_pages_page_encryption_error disabled +compress_pages_encrypted disabled +compress_pages_decrypted disabled index_page_splits disabled index_page_merge_attempts disabled index_page_merge_successful disabled diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption-32k.test b/mysql-test/suite/innodb/t/innodb-page_encryption-32k.test index e96e352da12..325f0a86521 100644 --- a/mysql-test/suite/innodb/t/innodb-page_encryption-32k.test +++ b/mysql-test/suite/innodb/t/innodb-page_encryption-32k.test @@ -1,7 +1,9 @@ --source include/no_valgrind_without_big.inc +--source include/not_embedded.inc # Tests for setting innodb-page-size=32k; ---source include/have_xtradb.inc +--source include/have_innodb.inc --source include/have_innodb_32k.inc +--source include/have_file_key_management_plugin.inc call mtr.add_suppression("InnoDB: Warning: innodb_page_size has been changed from default value *"); @@ -15,9 +17,9 @@ SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=3; -create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_encryption=1 page_encryption_key=4; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; show create table innodb_compact; show create table innodb_dynamic; @@ -61,11 +63,11 @@ select count(*) from innodb_compact where c1 < 1500000; select count(*) from innodb_dynamic where c1 < 1500000; select count(*) from innodb_redundant where c1 < 1500000; -alter table innodb_compact engine=innodb page_encryption=0; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compact; -alter table innodb_dynamic engine=innodb page_encryption=0; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_dynamic; -alter table innodb_redundant engine=innodb page_encryption=0; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_redundant; --source include/restart_mysqld.inc diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption.test b/mysql-test/suite/innodb/t/innodb-page_encryption.test index 66927d1905f..2f9192a5dec 100644 --- a/mysql-test/suite/innodb/t/innodb-page_encryption.test +++ b/mysql-test/suite/innodb/t/innodb-page_encryption.test @@ -4,20 +4,21 @@ --disable_query_log let $innodb_file_format_orig = `SELECT @@innodb_file_format`; let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; -let $default_page_encryption_key = `SELECT @@innodb_default_page_encryption_key`; --enable_query_log SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1; -create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed page_encryption=1 page_encryption_key=2; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=3; -create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_encryption=1 page_encryption_key=4; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +--error ER_CANT_CREATE_TABLE +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; -SET GLOBAL innodb_default_page_encryption_key = 5; -create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb page_encryption=1; +set innodb_default_encryption_key_id = 5; +create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb encrypted=yes; show create table innodb_defkey; show create table innodb_compact; @@ -73,9 +74,8 @@ select count(*) from innodb_defkey t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; # Note there that these variables are updated only when real I/O is done, thus they are not reliable -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; --source include/restart_mysqld.inc @@ -104,17 +104,16 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_defkey t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compact; -alter table innodb_compressed engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compressed; -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_dynamic; -alter table innodb_redundant engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_redundant; --source include/restart_mysqld.inc @@ -147,9 +146,8 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; # After alter+restart these should be 0 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; drop procedure innodb_insert_proc; drop table innodb_normal; @@ -163,5 +161,4 @@ drop table innodb_defkey; --disable_query_log EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; -EVAL SET GLOBAL innodb_default_page_encryption_key = $default_page_encryption_key; --enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption_compression.test b/mysql-test/suite/innodb/t/innodb-page_encryption_compression.test index 6b9fb5bca9d..00304e5268a 100644 --- a/mysql-test/suite/innodb/t/innodb-page_encryption_compression.test +++ b/mysql-test/suite/innodb/t/innodb-page_encryption_compression.test @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +-- source include/not_embedded.inc -- source include/have_file_key_management_plugin.inc --disable_query_log @@ -13,8 +14,8 @@ SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1 page_compressed=1; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=2 page_compressed=1; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1 page_compressed=1; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=2 page_compressed=1; show warnings; show create table innodb_normal; @@ -53,11 +54,10 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; --source include/restart_mysqld.inc @@ -77,17 +77,16 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; alter table innodb_normal engine=innodb page_compressed=DEFAULT; show create table innodb_normal; -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT page_compressed=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; show create table innodb_compact; -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT page_compressed=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; show create table innodb_dynamic; --source include/restart_mysqld.inc @@ -110,11 +109,10 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_dynamic t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_compressed'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decompressed'; drop procedure innodb_insert_proc; drop table innodb_normal; diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.test b/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.test index abff5d93083..fec5f062a71 100644 --- a/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.test +++ b/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.test @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +-- source include/not_embedded.inc -- source include/have_file_key_management_plugin.inc --disable_query_log @@ -14,10 +15,10 @@ SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_encryption=1 page_encryption_key=1; -create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed page_encryption=1 page_encryption_key=2; -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_encryption=1 page_encryption_key=3; -create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant page_encryption=1 page_encryption_key=4; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; show create table innodb_compact; show create table innodb_compressed; @@ -66,9 +67,8 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; # Note there that these variables are updated only when real I/O is done, thus they are not reliable -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; --source include/restart_mysqld.inc @@ -93,17 +93,16 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; -alter table innodb_compact engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compact; -alter table innodb_compressed engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_compressed; -alter table innodb_dynamic engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_dynamic; -alter table innodb_redundant engine=innodb page_encryption=DEFAULT page_encryption_key=DEFAULT; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; show create table innodb_redundant; --source include/restart_mysqld.inc @@ -135,9 +134,8 @@ select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; # After alter+restart these should be 0 -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; drop procedure innodb_insert_proc; drop table innodb_normal; diff --git a/mysql-test/suite/innodb/t/innodb_encryption-page-compression.opt b/mysql-test/suite/innodb/t/innodb_encryption-page-compression.opt index f00ecb411d8..0b7319dcef5 100644 --- a/mysql-test/suite/innodb/t/innodb_encryption-page-compression.opt +++ b/mysql-test/suite/innodb/t/innodb_encryption-page-compression.opt @@ -1,6 +1,7 @@ --aria-encrypt-tables=ON --encrypt-tmp-disk-tables=ON --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-encryption-rotate-key-age=15 --innodb-encryption-threads=4 --innodb-tablespaces-encryption diff --git a/mysql-test/suite/innodb/t/innodb_encryption-page-compression.test b/mysql-test/suite/innodb/t/innodb_encryption-page-compression.test index 48a9a780e0d..34962167ef1 100644 --- a/mysql-test/suite/innodb/t/innodb_encryption-page-compression.test +++ b/mysql-test/suite/innodb/t/innodb_encryption-page-compression.test @@ -15,16 +15,6 @@ SET GLOBAL innodb_file_per_table = ON; # zlib set global innodb_compression_algorithm = 1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ ---error 1005 -create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ ---error 1005 -create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact page_compressed=1; ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ ---error 1005 -create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic page_compressed=1; - # reset system --disable_query_log EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; diff --git a/mysql-test/suite/innodb/t/innodb_encryption.opt b/mysql-test/suite/innodb/t/innodb_encryption.opt index f7f583d18ef..b2c709f04b2 100644 --- a/mysql-test/suite/innodb/t/innodb_encryption.opt +++ b/mysql-test/suite/innodb/t/innodb_encryption.opt @@ -1,6 +1,7 @@ --aria-encrypt-tables=ON --encrypt-tmp-disk-tables=ON --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-encryption-rotate-key-age=15 --innodb-encryption-threads=4 --innodb-tablespaces-encryption diff --git a/mysql-test/suite/innodb/t/innodb_encryption_debug.opt b/mysql-test/suite/innodb/t/innodb_encryption_debug.opt new file mode 100644 index 00000000000..722d4676594 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_debug.opt @@ -0,0 +1,6 @@ +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=2 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption +--plugin-load-add=$DEBUG_KEY_MANAGEMENT_SO diff --git a/mysql-test/suite/innodb/t/innodb_encryption_debug.test b/mysql-test/suite/innodb/t/innodb_encryption_debug.test new file mode 100644 index 00000000000..f733d6ec91c --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_debug.test @@ -0,0 +1,21 @@ +-- source include/have_innodb.inc +if (`select count(*) = 0 from information_schema.plugins + where plugin_name = 'debug_key_management' and plugin_status='active'`) +{ + --skip Needs debug_key_management +} + +show variables like 'innodb_encrypt%'; + +let $wait_condition= select count(*) = 3 from information_schema.innodb_tablespaces_encryption where current_key_version=1; +--source include/wait_condition.inc + +select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; +set global debug_key_management_version=10; + +let $wait_condition= select count(*) = 3 from information_schema.innodb_tablespaces_encryption where current_key_version=10; +--source include/wait_condition.inc + +select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; +set global debug_key_management_version=1; + diff --git a/mysql-test/suite/innodb/t/innodb_encryption_force.opt b/mysql-test/suite/innodb/t/innodb_encryption_force.opt new file mode 100644 index 00000000000..c9e532878e1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_force.opt @@ -0,0 +1,2 @@ +--innodb-encrypt-tables=FORCE +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/innodb/t/innodb_encryption_force.test b/mysql-test/suite/innodb/t/innodb_encryption_force.test new file mode 100644 index 00000000000..71ca23ff3cc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_force.test @@ -0,0 +1,31 @@ +-- source include/have_innodb.inc +-- source include/have_example_key_management_plugin.inc + +select @@innodb_encrypt_tables; + +create table t1 (a int) engine=innodb encrypted=yes; +create table t2 (a int) engine=innodb encrypted=default; +--error ER_CANT_CREATE_TABLE +create table t3 (a int) engine=innodb encrypted=no; + +set global innodb_encrypt_tables='ON'; +create table t3 (a int) engine=innodb encrypted=no; +set global innodb_encrypt_tables='FORCE'; + +show create table t1; +show create table t2; +show create table t3; + +--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ +--error ER_CANT_CREATE_TABLE +alter table t1 encrypted=no; +alter table t2 encrypted=yes; +alter table t3 encrypted=default; + +show create table t1; +show create table t2; +show create table t3; + +drop table t1; +drop table t2; +drop table t3; diff --git a/mysql-test/suite/innodb/t/innodb_encryption_tables.opt b/mysql-test/suite/innodb/t/innodb_encryption_tables.opt index f00ecb411d8..0b7319dcef5 100644 --- a/mysql-test/suite/innodb/t/innodb_encryption_tables.opt +++ b/mysql-test/suite/innodb/t/innodb_encryption_tables.opt @@ -1,6 +1,7 @@ --aria-encrypt-tables=ON --encrypt-tmp-disk-tables=ON --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-encryption-rotate-key-age=15 --innodb-encryption-threads=4 --innodb-tablespaces-encryption diff --git a/mysql-test/suite/innodb/t/innodb_encryption_tables.test b/mysql-test/suite/innodb/t/innodb_encryption_tables.test index d192a16ffd4..6d378270ad9 100644 --- a/mysql-test/suite/innodb/t/innodb_encryption_tables.test +++ b/mysql-test/suite/innodb/t/innodb_encryption_tables.test @@ -1,6 +1,6 @@ -- source include/have_innodb.inc -- source include/have_example_key_management_plugin.inc ---source include/not_embedded.inc +-- source include/not_embedded.inc --disable_query_log let $innodb_file_format_orig = `SELECT @@innodb_file_format`; @@ -66,9 +66,8 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; @@ -96,11 +95,10 @@ t1.c1 = t2.c1 and t1.b = t2.b; select count(*) from innodb_redundant t1, innodb_normal t2 where t1.c1 = t2.c1 and t1.b = t2.b; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encrypted'; -SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decrypted'; -SELECT variable_value = 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_encryption_error'; -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; -SELECT variable_value > 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_num_pages_page_decompressed'; drop procedure innodb_insert_proc; drop table innodb_normal; diff --git a/mysql-test/suite/innodb/t/innodb_scrub.opt b/mysql-test/suite/innodb/t/innodb_scrub.opt index fcbedad0df7..1bcc580b218 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub.opt +++ b/mysql-test/suite/innodb/t/innodb_scrub.opt @@ -2,12 +2,11 @@ --encrypt-tmp-disk-tables=ON --innodb-background-scrub-data-compressed=OFF --innodb-background-scrub-data-uncompressed=OFF ---innodb-encrypt-tables=0 --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-encryption-rotate-key-age=15 ---innodb-encryption-threads=0 --innodb-encryption-threads=4 --innodb-file-format=Barracuda --innodb-file-per-table=1 --innodb-immediate-scrub-data-uncompressed=ON ---loose-innodb-scrub-force-testing=ON +--loose-innodb-debug-force-scrubbing=ON diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test index 4b370b3e148..32170567b4c 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub.test +++ b/mysql-test/suite/innodb/t/innodb_scrub.test @@ -1,6 +1,7 @@ -- source include/have_innodb.inc -- source include/not_embedded.inc -- source include/have_example_key_management_plugin.inc +-- source include/not_windows.inc let $MYSQLD_DATADIR=`select @@datadir`; let ib1_IBD = $MYSQLD_DATADIR/ibdata1; diff --git a/mysql-test/suite/innodb/t/innodb_scrub_background.opt b/mysql-test/suite/innodb/t/innodb_scrub_background.opt index bb1f4ce4e86..fb9925cde0f 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub_background.opt +++ b/mysql-test/suite/innodb/t/innodb_scrub_background.opt @@ -1,14 +1,13 @@ --innodb-file-per-table=1 --innodb-file-format=Barracuda ---innodb-encrypt-tables=0 ---innodb-encryption-threads=0 --innodb-immediate-scrub-data-uncompressed=OFF --innodb-background-scrub-data-uncompressed=ON --innodb-background-scrub-data-compressed=ON ---loose-innodb-scrub-force-testing=ON +--loose-innodb-debug-force-scrubbing=ON --encrypt-tmp-disk-tables=ON --aria-encrypt-tables=ON --innodb-encryption-threads=4 --innodb-encryption-rotate-key-age=15 --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-tablespaces-scrubbing diff --git a/mysql-test/suite/innodb/t/innodb_scrub_background.test b/mysql-test/suite/innodb/t/innodb_scrub_background.test index 44cb16b1241..b5b7e3288d0 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub_background.test +++ b/mysql-test/suite/innodb/t/innodb_scrub_background.test @@ -1,6 +1,7 @@ -- source include/have_innodb.inc -- source include/not_embedded.inc -- source include/have_example_key_management_plugin.inc +-- source include/not_windows.inc let $MYSQLD_DATADIR=`select @@datadir`; let ib1_IBD = $MYSQLD_DATADIR/ibdata1; diff --git a/mysql-test/suite/innodb/t/innodb_scrub_compressed.opt b/mysql-test/suite/innodb/t/innodb_scrub_compressed.opt index ac7ef8a1675..69f0ade0278 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub_compressed.opt +++ b/mysql-test/suite/innodb/t/innodb_scrub_compressed.opt @@ -1,15 +1,13 @@ --innodb-file-per-table=1 --innodb-file-format=Barracuda ---innodb-encrypt-tables=off --innodb-immediate-scrub-data-uncompressed=ON --innodb-background-scrub-data-uncompressed=ON --innodb-background-scrub-data-compressed=ON ---loose-innodb-scrub-force-testing=ON ---innodb-encryption-threads=0 +--loose-innodb-debug-force-scrubbing=ON --encrypt-tmp-disk-tables=ON --aria-encrypt-tables=ON --innodb-encryption-threads=4 --innodb-encryption-rotate-key-age=15 --innodb-encrypt-tables=ON +--innodb-encrypt-log=ON --innodb-tablespaces-scrubbing - diff --git a/mysql-test/suite/innodb/t/innodb_scrub_compressed.test b/mysql-test/suite/innodb/t/innodb_scrub_compressed.test index c89c32a4de8..d41edac7494 100644 --- a/mysql-test/suite/innodb/t/innodb_scrub_compressed.test +++ b/mysql-test/suite/innodb/t/innodb_scrub_compressed.test @@ -1,6 +1,7 @@ -- source include/have_innodb.inc -- source include/not_embedded.inc -- source include/have_example_key_management_plugin.inc +-- source include/not_windows.inc let $MYSQLD_DATADIR=`select @@datadir`; let ib1_IBD = $MYSQLD_DATADIR/ibdata1; diff --git a/mysql-test/suite/plugins/r/filekeys_encfile.result b/mysql-test/suite/plugins/r/filekeys_encfile.result new file mode 100644 index 00000000000..add6f312fda --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_encfile.result @@ -0,0 +1,38 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=3; +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=33; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=33 +alter table t1 encryption_key_id=4; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=4 +drop table t1; diff --git a/mysql-test/suite/plugins/r/filekeys_encfile_bad.result b/mysql-test/suite/plugins/r/filekeys_encfile_bad.result new file mode 100644 index 00000000000..6261bd459b8 --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_encfile_bad.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*filekeys-data.enc. Wrong key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Cannot decrypt .*filekeys-data.enc. Wrong key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/filekeys_encfile_badfile.result b/mysql-test/suite/plugins/r/filekeys_encfile_badfile.result new file mode 100644 index 00000000000..98e2266f3f2 --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_encfile_badfile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("File 'bad' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /File 'bad' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/filekeys_encfile_file.result b/mysql-test/suite/plugins/r/filekeys_encfile_file.result new file mode 100644 index 00000000000..add6f312fda --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_encfile_file.result @@ -0,0 +1,38 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=3; +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=33; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=33 +alter table t1 encryption_key_id=4; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=4 +drop table t1; diff --git a/mysql-test/suite/plugins/r/filekeys_encfile_no.result b/mysql-test/suite/plugins/r/filekeys_encfile_no.result new file mode 100644 index 00000000000..6261bd459b8 --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_encfile_no.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*filekeys-data.enc. Wrong key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Cannot decrypt .*filekeys-data.enc. Wrong key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/filekeys_nofile.result b/mysql-test/suite/plugins/r/filekeys_nofile.result new file mode 100644 index 00000000000..558ea1ce88c --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_nofile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("File '' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /File '' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/filekeys_syntax.result b/mysql-test/suite/plugins/r/filekeys_syntax.result new file mode 100644 index 00000000000..a5606152d80 --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_syntax.result @@ -0,0 +1,129 @@ +call mtr.add_suppression("File '.*keys.txt' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /File '.*keys.txt' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key id at MYSQL_TMP_DIR/keys.txt line 2, column 2 +call mtr.add_suppression("File '.*keys.txt' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /File '.*keys.txt' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key id at MYSQL_TMP_DIR/keys.txt line 2, column 11 +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key at MYSQL_TMP_DIR/keys.txt line 2, column 47 +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key at MYSQL_TMP_DIR/keys.txt line 2, column 33 +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Syntax error at MYSQL_TMP_DIR/keys.txt line 2, column 2 +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Syntax error at MYSQL_TMP_DIR/keys.txt line 2, column 1 +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/filekeys_unencfile.result b/mysql-test/suite/plugins/r/filekeys_unencfile.result new file mode 100644 index 00000000000..1b9c092a713 --- /dev/null +++ b/mysql-test/suite/plugins/r/filekeys_unencfile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*keys.txt. Not encrypted"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND /Cannot decrypt .*keys.txt. Not encrypted/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/plugins/r/show_all_plugins.result b/mysql-test/suite/plugins/r/show_all_plugins.result index 5fe80e23af0..f07bafe3536 100644 --- a/mysql-test/suite/plugins/r/show_all_plugins.result +++ b/mysql-test/suite/plugins/r/show_all_plugins.result @@ -21,7 +21,7 @@ Name Status Type Library License EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL daemon_example NOT INSTALLED DAEMON libdaemon_example.so GPL -example_key_management_plugin NOT INSTALLED ENCRYPTION KEY MANAGEMENT example_key_management_plugin.so GPL +example_key_management NOT INSTALLED ENCRYPTION example_key_management.so GPL three_attempts NOT INSTALLED AUTHENTICATION dialog_examples.so GPL two_questions NOT INSTALLED AUTHENTICATION dialog_examples.so GPL show status like '%libraries%'; diff --git a/mysql-test/suite/plugins/t/filekeys-data.enc b/mysql-test/suite/plugins/t/filekeys-data.enc new file mode 100644 index 00000000000..a8adb2f939c Binary files /dev/null and b/mysql-test/suite/plugins/t/filekeys-data.enc differ diff --git a/mysql-test/suite/plugins/t/filekeys-data.key b/mysql-test/suite/plugins/t/filekeys-data.key new file mode 100644 index 00000000000..536aca34dba --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys-data.key @@ -0,0 +1 @@ +secret \ No newline at end of file diff --git a/mysql-test/suite/plugins/t/filekeys_badtest.inc b/mysql-test/suite/plugins/t/filekeys_badtest.inc new file mode 100644 index 00000000000..7c0858af20a --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_badtest.inc @@ -0,0 +1,18 @@ +-- source include/not_embedded.inc +-- source include/have_xtradb.inc +-- source filekeys_plugin.inc + +--eval call mtr.add_suppression("$SEARCH_PATTERN") +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); + +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_RANGE= -10000 +--source include/search_pattern_in_file.inc + +--error ER_CANT_CREATE_TABLE +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; + +select plugin_status from information_schema.plugins + where plugin_name = 'file_key_management'; + diff --git a/mysql-test/suite/plugins/t/filekeys_encfile.opt b/mysql-test/suite/plugins/t/filekeys_encfile.opt new file mode 100644 index 00000000000..651cc0f4cbe --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=secret +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/plugins/t/filekeys_encfile.test b/mysql-test/suite/plugins/t/filekeys_encfile.test new file mode 100644 index 00000000000..a0611a38ec4 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile.test @@ -0,0 +1 @@ +source filekeys_goodtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_bad.opt b/mysql-test/suite/plugins/t/filekeys_encfile_bad.opt new file mode 100644 index 00000000000..6ece8c6b08d --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_bad.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=bad +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_bad.test b/mysql-test/suite/plugins/t/filekeys_encfile_bad.test new file mode 100644 index 00000000000..51ab14c5608 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_bad.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*filekeys-data.enc. Wrong key; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_badfile.opt b/mysql-test/suite/plugins/t/filekeys_encfile_badfile.opt new file mode 100644 index 00000000000..374a41395b8 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_badfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=FILE:bad +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_badfile.test b/mysql-test/suite/plugins/t/filekeys_encfile_badfile.test new file mode 100644 index 00000000000..e0b07ac62b1 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_badfile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=File 'bad' not found; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_file.opt b/mysql-test/suite/plugins/t/filekeys_encfile_file.opt new file mode 100644 index 00000000000..df2d3d526d7 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_file.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_file.test b/mysql-test/suite/plugins/t/filekeys_encfile_file.test new file mode 100644 index 00000000000..a0611a38ec4 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_file.test @@ -0,0 +1 @@ +source filekeys_goodtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_no.opt b/mysql-test/suite/plugins/t/filekeys_encfile_no.opt new file mode 100644 index 00000000000..68264e5c261 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_no.opt @@ -0,0 +1 @@ +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/plugins/t/filekeys_encfile_no.test b/mysql-test/suite/plugins/t/filekeys_encfile_no.test new file mode 100644 index 00000000000..51ab14c5608 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_encfile_no.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*filekeys-data.enc. Wrong key; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_goodtest.inc b/mysql-test/suite/plugins/t/filekeys_goodtest.inc new file mode 100644 index 00000000000..146a570412c --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_goodtest.inc @@ -0,0 +1,20 @@ +-- source include/have_xtradb.inc +-- source filekeys_plugin.inc + +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +insert t1 values (12345, repeat('1234567890', 20)); + +alter table t1 encryption_key_id=2; +show create table t1; +--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ +--error ER_CANT_CREATE_TABLE +alter table t1 encryption_key_id=3; +show create table t1; +alter table t1 encryption_key_id=33; +show create table t1; +alter table t1 encryption_key_id=4; +show create table t1; + +drop table t1; + diff --git a/mysql-test/suite/plugins/t/filekeys_nofile.test b/mysql-test/suite/plugins/t/filekeys_nofile.test new file mode 100644 index 00000000000..c4505ebec81 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_nofile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=File '' not found; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_plugin.inc b/mysql-test/suite/plugins/t/filekeys_plugin.inc new file mode 100644 index 00000000000..8f0634a9076 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_plugin.inc @@ -0,0 +1,4 @@ +if (!$FILE_KEY_MANAGEMENT_SO) +{ + --skip Needs file_key_management +} diff --git a/mysql-test/suite/plugins/t/filekeys_plugin.opt b/mysql-test/suite/plugins/t/filekeys_plugin.opt new file mode 100644 index 00000000000..b42e6266e66 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_plugin.opt @@ -0,0 +1 @@ +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO diff --git a/mysql-test/suite/plugins/t/filekeys_syntax.opt b/mysql-test/suite/plugins/t/filekeys_syntax.opt new file mode 100644 index 00000000000..4be6601bbac --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_syntax.opt @@ -0,0 +1 @@ +--loose-file-key-management-filename=$MYSQL_TMP_DIR/keys.txt diff --git a/mysql-test/suite/plugins/t/filekeys_syntax.test b/mysql-test/suite/plugins/t/filekeys_syntax.test new file mode 100644 index 00000000000..e68e18bee1a --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_syntax.test @@ -0,0 +1,96 @@ +# +# first test - missing key file +# +let SEARCH_PATTERN=File '.*keys.txt' not found; +source filekeys_badtest.inc; + +# +# key id= 0 +# +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +0;00000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key id; +source filekeys_badtest.inc; + +# +# id too big +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +4294967299;00000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key id; +source filekeys_badtest.inc; +# +# wrong key length (not 16, 24, 23 bytes) +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3;00000000000000000000000000000000111122223333 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key; +source filekeys_badtest.inc; +# +# wrong key length (not an even number of digits) +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3;0000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key; +source filekeys_badtest.inc; +# +# no semicolon +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3:0000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Syntax error; +source filekeys_badtest.inc; +# +# another syntax error +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +syntax error +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Syntax error; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/filekeys_unencfile.opt b/mysql-test/suite/plugins/t/filekeys_unencfile.opt new file mode 100644 index 00000000000..b7e207c07d4 --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_unencfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=bad +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt diff --git a/mysql-test/suite/plugins/t/filekeys_unencfile.test b/mysql-test/suite/plugins/t/filekeys_unencfile.test new file mode 100644 index 00000000000..2567c29f5ec --- /dev/null +++ b/mysql-test/suite/plugins/t/filekeys_unencfile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*keys.txt. Not encrypted; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/plugins/t/show_all_plugins.test b/mysql-test/suite/plugins/t/show_all_plugins.test index 5d57def449b..103b6bead5a 100644 --- a/mysql-test/suite/plugins/t/show_all_plugins.test +++ b/mysql-test/suite/plugins/t/show_all_plugins.test @@ -2,7 +2,7 @@ if (!$DIALOG_EXAMPLES_SO) { skip requires dialog_examples.so; } if (!$HA_EXAMPLE_SO) { skip requires ha_examples.so; } if (!$LIBDAEMON_EXAMPLE_SO) { skip requires libdaemon_examples.so; } if (!$UDF_EXAMPLE_SO) { skip requires udf_example.so; } -if (!$EXAMPLE_KEY_MANAGEMENT_PLUGIN_SO) { skip requires example_key_management_plugin_so; } +if (!$EXAMPLE_KEY_MANAGEMENT_SO) { skip requires example_key_management.so; } flush status; show status like '%libraries%'; diff --git a/mysql-test/suite/rpl/r/rpl_checksum.result b/mysql-test/suite/rpl/r/rpl_checksum.result index 231afeec4b2..3f9c780ed67 100644 --- a/mysql-test/suite/rpl/r/rpl_checksum.result +++ b/mysql-test/suite/rpl/r/rpl_checksum.result @@ -143,6 +143,7 @@ SET debug_dbug= @old_dbug; INSERT INTO t4 VALUES (2); include/wait_for_slave_sql_error.inc [errno=1590] Last_SQL_Error = 'The incident LOST_EVENTS occured on the master. Message: error writing to the binary log' +FOUND /Slave SQL: The incident LOST_EVENTS occured on the master\. Message: error writing to the binary log, Internal MariaDB error code: 1590/ in mysqld.2.err SELECT * FROM t4 ORDER BY a; a 1 diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result index 204615201d9..ab615d0510a 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result @@ -38,5 +38,7 @@ a 3 4 5 +FOUND /Slave SQL: Error 'Duplicate entry .* on query\. .*Query: '.*', Gtid 0-1-100, Internal MariaDB error code:|Slave SQL: Could not execute Write_rows.*table test.t1; Duplicate entry.*, Gtid 0-1-100, Internal MariaDB error/ in mysqld.2.err +FOUND /Slave SQL: The incident LOST_EVENTS occured on the master\. Message: , Internal MariaDB error code: 1590/ in mysqld.2.err DROP TABLE t1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_table_options.result b/mysql-test/suite/rpl/r/rpl_table_options.result index a94d6e9bc2f..a417aaf720d 100644 --- a/mysql-test/suite/rpl/r/rpl_table_options.result +++ b/mysql-test/suite/rpl/r/rpl_table_options.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 840da8405c3..5bd55dc8133 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,6 +10,7 @@ there should be *no* long test name listed below: select distinct variable_name as `there should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; there should be *no* variables listed below: +innodb_default_encryption_key_id strict_password_validation drop table t1; drop table t2; diff --git a/mysql-test/suite/sys_vars/r/debug_use_static_encryption_keys_basic.result b/mysql-test/suite/sys_vars/r/debug_use_static_encryption_keys_basic.result deleted file mode 100644 index a0d4f45cdbf..00000000000 --- a/mysql-test/suite/sys_vars/r/debug_use_static_encryption_keys_basic.result +++ /dev/null @@ -1,3 +0,0 @@ -show global variables like "debug_use_static_encryption_keys"; -Variable_name Value -debug_use_static_encryption_keys OFF diff --git a/mysql-test/suite/sys_vars/r/encryption_algorithm_basic.result b/mysql-test/suite/sys_vars/r/encryption_algorithm_basic.result deleted file mode 100644 index a9101b0f950..00000000000 --- a/mysql-test/suite/sys_vars/r/encryption_algorithm_basic.result +++ /dev/null @@ -1,7 +0,0 @@ -select @@global.encryption_algorithm; -@@global.encryption_algorithm -none -select @@session.encryption_algorithm; -ERROR HY000: Variable 'encryption_algorithm' is a GLOBAL variable -set global encryption_algorithm="none"; -ERROR HY000: Variable 'encryption_algorithm' is a read only variable diff --git a/mysql-test/suite/sys_vars/r/innodb_debug_force_scrubbing_basic.result b/mysql-test/suite/sys_vars/r/innodb_debug_force_scrubbing_basic.result new file mode 100644 index 00000000000..eced486ad70 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_debug_force_scrubbing_basic.result @@ -0,0 +1,50 @@ +SET @start_global_value = @@global.innodb_debug_force_scrubbing; +# +# exists as global only +# +select @@global.innodb_debug_force_scrubbing; +@@global.innodb_debug_force_scrubbing +0 +select @@session.innodb_debug_force_scrubbing; +ERROR HY000: Variable 'innodb_debug_force_scrubbing' is a GLOBAL variable +show global variables like 'innodb_debug_force_scrubbing'; +Variable_name Value +innodb_debug_force_scrubbing OFF +show session variables like 'innodb_debug_force_scrubbing'; +Variable_name Value +innodb_debug_force_scrubbing OFF +select * from information_schema.global_variables +where variable_name='innodb_debug_force_scrubbing'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_DEBUG_FORCE_SCRUBBING OFF +select * from information_schema.session_variables +where variable_name='innodb_debug_force_scrubbing'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_DEBUG_FORCE_SCRUBBING OFF +# +# show that it's writable +# +set global innodb_debug_force_scrubbing=ON; +select @@global.innodb_debug_force_scrubbing; +@@global.innodb_debug_force_scrubbing +1 +set global innodb_debug_force_scrubbing=OFF; +select @@global.innodb_debug_force_scrubbing; +@@global.innodb_debug_force_scrubbing +0 +set global innodb_debug_force_scrubbing=1; +select @@global.innodb_debug_force_scrubbing; +@@global.innodb_debug_force_scrubbing +1 +set session innodb_debug_force_scrubbing=1; +ERROR HY000: Variable 'innodb_debug_force_scrubbing' is a GLOBAL variable and should be set with SET GLOBAL +# +# incorrect types +# +set global innodb_debug_force_scrubbing=1.1; +ERROR 42000: Incorrect argument type to variable 'innodb_debug_force_scrubbing' +set global innodb_debug_force_scrubbing=1e1; +ERROR 42000: Incorrect argument type to variable 'innodb_debug_force_scrubbing' +set global innodb_debug_force_scrubbing="foo"; +ERROR 42000: Variable 'innodb_debug_force_scrubbing' can't be set to the value of 'foo' +SET @@global.innodb_debug_force_scrubbing = @start_global_value; diff --git a/mysql-test/suite/sys_vars/r/innodb_default_page_encryption_key_basic.result b/mysql-test/suite/sys_vars/r/innodb_default_page_encryption_key_basic.result deleted file mode 100644 index 1e779d7c4f6..00000000000 --- a/mysql-test/suite/sys_vars/r/innodb_default_page_encryption_key_basic.result +++ /dev/null @@ -1,71 +0,0 @@ -SET @start_global_value = @@global.innodb_default_page_encryption_key; -SELECT @start_global_value; -@start_global_value -1 -Valid value 0-9 -select @@global.innodb_default_page_encryption_key <= 9; -@@global.innodb_default_page_encryption_key <= 9 -1 -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -1 -select @@session.innodb_default_page_encryption_key; -ERROR HY000: Variable 'innodb_default_page_encryption_key' is a GLOBAL variable -show global variables like 'innodb_default_page_encryption_key'; -Variable_name Value -innodb_default_page_encryption_key 1 -show session variables like 'innodb_default_page_encryption_key'; -Variable_name Value -innodb_default_page_encryption_key 1 -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 1 -select * from information_schema.session_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 1 -set global innodb_default_page_encryption_key=2; -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -2 -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 2 -select * from information_schema.session_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 2 -set session innodb_default_page_encryption_key=4; -ERROR HY000: Variable 'innodb_default_page_encryption_key' is a GLOBAL variable and should be set with SET GLOBAL -set global innodb_default_page_encryption_key=1.1; -ERROR 42000: Incorrect argument type to variable 'innodb_default_page_encryption_key' -set global innodb_default_page_encryption_key=1e1; -ERROR 42000: Incorrect argument type to variable 'innodb_default_page_encryption_key' -set global innodb_default_page_encryption_key="foo"; -ERROR 42000: Incorrect argument type to variable 'innodb_default_page_encryption_key' -set global innodb_default_page_encryption_key=10; -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -10 -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 10 -set global innodb_default_page_encryption_key=-7; -Warnings: -Warning 1292 Truncated incorrect innodb_default_page_encryption_k value: '-7' -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -1 -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_DEFAULT_PAGE_ENCRYPTION_KEY 1 -set global innodb_default_page_encryption_key=1; -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -1 -set global innodb_default_page_encryption_key=255; -select @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -255 -SET @@global.innodb_default_page_encryption_key = @start_global_value; -SELECT @@global.innodb_default_page_encryption_key; -@@global.innodb_default_page_encryption_key -1 diff --git a/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result b/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result index 87212399f09..bcca96b8cd7 100644 --- a/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result @@ -1,7 +1,7 @@ SET @start_global_value = @@global.innodb_encrypt_tables; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -0 +OFF select @@session.innodb_encrypt_tables; ERROR HY000: Variable 'innodb_encrypt_tables' is a GLOBAL variable show global variables like 'innodb_encrypt_tables'; @@ -21,15 +21,15 @@ INNODB_ENCRYPT_TABLES OFF set global innodb_encrypt_tables=ON; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -1 +ON set global innodb_encrypt_tables=OFF; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -0 +OFF set global innodb_encrypt_tables=1; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -1 +ON set session innodb_encrypt_tables=1; ERROR HY000: Variable 'innodb_encrypt_tables' is a GLOBAL variable and should be set with SET GLOBAL set global innodb_encrypt_tables=1.1; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result index 85fe22dd816..d992695a7fe 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result @@ -180,9 +180,8 @@ compress_page_compressed_trim_op disabled compress_page_compressed_trim_op_saved disabled compress_pages_page_decompressed disabled compress_pages_page_compression_error disabled -compress_pages_page_encrypted disabled -compress_pages_page_decrypted disabled -compress_pages_page_encryption_error disabled +compress_pages_encrypted disabled +compress_pages_decrypted disabled index_page_splits disabled index_page_merge_attempts disabled index_page_merge_successful disabled diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result index 85fe22dd816..d992695a7fe 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result @@ -180,9 +180,8 @@ compress_page_compressed_trim_op disabled compress_page_compressed_trim_op_saved disabled compress_pages_page_decompressed disabled compress_pages_page_compression_error disabled -compress_pages_page_encrypted disabled -compress_pages_page_decrypted disabled -compress_pages_page_encryption_error disabled +compress_pages_encrypted disabled +compress_pages_decrypted disabled index_page_splits disabled index_page_merge_attempts disabled index_page_merge_successful disabled diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result index 85fe22dd816..d992695a7fe 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result @@ -180,9 +180,8 @@ compress_page_compressed_trim_op disabled compress_page_compressed_trim_op_saved disabled compress_pages_page_decompressed disabled compress_pages_page_compression_error disabled -compress_pages_page_encrypted disabled -compress_pages_page_decrypted disabled -compress_pages_page_encryption_error disabled +compress_pages_encrypted disabled +compress_pages_decrypted disabled index_page_splits disabled index_page_merge_attempts disabled index_page_merge_successful disabled diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result index 85fe22dd816..d992695a7fe 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result @@ -180,9 +180,8 @@ compress_page_compressed_trim_op disabled compress_page_compressed_trim_op_saved disabled compress_pages_page_decompressed disabled compress_pages_page_compression_error disabled -compress_pages_page_encrypted disabled -compress_pages_page_decrypted disabled -compress_pages_page_encryption_error disabled +compress_pages_encrypted disabled +compress_pages_decrypted disabled index_page_splits disabled index_page_merge_attempts disabled index_page_merge_successful disabled diff --git a/mysql-test/suite/sys_vars/r/innodb_scrub_force_testing_basic.result b/mysql-test/suite/sys_vars/r/innodb_scrub_force_testing_basic.result deleted file mode 100644 index 24287efaffc..00000000000 --- a/mysql-test/suite/sys_vars/r/innodb_scrub_force_testing_basic.result +++ /dev/null @@ -1,50 +0,0 @@ -SET @start_global_value = @@global.innodb_scrub_force_testing; -# -# exists as global only -# -select @@global.innodb_scrub_force_testing; -@@global.innodb_scrub_force_testing -0 -select @@session.innodb_scrub_force_testing; -ERROR HY000: Variable 'innodb_scrub_force_testing' is a GLOBAL variable -show global variables like 'innodb_scrub_force_testing'; -Variable_name Value -innodb_scrub_force_testing OFF -show session variables like 'innodb_scrub_force_testing'; -Variable_name Value -innodb_scrub_force_testing OFF -select * from information_schema.global_variables -where variable_name='innodb_scrub_force_testing'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SCRUB_FORCE_TESTING OFF -select * from information_schema.session_variables -where variable_name='innodb_scrub_force_testing'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SCRUB_FORCE_TESTING OFF -# -# show that it's writable -# -set global innodb_scrub_force_testing=ON; -select @@global.innodb_scrub_force_testing; -@@global.innodb_scrub_force_testing -1 -set global innodb_scrub_force_testing=OFF; -select @@global.innodb_scrub_force_testing; -@@global.innodb_scrub_force_testing -0 -set global innodb_scrub_force_testing=1; -select @@global.innodb_scrub_force_testing; -@@global.innodb_scrub_force_testing -1 -set session innodb_scrub_force_testing=1; -ERROR HY000: Variable 'innodb_scrub_force_testing' is a GLOBAL variable and should be set with SET GLOBAL -# -# incorrect types -# -set global innodb_scrub_force_testing=1.1; -ERROR 42000: Incorrect argument type to variable 'innodb_scrub_force_testing' -set global innodb_scrub_force_testing=1e1; -ERROR 42000: Incorrect argument type to variable 'innodb_scrub_force_testing' -set global innodb_scrub_force_testing="foo"; -ERROR 42000: Variable 'innodb_scrub_force_testing' can't be set to the value of 'foo' -SET @@global.innodb_scrub_force_testing = @start_global_value; diff --git a/mysql-test/suite/sys_vars/r/innodb_scrub_log_interval_basic.result b/mysql-test/suite/sys_vars/r/innodb_scrub_log_interval_basic.result deleted file mode 100644 index 0d7bc7e61c6..00000000000 --- a/mysql-test/suite/sys_vars/r/innodb_scrub_log_interval_basic.result +++ /dev/null @@ -1,53 +0,0 @@ -SELECT @@GLOBAL.innodb_scrub_log_interval; -@@GLOBAL.innodb_scrub_log_interval -2000 -200 Expected -SET @@GLOBAL.innodb_scrub_log_interval=100; -1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; -@@GLOBAL.innodb_scrub_log_interval -100 -100 Expected -SET @@GLOBAL.innodb_scrub_log_interval=DEFAULT; -1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; -@@GLOBAL.innodb_scrub_log_interval -2000 -200 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_scrub_log_interval'; -@@GLOBAL.innodb_scrub_log_interval = VARIABLE_VALUE -1 -1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; -@@GLOBAL.innodb_scrub_log_interval -2000 -200 Expected -SELECT VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_scrub_log_interval'; -VARIABLE_VALUE -2000 -200 Expected -SELECT @@innodb_scrub_log_interval = @@GLOBAL.innodb_scrub_log_interval; -@@innodb_scrub_log_interval = @@GLOBAL.innodb_scrub_log_interval -1 -1 Expected -SELECT @@innodb_scrub_log_interval; -@@innodb_scrub_log_interval -2000 -200 Expected -SELECT @@local.innodb_scrub_log_interval; -ERROR HY000: Variable 'innodb_scrub_log_interval' is a GLOBAL variable -Expected error 'Variable is a GLOBAL variable' -SELECT @@SESSION.innodb_scrub_log_interval; -ERROR HY000: Variable 'innodb_scrub_log_interval' is a GLOBAL variable -Expected error 'Variable is a GLOBAL variable' -SELECT @@GLOBAL.innodb_scrub_log_interval; -@@GLOBAL.innodb_scrub_log_interval -2000 -200 Expected -SELECT innodb_scrub_log_interval; -ERROR 42S22: Unknown column 'innodb_scrub_log_interval' in 'field list' -Expected error 'Unknow column in field list' diff --git a/mysql-test/suite/sys_vars/r/innodb_scrub_log_speed_basic.result b/mysql-test/suite/sys_vars/r/innodb_scrub_log_speed_basic.result new file mode 100644 index 00000000000..e51dab0718a --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_scrub_log_speed_basic.result @@ -0,0 +1,53 @@ +SELECT @@GLOBAL.innodb_scrub_log_speed; +@@GLOBAL.innodb_scrub_log_speed +256 +200 Expected +SET @@GLOBAL.innodb_scrub_log_speed=100; +1 Expected +SELECT @@GLOBAL.innodb_scrub_log_speed; +@@GLOBAL.innodb_scrub_log_speed +100 +100 Expected +SET @@GLOBAL.innodb_scrub_log_speed=DEFAULT; +1 Expected +SELECT @@GLOBAL.innodb_scrub_log_speed; +@@GLOBAL.innodb_scrub_log_speed +256 +200 Expected +SELECT @@GLOBAL.innodb_scrub_log_speed = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_scrub_log_speed'; +@@GLOBAL.innodb_scrub_log_speed = VARIABLE_VALUE +1 +1 Expected +SELECT @@GLOBAL.innodb_scrub_log_speed; +@@GLOBAL.innodb_scrub_log_speed +256 +200 Expected +SELECT VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_scrub_log_speed'; +VARIABLE_VALUE +256 +200 Expected +SELECT @@innodb_scrub_log_speed = @@GLOBAL.innodb_scrub_log_speed; +@@innodb_scrub_log_speed = @@GLOBAL.innodb_scrub_log_speed +1 +1 Expected +SELECT @@innodb_scrub_log_speed; +@@innodb_scrub_log_speed +256 +200 Expected +SELECT @@local.innodb_scrub_log_speed; +ERROR HY000: Variable 'innodb_scrub_log_speed' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT @@SESSION.innodb_scrub_log_speed; +ERROR HY000: Variable 'innodb_scrub_log_speed' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT @@GLOBAL.innodb_scrub_log_speed; +@@GLOBAL.innodb_scrub_log_speed +256 +200 Expected +SELECT innodb_scrub_log_speed; +ERROR 42S22: Unknown column 'innodb_scrub_log_speed' in 'field list' +Expected error 'Unknow column in field list' diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug.result b/mysql-test/suite/sys_vars/r/sysvars_debug.result index b7f169dc22e..a46e135af0a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_debug.result +++ b/mysql-test/suite/sys_vars/r/sysvars_debug.result @@ -57,20 +57,6 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL -VARIABLE_NAME DEBUG_ENCRYPTION_KEY_VERSION -SESSION_VALUE NULL -GLOBAL_VALUE 0 -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 0 -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE INT UNSIGNED -VARIABLE_COMMENT Encryption key version. Only to be used in internal testing. -NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 4294967295 -NUMERIC_BLOCK_SIZE 1 -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME DEBUG_MUTEX_DEADLOCK_DETECTOR SESSION_VALUE NULL GLOBAL_VALUE ON @@ -113,17 +99,3 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT NULL -VARIABLE_NAME DEBUG_USE_STATIC_ENCRYPTION_KEYS -SESSION_VALUE NULL -GLOBAL_VALUE OFF -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE OFF -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable use of nonrandom encryption keys. Only to be used in internal testing -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST OFF,ON -READ_ONLY YES -COMMAND_LINE_ARGUMENT OPTIONAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff index 2ce01384d0f..a5b8fc1a205 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff @@ -177,7 +177,7 @@ VARIABLE_NAME INNODB_DATA_FILE_PATH SESSION_VALUE NULL GLOBAL_VALUE ibdata1:12M:autoextend -@@ -719,6 +859,20 @@ +@@ -733,6 +873,20 @@ ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT OPTIONAL @@ -198,10 +198,10 @@ VARIABLE_NAME INNODB_ENCRYPTION_ROTATE_KEY_AGE SESSION_VALUE NULL GLOBAL_VALUE 1 -@@ -789,6 +943,20 @@ - ENUM_VALUE_LIST NULL +@@ -803,6 +957,20 @@ + ENUM_VALUE_LIST OFF,ON,FORCE READ_ONLY NO - COMMAND_LINE_ARGUMENT REQUIRED + COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_FAKE_CHANGES +SESSION_VALUE OFF +GLOBAL_VALUE OFF @@ -219,7 +219,7 @@ VARIABLE_NAME INNODB_FAST_SHUTDOWN SESSION_VALUE NULL GLOBAL_VALUE 1 -@@ -916,11 +1084,11 @@ +@@ -930,11 +1098,11 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_FLUSH_LOG_AT_TRX_COMMIT @@ -233,7 +233,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Controls the durability/speed trade-off for commits. Set to 0 (write and flush redo log to disk only once per second), 1 (flush to disk at each commit), 2 (write to log at commit but flush to disk only once per second) or 3 (flush to disk at prepare and at commit, slower and usually redundant). 1 and 3 guarantees that after a crash, committed transactions will not be lost and will be consistent with the binlog and other transactional engines. 2 can get inconsistent and lose transactions if there is a power failure or kernel crash but not if mysqld crashes. 0 has no guarantees in case of crash. 0 and 2 can be faster than 1 or 3. NUMERIC_MIN_VALUE 0 -@@ -1013,6 +1181,20 @@ +@@ -1027,6 +1195,20 @@ ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED @@ -254,7 +254,7 @@ VARIABLE_NAME INNODB_FT_AUX_TABLE SESSION_VALUE NULL GLOBAL_VALUE -@@ -1251,6 +1433,20 @@ +@@ -1265,6 +1447,20 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -275,7 +275,7 @@ VARIABLE_NAME INNODB_LARGE_PREFIX SESSION_VALUE NULL GLOBAL_VALUE OFF -@@ -1279,6 +1475,20 @@ +@@ -1293,6 +1489,20 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -296,7 +296,7 @@ VARIABLE_NAME INNODB_LOCKS_UNSAFE_FOR_BINLOG SESSION_VALUE NULL GLOBAL_VALUE OFF -@@ -1307,6 +1517,62 @@ +@@ -1321,6 +1531,62 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -359,7 +359,7 @@ VARIABLE_NAME INNODB_LOG_BUFFER_SIZE SESSION_VALUE NULL GLOBAL_VALUE 1048576 -@@ -1335,6 +1601,20 @@ +@@ -1349,6 +1615,20 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL @@ -380,7 +380,7 @@ VARIABLE_NAME INNODB_LOG_COMPRESSED_PAGES SESSION_VALUE NULL GLOBAL_VALUE OFF -@@ -1405,6 +1685,34 @@ +@@ -1419,6 +1699,34 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -415,7 +415,7 @@ VARIABLE_NAME INNODB_MAX_DIRTY_PAGES_PCT SESSION_VALUE NULL GLOBAL_VALUE 75.000000 -@@ -1671,6 +1979,62 @@ +@@ -1685,6 +1993,62 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL @@ -478,7 +478,7 @@ VARIABLE_NAME INNODB_PURGE_BATCH_SIZE SESSION_VALUE NULL GLOBAL_VALUE 300 -@@ -1839,6 +2203,48 @@ +@@ -1853,6 +2217,48 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL @@ -524,7 +524,7 @@ +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED - VARIABLE_NAME INNODB_SCRUB_FORCE_TESTING + VARIABLE_NAME INNODB_SCRUB_LOG SESSION_VALUE NULL GLOBAL_VALUE OFF @@ -1881,6 +2287,34 @@ diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 867fe02d454..15d0209e2dc 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -565,16 +565,30 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME INNODB_DEFAULT_PAGE_ENCRYPTION_KEY +VARIABLE_NAME INNODB_DEBUG_FORCE_SCRUBBING SESSION_VALUE NULL +GLOBAL_VALUE OFF +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE OFF +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Perform extra scrubbing to increase test exposure +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME INNODB_DEFAULT_ENCRYPTION_KEY_ID +SESSION_VALUE 1 GLOBAL_VALUE 1 GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 -VARIABLE_SCOPE GLOBAL +VARIABLE_SCOPE SESSION VARIABLE_TYPE INT UNSIGNED -VARIABLE_COMMENT Encryption key used for page encryption. +VARIABLE_COMMENT Default encryption key id used for table encryption. NUMERIC_MIN_VALUE 1 -NUMERIC_MAX_VALUE 255 +NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO @@ -726,7 +740,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE INT UNSIGNED -VARIABLE_COMMENT Rotate any page having a key older than this +VARIABLE_COMMENT Key rotation - re-encrypt in background all pages that were encrypted with a key that many (or more) versions behind NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 0 @@ -754,7 +768,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE INT UNSIGNED -VARIABLE_COMMENT No of threads performing background key rotation and scrubbing +VARIABLE_COMMENT Number of threads performing background key rotation and scrubbing NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 0 @@ -768,7 +782,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE OFF VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable redo log encryption/decryption. +VARIABLE_COMMENT Enable redo log encryption NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL @@ -781,14 +795,14 @@ GLOBAL_VALUE OFF GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE OFF VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Encrypt all tables in the storage engine +VARIABLE_TYPE ENUM +VARIABLE_COMMENT Enable encryption for tables. Don't forget to enable --innodb-encrypt-log too NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL +ENUM_VALUE_LIST OFF,ON,FORCE READ_ONLY NO -COMMAND_LINE_ARGUMENT REQUIRED +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_FAST_SHUTDOWN SESSION_VALUE NULL GLOBAL_VALUE 1 @@ -1839,20 +1853,6 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL -VARIABLE_NAME INNODB_SCRUB_FORCE_TESTING -SESSION_VALUE NULL -GLOBAL_VALUE OFF -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE OFF -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Perform extra scrubbing to increase test exposure -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME INNODB_SCRUB_LOG SESSION_VALUE NULL GLOBAL_VALUE OFF @@ -1860,23 +1860,23 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE OFF VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable redo log scrubbing +VARIABLE_COMMENT Enable background redo log (ib_logfile0, ib_logfile1...) scrubbing NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT OPTIONAL -VARIABLE_NAME INNODB_SCRUB_LOG_INTERVAL +VARIABLE_NAME INNODB_SCRUB_LOG_SPEED SESSION_VALUE NULL -GLOBAL_VALUE 2000 +GLOBAL_VALUE 256 GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 2000 +DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Innodb redo log scrubbing interval in ms -NUMERIC_MIN_VALUE 10 -NUMERIC_MAX_VALUE 18446744073709551615 +VARIABLE_COMMENT Background redo log scrubbing speed in bytes/sec +NUMERIC_MIN_VALUE 1 +NUMERIC_MAX_VALUE 50000 NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index e72678c5243..21d4ea85dd9 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -681,20 +681,6 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME ENCRYPTION_ALGORITHM -SESSION_VALUE NULL -GLOBAL_VALUE none -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE none -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE ENUM -VARIABLE_COMMENT Which encryption algorithm to use for table encryption. aes_cbc is the recommended one. -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST none,aes_ecb,aes_cbc,aes_ctr -READ_ONLY YES -COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ENCRYPT_TMP_DISK_TABLES SESSION_VALUE NULL GLOBAL_VALUE OFF diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 7908300bf8f..ea4019e65cc 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -695,20 +695,6 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME ENCRYPTION_ALGORITHM -SESSION_VALUE NULL -GLOBAL_VALUE none -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE none -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE ENUM -VARIABLE_COMMENT Which encryption algorithm to use for table encryption. aes_cbc is the recommended one. -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST none,aes_ecb,aes_cbc,aes_ctr -READ_ONLY YES -COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ENCRYPT_TMP_DISK_TABLES SESSION_VALUE NULL GLOBAL_VALUE OFF diff --git a/mysql-test/suite/sys_vars/t/debug_encryption_key_version_basic.test b/mysql-test/suite/sys_vars/t/debug_encryption_key_version_basic.test deleted file mode 100644 index 007724b0966..00000000000 --- a/mysql-test/suite/sys_vars/t/debug_encryption_key_version_basic.test +++ /dev/null @@ -1,3 +0,0 @@ ---source include/have_debug.inc -# This is just to satisfy all_vars -select 1; diff --git a/mysql-test/suite/sys_vars/t/debug_use_static_encryption_keys_basic.test b/mysql-test/suite/sys_vars/t/debug_use_static_encryption_keys_basic.test deleted file mode 100644 index 2e0d51e89b7..00000000000 --- a/mysql-test/suite/sys_vars/t/debug_use_static_encryption_keys_basic.test +++ /dev/null @@ -1,3 +0,0 @@ -# This is just to satisfy all_vars ---source include/have_debug.inc -show global variables like "debug_use_static_encryption_keys"; diff --git a/mysql-test/suite/sys_vars/t/encryption_algorithm_basic.test b/mysql-test/suite/sys_vars/t/encryption_algorithm_basic.test deleted file mode 100644 index 065453eba34..00000000000 --- a/mysql-test/suite/sys_vars/t/encryption_algorithm_basic.test +++ /dev/null @@ -1,13 +0,0 @@ -# bool global - -# exists as global only -# -select @@global.encryption_algorithm; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.encryption_algorithm; - -# -# show that it's not writable -# ---error 1238 -set global encryption_algorithm="none"; diff --git a/mysql-test/suite/sys_vars/t/innodb_debug_force_scrubbing_basic.test b/mysql-test/suite/sys_vars/t/innodb_debug_force_scrubbing_basic.test new file mode 100644 index 00000000000..cc00f0f6f3d --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_debug_force_scrubbing_basic.test @@ -0,0 +1,42 @@ +# bool global +--source include/have_innodb.inc +--source include/have_debug.inc + +SET @start_global_value = @@global.innodb_debug_force_scrubbing; + +--echo # +--echo # exists as global only +--echo # +select @@global.innodb_debug_force_scrubbing; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.innodb_debug_force_scrubbing; +show global variables like 'innodb_debug_force_scrubbing'; +show session variables like 'innodb_debug_force_scrubbing'; +select * from information_schema.global_variables +where variable_name='innodb_debug_force_scrubbing'; +select * from information_schema.session_variables +where variable_name='innodb_debug_force_scrubbing'; + +--echo # +--echo # show that it's writable +--echo # +set global innodb_debug_force_scrubbing=ON; +select @@global.innodb_debug_force_scrubbing; +set global innodb_debug_force_scrubbing=OFF; +select @@global.innodb_debug_force_scrubbing; +set global innodb_debug_force_scrubbing=1; +select @@global.innodb_debug_force_scrubbing; +--error ER_GLOBAL_VARIABLE +set session innodb_debug_force_scrubbing=1; + +--echo # +--echo # incorrect types +--echo # +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_debug_force_scrubbing=1.1; +--error ER_WRONG_TYPE_FOR_VAR +set global innodb_debug_force_scrubbing=1e1; +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_debug_force_scrubbing="foo"; + +SET @@global.innodb_debug_force_scrubbing = @start_global_value; diff --git a/mysql-test/suite/sys_vars/t/innodb_default_page_encryption_key_basic.test b/mysql-test/suite/sys_vars/t/innodb_default_page_encryption_key_basic.test deleted file mode 100644 index c8a02cb8c74..00000000000 --- a/mysql-test/suite/sys_vars/t/innodb_default_page_encryption_key_basic.test +++ /dev/null @@ -1,60 +0,0 @@ - ---source include/have_innodb.inc - -SET @start_global_value = @@global.innodb_default_page_encryption_key; -SELECT @start_global_value; - -# -# exists as global only -# ---echo Valid value 0-9 -select @@global.innodb_default_page_encryption_key <= 9; -select @@global.innodb_default_page_encryption_key; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.innodb_default_page_encryption_key; -show global variables like 'innodb_default_page_encryption_key'; -show session variables like 'innodb_default_page_encryption_key'; -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -select * from information_schema.session_variables where variable_name='innodb_default_page_encryption_key'; - -# -# show that it's writable -# -set global innodb_default_page_encryption_key=2; -select @@global.innodb_default_page_encryption_key; -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -select * from information_schema.session_variables where variable_name='innodb_default_page_encryption_key'; ---error ER_GLOBAL_VARIABLE -set session innodb_default_page_encryption_key=4; - -# -# incorrect types -# ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_default_page_encryption_key=1.1; ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_default_page_encryption_key=1e1; ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_default_page_encryption_key="foo"; - -set global innodb_default_page_encryption_key=10; -select @@global.innodb_default_page_encryption_key; -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; -set global innodb_default_page_encryption_key=-7; -select @@global.innodb_default_page_encryption_key; -select * from information_schema.global_variables where variable_name='innodb_default_page_encryption_key'; - -# -# min/max values -# -set global innodb_default_page_encryption_key=1; -select @@global.innodb_default_page_encryption_key; -set global innodb_default_page_encryption_key=255; -select @@global.innodb_default_page_encryption_key; - -# -# cleanup -# - -SET @@global.innodb_default_page_encryption_key = @start_global_value; -SELECT @@global.innodb_default_page_encryption_key; diff --git a/mysql-test/suite/sys_vars/t/innodb_scrub_force_testing_basic.test b/mysql-test/suite/sys_vars/t/innodb_scrub_force_testing_basic.test deleted file mode 100644 index e2df0de4e28..00000000000 --- a/mysql-test/suite/sys_vars/t/innodb_scrub_force_testing_basic.test +++ /dev/null @@ -1,42 +0,0 @@ -# bool global ---source include/have_innodb.inc ---source include/have_debug.inc - -SET @start_global_value = @@global.innodb_scrub_force_testing; - ---echo # ---echo # exists as global only ---echo # -select @@global.innodb_scrub_force_testing; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.innodb_scrub_force_testing; -show global variables like 'innodb_scrub_force_testing'; -show session variables like 'innodb_scrub_force_testing'; -select * from information_schema.global_variables -where variable_name='innodb_scrub_force_testing'; -select * from information_schema.session_variables -where variable_name='innodb_scrub_force_testing'; - ---echo # ---echo # show that it's writable ---echo # -set global innodb_scrub_force_testing=ON; -select @@global.innodb_scrub_force_testing; -set global innodb_scrub_force_testing=OFF; -select @@global.innodb_scrub_force_testing; -set global innodb_scrub_force_testing=1; -select @@global.innodb_scrub_force_testing; ---error ER_GLOBAL_VARIABLE -set session innodb_scrub_force_testing=1; - ---echo # ---echo # incorrect types ---echo # ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_scrub_force_testing=1.1; ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_scrub_force_testing=1e1; ---error ER_WRONG_VALUE_FOR_VAR -set global innodb_scrub_force_testing="foo"; - -SET @@global.innodb_scrub_force_testing = @start_global_value; diff --git a/mysql-test/suite/sys_vars/t/innodb_scrub_log_interval_basic.test b/mysql-test/suite/sys_vars/t/innodb_scrub_log_speed_basic.test similarity index 51% rename from mysql-test/suite/sys_vars/t/innodb_scrub_log_interval_basic.test rename to mysql-test/suite/sys_vars/t/innodb_scrub_log_speed_basic.test index e8d4f1bc737..5e750eebd65 100644 --- a/mysql-test/suite/sys_vars/t/innodb_scrub_log_interval_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_scrub_log_speed_basic.test @@ -1,55 +1,55 @@ --source include/have_innodb.inc # Display default value -SELECT @@GLOBAL.innodb_scrub_log_interval; +SELECT @@GLOBAL.innodb_scrub_log_speed; --echo 200 Expected # Check if value can be set -SET @@GLOBAL.innodb_scrub_log_interval=100; +SET @@GLOBAL.innodb_scrub_log_speed=100; --echo 1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; +SELECT @@GLOBAL.innodb_scrub_log_speed; --echo 100 Expected -SET @@GLOBAL.innodb_scrub_log_interval=DEFAULT; +SET @@GLOBAL.innodb_scrub_log_speed=DEFAULT; --echo 1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; +SELECT @@GLOBAL.innodb_scrub_log_speed; --echo 200 Expected # Check if the value in GLOBAL TABLE matches value in variable -SELECT @@GLOBAL.innodb_scrub_log_interval = VARIABLE_VALUE +SELECT @@GLOBAL.innodb_scrub_log_speed = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_scrub_log_interval'; +WHERE VARIABLE_NAME='innodb_scrub_log_speed'; --echo 1 Expected -SELECT @@GLOBAL.innodb_scrub_log_interval; +SELECT @@GLOBAL.innodb_scrub_log_speed; --echo 200 Expected SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_scrub_log_interval'; +WHERE VARIABLE_NAME='innodb_scrub_log_speed'; --echo 200 Expected # Check if accessing variable with and without GLOBAL point to same variable -SELECT @@innodb_scrub_log_interval = @@GLOBAL.innodb_scrub_log_interval; +SELECT @@innodb_scrub_log_speed = @@GLOBAL.innodb_scrub_log_speed; --echo 1 Expected -# Check if innodb_scrub_log_interval can be accessed with and without @@ sign -SELECT @@innodb_scrub_log_interval; +# Check if innodb_scrub_log_speed can be accessed with and without @@ sign +SELECT @@innodb_scrub_log_speed; --echo 200 Expected --Error ER_INCORRECT_GLOBAL_LOCAL_VAR -SELECT @@local.innodb_scrub_log_interval; +SELECT @@local.innodb_scrub_log_speed; --echo Expected error 'Variable is a GLOBAL variable' --Error ER_INCORRECT_GLOBAL_LOCAL_VAR -SELECT @@SESSION.innodb_scrub_log_interval; +SELECT @@SESSION.innodb_scrub_log_speed; --echo Expected error 'Variable is a GLOBAL variable' -SELECT @@GLOBAL.innodb_scrub_log_interval; +SELECT @@GLOBAL.innodb_scrub_log_speed; --echo 200 Expected --Error ER_BAD_FIELD_ERROR -SELECT innodb_scrub_log_interval; +SELECT innodb_scrub_log_speed; --echo Expected error 'Unknow column in field list' diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index ab1fb4e4c54..8a4ad35765c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1697,3 +1697,19 @@ INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e; ALTER TABLE t1 MODIFY i FLOAT; DROP TABLE t1; +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-7816 ALTER with DROP INDEX and ADD INDEX .. COMMENT='comment2' ignores the new comment +--echo # +CREATE TABLE t1(a INT); +CREATE INDEX i1 ON t1(a) COMMENT 'comment1'; +ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2'; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # Start of 10.1 tests +--echo # diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index ede434f2c32..3ec5e0ba0b1 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -87,8 +87,7 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) my_errno=errno; DBUG_PRINT("error",("Got error %d on open",my_errno)); if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) - my_error((flags & O_RDONLY) || (flags == O_RDONLY ) ? EE_FILENOTFOUND : - EE_CANTCREATEFILE, + my_error((flags & O_RDONLY) ? EE_FILENOTFOUND : EE_CANTCREATEFILE, MYF(ME_BELL+ME_WAITTANG), filename, my_errno); DBUG_RETURN((FILE*) 0); } /* my_fopen */ diff --git a/mysys_ssl/CMakeLists.txt b/mysys_ssl/CMakeLists.txt index 5eead8d6aaf..8a8f81d70ae 100644 --- a/mysys_ssl/CMakeLists.txt +++ b/mysys_ssl/CMakeLists.txt @@ -33,7 +33,6 @@ IF(WITH_SSL STREQUAL "bundled" AND HAVE_VISIBILITY_HIDDEN) ENDIF() SET(MYSYS_SSL_SOURCES - my_aes.cc my_sha1.cc my_sha2.cc my_md5.cc diff --git a/mysys_ssl/my_aes.cc b/mysys_ssl/my_aes.cc deleted file mode 100644 index 6486f7447c3..00000000000 --- a/mysys_ssl/my_aes.cc +++ /dev/null @@ -1,1048 +0,0 @@ -/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include -#include -#include -#include - -#if defined(HAVE_YASSL) -#include "aes.hpp" -#include "openssl/ssl.h" -#include "crypto_wrapper.hpp" -#elif defined(HAVE_OPENSSL) -#include -#include -#include -#include - -// Wrap C struct, to ensure resources are released. -struct MyCipherCtx -{ - MyCipherCtx() { memset(&ctx, 0, sizeof(ctx)); } - ~MyCipherCtx() { EVP_CIPHER_CTX_cleanup(&ctx); } - - EVP_CIPHER_CTX ctx; -}; -#endif - -enum encrypt_dir { MY_AES_ENCRYPT, MY_AES_DECRYPT }; - -/** - This is internal function just keeps joint code of Key generation - - SYNOPSIS - my_aes_create_key() - @param key [in] Key to use for real key creation - @param key_length [in] Length of the key - @param rkey [out] Real key (used by OpenSSL/YaSSL) - - @return - 0 Ok - -1 Error; Note: The current impementation never returns this -*/ - -static int my_aes_create_key(const char *key, int key_length, uint8 *rkey) -{ - uint8 *rkey_end= rkey + AES_KEY_LENGTH / 8; /* Real key boundary */ - uint8 *ptr; /* Start of the real key*/ - const char *sptr; /* Start of the working key */ - const char *key_end= key + key_length; /* Working key boundary*/ - - memset(rkey, 0, AES_KEY_LENGTH / 8); /* Set initial key */ - - for (ptr= rkey, sptr= key; sptr < key_end; ptr ++, sptr ++) - { - if (ptr == rkey_end) - /* Just loop over tmp_key until we used all key */ - ptr= rkey; - *ptr ^= (uint8) *sptr; - } -#ifdef AES_USE_KEY_BITS - /* - This block is intended to allow more weak encryption if application - build with libmysqld needs to correspond to export regulations - It should be never used in normal distribution as does not give - any speed improvement. - To get worse security define AES_USE_KEY_BITS to number of bits - you want key to be. It should be divisible by 8 - - WARNING: Changing this value results in changing of enryption for - all key lengths so altering this value will result in impossibility - to decrypt data encrypted with previous value - */ -#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8) - /* - To get weaker key we use first AES_USE_KEY_BYTES bytes of created key - and cyclically copy them until we created all required key length - */ - for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end; - ptr ++, sptr ++) - { - if (sptr == rkey + AES_USE_KEY_BYTES) - sptr= rkey; - *ptr= *sptr; - } -#endif - return 0; -} - -/** - Decode Hexencoded String to uint8[]. - - SYNOPSIS - my_aes_hex2uint() - @param iv [in] Pointer to hexadecimal encoded IV String - @param dest [out] Pointer to output uint8 array. Memory allocated by caller - @param iv_length [in] Size of destination array. - */ - -void my_aes_hex2uint(const char* in, unsigned char *out, int dest_length) -{ - const char *pos= in; - int count; - for (count = 0; count < dest_length; count++) - { - uchar res; - sscanf(pos, "%2hhx", &res); - out[count] = res; - pos += 2 * sizeof(char); - } -} - - -/** - Calculate key and iv from a given salt and secret as it is handled - in openssl encrypted files via console - - SYNOPSIS - my_bytes_to_key() - @param salt [in] the given salt as extracted from the encrypted file - @param secret [in] the given secret as String, provided by the user - @param key [out] 32 Bytes of key are written to this pointer - @param iv [out] 16 Bytes of iv are written to this pointer -*/ - -void my_bytes_to_key(const unsigned char *salt, const char *secret, unsigned char *key, - unsigned char *iv) -{ -#ifdef HAVE_YASSL - /* the yassl function has no support for SHA1. Reason unknown. */ - int keyLen = 32; - int ivLen = 16; - int EVP_SALT_SZ = 8; - const int SHA_LEN = 20; - yaSSL::SHA myMD; - uint digestSz = myMD.get_digestSize(); - unsigned char digest[SHA_LEN]; // max size - int sz = strlen(secret); - int count = 1; - int keyLeft = keyLen; - int ivLeft = ivLen; - int keyOutput = 0; - - while (keyOutput < (keyLen + ivLen)) - { - int digestLeft = digestSz; - if (keyOutput) // first time D_0 is empty - myMD.update(digest, digestSz); - myMD.update((yaSSL::byte* )secret, sz); - if (salt) - myMD.update(salt, EVP_SALT_SZ); - myMD.get_digest(digest); - for (int j = 1; j < count; j++) - { - myMD.update(digest, digestSz); - myMD.get_digest(digest); - } - - if (keyLeft) - { - int store = MY_MIN(keyLeft, static_cast(digestSz)); - memcpy(&key[keyLen - keyLeft], digest, store); - - keyOutput += store; - keyLeft -= store; - digestLeft -= store; - } - - if (ivLeft && digestLeft) - { - int store = MY_MIN(ivLeft, digestLeft); - memcpy(&iv[ivLen - ivLeft], &digest[digestSz - digestLeft], store); - - keyOutput += store; - ivLeft -= store; - } - } -#elif defined(HAVE_OPENSSL) - const EVP_CIPHER *type = EVP_aes_256_cbc(); - const EVP_MD *digest = EVP_sha1(); - EVP_BytesToKey(type, digest, salt, (uchar*) secret, strlen(secret), 1, key, iv); -#endif -} - -/** - Crypt buffer with AES CBC encryption algorithm. - - SYNOPSIS - my_aes_encrypt_cbc() - @param source [in] Pointer to data for encryption - @param source_length [in] Size of encryption data - @param dest [out] Buffer to place encrypted data (must be large enough) - @param dest_length [out] Pointer to size of encrypted data - @param key [in] Key to be used for encryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set to true, no padding is used. if the input length is not a - multiple of the AES block size, trailing bytes are only copied to destination buffer. - This allows currently the same interface for CBC, ECB and CTR encryption. - @return - != 0 error - 0 no error -*/ - -static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE; - source_length = source_length - remaining_bytes; - -#ifdef HAVE_YASSL - TaoCrypt::AES_CBC_Encryption enc; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - int num_blocks; /* number of complete blocks */ - int i; - switch(key_length) { - case 16: - break; - case 24: - break; - case 32: - break; - default: - return AES_BAD_KEYSIZE; - } - - enc.SetKey((const TaoCrypt::byte *) key, key_length, (const TaoCrypt::byte *) iv); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ - { - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - if (noPadding) { - if (remaining_bytes!=0) { - /* Note that we moved the original pointers above */ - memcpy(dest, source, remaining_bytes); - } - *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes; - return AES_OK; - } - - /* Encode the rest. We always have incomplete block */ - char pad_len = MY_AES_BLOCK_SIZE - (source_length - - MY_AES_BLOCK_SIZE * num_blocks); - memcpy(block, source, 16 - pad_len); - memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len); - - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block, - MY_AES_BLOCK_SIZE); - - *dest_length = MY_AES_BLOCK_SIZE * (num_blocks + 1); - return AES_OK; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; - /* The real key to be used for encryption */ - const EVP_CIPHER* cipher; - switch(key_length) { - case 16: - cipher = EVP_aes_128_cbc(); - break; - case 24: - cipher = EVP_aes_192_cbc(); - break; - case 32: - cipher = EVP_aes_256_cbc(); - break; - default: - return AES_BAD_KEYSIZE; - } - //Initialize Encryption Engine here, default software Engine is default - ENGINE *engine = NULL; - - if (! EVP_EncryptInit_ex(&ctx.ctx, cipher, engine, key, iv)) - return AES_BAD_DATA; /* Error */ - if (noPadding) { - EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0); - } - EVP_CIPHER_CTX_key_length(&ctx.ctx); - OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); - OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); - if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) - return AES_BAD_DATA; /* Error */ - - if (remaining_bytes!=0) { - memcpy(dest + source_length, source + source_length, remaining_bytes); - } - *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes); - - return AES_OK; -#else - /* currently Open SSL is required */ - return AES_BAD_DATA; -#endif -} - - -/** - Crypt buffer with AES ECB encryption algorithm. - - SYNOPSIS - my_aes_encrypt_ecb() - @param source [in] Pointer to data for encryption - @param source_length [in] Size of encryption data - @param dest [out] Buffer to place encrypted data (must be large enough) - @param dest_length [out] Pointer to size of encrypted data - @param key [in] Key to be used for encryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set to true, no padding is used. if the input length is not a - multiple of the AES block size, trailing bytes are only copied to destination buffer. - This allows currently the same interface for CBC, ECB and CTR encryption. - @return - != 0 error - 0 no error -*/ - -static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE; - source_length = source_length - remaining_bytes; - -#ifdef HAVE_YASSL - TaoCrypt::AES_ECB_Encryption enc; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - int num_blocks; /* number of complete blocks */ - int i; - switch(key_length) { - case 16: - break; - case 24: - break; - case 32: - break; - default: - return AES_BAD_KEYSIZE; - } - - enc.SetKey((const TaoCrypt::byte *) key, key_length, (const TaoCrypt::byte *) iv); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ - { - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - if (noPadding) { - if (remaining_bytes!=0) { - /* Note that we moved the original pointers above */ - memcpy(dest, source, remaining_bytes); - } - *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes; - return AES_OK; - } - - /* Encode the rest. We always have incomplete block */ - char pad_len = MY_AES_BLOCK_SIZE - (source_length - - MY_AES_BLOCK_SIZE * num_blocks); - memcpy(block, source, 16 - pad_len); - memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len); - - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block, - MY_AES_BLOCK_SIZE); - - *dest_length = MY_AES_BLOCK_SIZE * (num_blocks + 1); - return AES_OK; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; - /* The real key to be used for encryption */ - const EVP_CIPHER* cipher; - switch(key_length) { - case 16: - cipher = EVP_aes_128_ecb(); - break; - case 24: - cipher = EVP_aes_192_ecb(); - break; - case 32: - cipher = EVP_aes_256_ecb(); - break; - default: - return AES_BAD_KEYSIZE; - } - //Initialize Encryption Engine here, default software Engine is default - ENGINE *engine = NULL; - - if (! EVP_EncryptInit_ex(&ctx.ctx, cipher, engine, key, iv)) - return AES_BAD_DATA; /* Error */ - if (noPadding) { - EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0); - } - EVP_CIPHER_CTX_key_length(&ctx.ctx); - OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); - // ECB does not use IV - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0); - OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); - if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) - return AES_BAD_DATA; /* Error */ - - if (remaining_bytes!=0) - memcpy(dest + source_length, source + source_length, remaining_bytes); - - *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes); - - return AES_OK; -#else - /* currently Open SSL is required */ - return AES_BAD_DATA; -#endif -} - - - -/** - AES decryption - CBC mode - - SYNOPSIS - my_aes_decrypt_cbc() - @param source [in] Pointer to data to decrypt - @param source_length [in] Size of data - @param dest [out] Buffer to place decrypted data (must be large enough) - @param dest_length [out] Pointer to size of decrypted data - @param key [in] Key to be used for decryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set to true, no padding is used. if the input length is not a - multiple of the AES block size, trailing bytes are only copied to destination buffer. - This allows currently the same interface for CBC, ECB and CTR encryption. - - @return - != 0 error - 0 no error -*/ - -static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length, - uchar* dest, uint32 *dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE; - source_length = source_length - remaining_bytes; - - -#ifdef HAVE_YASSL - TaoCrypt::AES_CBC_Decryption dec; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - uint num_blocks; /* Number of complete blocks */ - int i; - switch(key_length) { - case 16: - break; - case 24: - break; - case 32: - break; - default: - return AES_BAD_KEYSIZE; - } - - dec.SetKey((const TaoCrypt::byte *) key, key_length, iv); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - if ((source_length != num_blocks * MY_AES_BLOCK_SIZE) || num_blocks == 0 ) - /* Input size has to be even and at least one block */ - return AES_BAD_DATA; - - /* Decode all but last blocks */ - for (i = num_blocks - 1; i > 0; i--) - { - dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - - if (noPadding) { - memcpy(dest, block, MY_AES_BLOCK_SIZE); - if (remaining_bytes!=0) { - /* Note that we have moved dest and source */ - memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes); - } - *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes; - return AES_OK; - } - - /* Use last char in the block as size */ - uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; - - if (pad_len > MY_AES_BLOCK_SIZE) - return AES_BAD_DATA; - /* We could also check whole padding but we do not really need this */ - - memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len); - *dest_length = MY_AES_BLOCK_SIZE * num_blocks - pad_len; - return AES_OK; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; - - const EVP_CIPHER* cipher; - switch(key_length) { - case 16: - cipher = EVP_aes_128_cbc(); - break; - case 24: - cipher = EVP_aes_192_cbc(); - break; - case 32: - cipher = EVP_aes_256_cbc(); - break; - default: - return AES_BAD_KEYSIZE; - } - //Initialize Encryption Engine here, default software Engine is default - ENGINE *engine = NULL; - - if (! EVP_DecryptInit_ex(&ctx.ctx, cipher, engine, key, iv)) - return AES_BAD_DATA; /* Error */ - if (noPadding) { - EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0); - } - OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); - OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); - if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned char *)source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_DecryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) { - *dest_length = (unsigned long int) u_len; - return AES_BAD_DATA; - } - if (remaining_bytes!=0) { - memcpy(dest + source_length, source + source_length, remaining_bytes); - } - *dest_length = (unsigned long int) (u_len + f_len) + remaining_bytes; -#endif - return AES_OK; -} - -/** - AES decryption - ECB mode - - SYNOPSIS - my_aes_decrypt_ecb() - @param source [in] Pointer to data to decrypt - @param source_length [in] Size of data - @param dest [out] Buffer to place decrypted data (must be large enough) - @param dest_length [out] Pointer to size of decrypted data - @param key [in] Key to be used for decryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] if set to true, no padding is used. if the input length is not a - multiple of the AES block size, trailing bytes are only copied to destination buffer. - This allows currently the same interface for CBC, ECB and CTR encryption. - - @return - != 0 error - 0 no error -*/ - -static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length, - uchar* dest, uint32 *dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - uint8 remaining_bytes = (noPadding == 0) ? 0 : source_length % MY_AES_BLOCK_SIZE; - source_length = source_length - remaining_bytes; - - -#ifdef HAVE_YASSL - TaoCrypt::AES_ECB_Decryption dec; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - uint num_blocks; /* Number of complete blocks */ - int i; - switch(key_length) { - case 16: - break; - case 24: - break; - case 32: - break; - default: - return AES_BAD_KEYSIZE; - } - - dec.SetKey((const TaoCrypt::byte *) key, key_length, iv); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - if ((source_length != num_blocks * MY_AES_BLOCK_SIZE) || num_blocks == 0 ) - /* Input size has to be even and at least one block */ - return AES_BAD_DATA; - - /* Decode all but last blocks */ - for (i = num_blocks - 1; i > 0; i--) - { - dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - - if (noPadding) { - memcpy(dest, block, MY_AES_BLOCK_SIZE); - if (remaining_bytes!=0) { - /* Note that we have moved dest and source */ - memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes); - } - *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes; - return AES_OK; - } - - /* Use last char in the block as size */ - uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; - - if (pad_len > MY_AES_BLOCK_SIZE) - return AES_BAD_DATA; - /* We could also check whole padding but we do not really need this */ - - memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len); - *dest_length = MY_AES_BLOCK_SIZE * num_blocks - pad_len; - return AES_OK; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; - - const EVP_CIPHER* cipher; - switch(key_length) { - case 16: - cipher = EVP_aes_128_ecb(); - break; - case 24: - cipher = EVP_aes_192_ecb(); - break; - case 32: - cipher = EVP_aes_256_ecb(); - break; - default: - return AES_BAD_KEYSIZE; - } - //Initialize Encryption Engine here, default software Engine is default - ENGINE *engine = NULL; - - if (! EVP_DecryptInit_ex(&ctx.ctx, cipher, engine, key, iv)) - return AES_BAD_DATA; /* Error */ - if (noPadding) { - EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0); - } - OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length); - // ECB does not use IV - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0); - OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16); - if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned char *)source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_DecryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) { - *dest_length = (unsigned long int) u_len; - return AES_BAD_DATA; - } - if (remaining_bytes!=0) { - memcpy(dest + source_length, source + source_length, remaining_bytes); - } - *dest_length = (unsigned long int) (u_len + f_len) + remaining_bytes; - -#endif - return AES_OK; -} - - - - - -/** - Encryption interface that doesn't do anything (for testing) - - SYNOPSIS - my_aes_encrypt_none() - @param source [in] Pointer to data for encryption - @param source_length [in] Size of encryption data - @param dest [out] Buffer to place encrypted data (must be large enough) - @param dest_length [out] Pointer to size of encrypted data - @param key [in] Key to be used for encryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] unused - @return - != 0 error - 0 no error -*/ - -static int my_aes_encrypt_none(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - memcpy(dest, source, source_length); - *dest_length= source_length; - return 0; -} - - -/** - Decryption interface that doesn't do anything (for testing) - - SYNOPSIS - my_aes_decrypt_none() - @param source [in] Pointer to data to decrypt - @param source_length [in] Size of data - @param dest [out] Buffer to place decrypted data (must be large enough) - @param dest_length [out] Pointer to size of decrypted data - @param key [in] Key to be used for decryption - @param key_length [in] Length of the key. 16, 24 or 32 - @param iv [in] Iv to be used for encryption - @param iv_length [in] Length of the iv. should be 16. - @param noPadding [in] unused - - @return - != 0 error - 0 no error -*/ - -int my_aes_decrypt_none(const uchar* source, uint32 source_length, - uchar* dest, uint32 *dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) -{ - memcpy(dest, source, source_length); - *dest_length= source_length; - return 0; -} - -/** - Initialize encryption methods -*/ - -my_aes_decrypt_dynamic_type my_aes_decrypt_dynamic= my_aes_decrypt_none; -my_aes_encrypt_dynamic_type my_aes_encrypt_dynamic= my_aes_encrypt_none; -enum_my_aes_encryption_algorithm current_aes_dynamic_method= MY_AES_ALGORITHM_NONE; - -my_bool my_aes_init_dynamic_encrypt(enum_my_aes_encryption_algorithm method) -{ - switch (method) - { - /* used for encrypting tables */ - case MY_AES_ALGORITHM_ECB: - my_aes_encrypt_dynamic= my_aes_encrypt_ecb; - my_aes_decrypt_dynamic= my_aes_decrypt_ecb; - break; - case MY_AES_ALGORITHM_CBC: - my_aes_encrypt_dynamic= my_aes_encrypt_cbc; - my_aes_decrypt_dynamic= my_aes_decrypt_cbc; - break; -#ifdef HAVE_EncryptAes128Ctr - /* encrypt everything, with a set of keys */ - case MY_AES_ALGORITHM_CTR: - my_aes_encrypt_dynamic= my_aes_encrypt_ctr; - my_aes_decrypt_dynamic= my_aes_decrypt_ctr; - break; -#endif - /* Simulate encrypting interface */ - case MY_AES_ALGORITHM_NONE: - my_aes_encrypt_dynamic= my_aes_encrypt_none; - my_aes_decrypt_dynamic= my_aes_decrypt_none; - break; - default: - return 1; - } - current_aes_dynamic_method= method; - return 0; -} - -my_aes_decrypt_dynamic_type -get_aes_decrypt_func(enum_my_aes_encryption_algorithm method) -{ - switch (method) - { - /* used for encrypting tables */ - case MY_AES_ALGORITHM_ECB: - return my_aes_decrypt_ecb; - break; - case MY_AES_ALGORITHM_CBC: - return my_aes_decrypt_cbc; - break; -#ifdef HAVE_EncryptAes128Ctr - /* encrypt everything, with a set of keys */ - case MY_AES_ALGORITHM_CTR: - return my_aes_decrypt_ctr; - break; -#endif - /* Simulate encrypting interface */ - case MY_AES_ALGORITHM_NONE: - return my_aes_decrypt_none; - break; - default: - return NULL; - } - return NULL; -} - -my_aes_encrypt_dynamic_type -get_aes_encrypt_func(enum_my_aes_encryption_algorithm method) -{ - switch (method) - { - /* used for encrypting tables */ - case MY_AES_ALGORITHM_ECB: - return my_aes_encrypt_ecb; - break; - case MY_AES_ALGORITHM_CBC: - return my_aes_encrypt_cbc; - break; -#ifdef HAVE_EncryptAes128Ctr - /* encrypt everything, with a set of keys */ - case MY_AES_ALGORITHM_CTR: - return my_aes_encrypt_ctr; - break; -#endif - /* Simulate encrypting interface */ - case MY_AES_ALGORITHM_NONE: - return my_aes_encrypt_none; - break; - default: - return NULL; - } - return NULL; -} - - -/**************************************************************** - Encryption function visible to MariaDB users -****************************************************************/ - -int my_aes_encrypt(const uchar* source, int source_length, uchar* dest, - const char* key, int key_length) -{ -#if defined(HAVE_YASSL) - TaoCrypt::AES_ECB_Encryption enc; - - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - int num_blocks; /* number of complete blocks */ - int i; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; -#endif - - /* The real key to be used for encryption */ - uint8 rkey[AES_KEY_LENGTH / 8]; - int rc; /* result codes */ - - if ((rc= my_aes_create_key(key, key_length, rkey))) - return rc; - -#if defined(HAVE_YASSL) - enc.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ - { - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - /* Encode the rest. We always have incomplete block */ - char pad_len = MY_AES_BLOCK_SIZE - (source_length - - MY_AES_BLOCK_SIZE * num_blocks); - memcpy(block, source, 16 - pad_len); - memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len); - - enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block, - MY_AES_BLOCK_SIZE); - - return MY_AES_BLOCK_SIZE * (num_blocks + 1); -#elif defined(HAVE_OPENSSL) - if (! EVP_EncryptInit(&ctx.ctx, EVP_aes_128_ecb(), - (const unsigned char *) rkey, NULL)) - return AES_BAD_DATA; /* Error */ - if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_EncryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) - return AES_BAD_DATA; /* Error */ - - return u_len + f_len; -#endif -} - - -/** - DeCrypt buffer with AES encryption algorithm. - - SYNOPSIS - my_aes_decrypt() - @param source [in] Pointer to data for decryption - @param source_length [in] Size of encrypted data - @param dest [out] Buffer to place decrypted data (must - be large enough) - @param key [in] Key to be used for decryption - @param key_length [in] Length of the key. Will handle keys of any length - - @return - >= 0 Size of encrypted data - < 0 Error -*/ - -int my_aes_decrypt(const uchar *source, int source_length, uchar *dest, - const char *key, int key_length) -{ -#if defined(HAVE_YASSL) - TaoCrypt::AES_ECB_Decryption dec; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; - int num_blocks; /* Number of complete blocks */ - int i; -#elif defined(HAVE_OPENSSL) - MyCipherCtx ctx; - int u_len, f_len; -#endif - - /* The real key to be used for decryption */ - uint8 rkey[AES_KEY_LENGTH / 8]; - int rc; /* Result codes */ - - if ((rc= my_aes_create_key(key, key_length, rkey))) - return rc; - -#if defined(HAVE_YASSL) - dec.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); - - num_blocks = source_length / MY_AES_BLOCK_SIZE; - - if ((source_length != num_blocks * MY_AES_BLOCK_SIZE) || num_blocks == 0 ) - /* Input size has to be even and at least one block */ - return AES_BAD_DATA; - - /* Decode all but last blocks */ - for (i = num_blocks - 1; i > 0; i--) - { - dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - source += MY_AES_BLOCK_SIZE; - dest += MY_AES_BLOCK_SIZE; - } - - dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source, - MY_AES_BLOCK_SIZE); - - /* Use last char in the block as size */ - uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; - - if (pad_len > MY_AES_BLOCK_SIZE) - return AES_BAD_DATA; - /* We could also check whole padding but we do not really need this */ - - memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len); - return MY_AES_BLOCK_SIZE * num_blocks - pad_len; -#elif defined(HAVE_OPENSSL) - if (! EVP_DecryptInit(&ctx.ctx, EVP_aes_128_ecb(), - (const unsigned char *) rkey, NULL)) - return AES_BAD_DATA; /* Error */ - if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, source_length)) - return AES_BAD_DATA; /* Error */ - if (! EVP_DecryptFinal(&ctx.ctx, (unsigned char *) dest + u_len, &f_len)) - return AES_BAD_DATA; /* Error */ - return u_len + f_len; -#endif -} - - -/** - Get size of buffer which will be large enough for encrypted data - - SYNOPSIS - my_aes_get_size() - @param source_length [in] Length of data to be encrypted - - @return - Size of buffer required to store encrypted data -*/ - -int my_aes_get_size(int source_length) -{ - return MY_AES_BLOCK_SIZE * (source_length / MY_AES_BLOCK_SIZE) - + MY_AES_BLOCK_SIZE; -} diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc index d92f76d633b..3bb8f860c37 100644 --- a/mysys_ssl/my_crypt.cc +++ b/mysys_ssl/my_crypt.cc @@ -1,348 +1,246 @@ /* - TODO: add support for YASSL -*/ + Copyright (c) 2014 Google Inc. + Copyright (c) 2014, 2015 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include -/* YASSL doesn't support EVP_CIPHER_CTX */ -#ifdef HAVE_EncryptAes128Ctr +#ifdef HAVE_YASSL +#include "aes.hpp" -#include "mysql.h" +typedef TaoCrypt::CipherDir Dir; +static const Dir CRYPT_ENCRYPT = TaoCrypt::ENCRYPTION; +static const Dir CRYPT_DECRYPT = TaoCrypt::DECRYPTION; + +typedef TaoCrypt::Mode CipherMode; +static inline CipherMode aes_ecb(uint) { return TaoCrypt::ECB; } +static inline CipherMode aes_cbc(uint) { return TaoCrypt::CBC; } + +typedef TaoCrypt::byte KeyByte; + +#else #include #include -static const int CRYPT_ENCRYPT = 1; -static const int CRYPT_DECRYPT = 0; +typedef int Dir; +static const Dir CRYPT_ENCRYPT = 1; +static const Dir CRYPT_DECRYPT = 0; -class Encrypter { - public: - virtual ~Encrypter() {} +typedef const EVP_CIPHER *CipherMode; - virtual Crypt_result Encrypt(const uchar* plaintext, - int plaintext_size, - uchar* ciphertext, - int* ciphertext_used) = 0; - virtual Crypt_result GetTag(uchar* tag, int tag_size) = 0; +#define make_aes_dispatcher(mode) \ + static inline CipherMode aes_ ## mode(uint key_length) \ + { \ + switch (key_length) { \ + case 16: return EVP_aes_128_ ## mode(); \ + case 24: return EVP_aes_192_ ## mode(); \ + case 32: return EVP_aes_256_ ## mode(); \ + default: return 0; \ + } \ + } + +make_aes_dispatcher(ecb) +make_aes_dispatcher(cbc) +#ifdef HAVE_EncryptAes128Ctr +make_aes_dispatcher(ctr) +#endif + +typedef uchar KeyByte; + +struct MyCTX : EVP_CIPHER_CTX { + MyCTX() { EVP_CIPHER_CTX_init(this); } + ~MyCTX() { EVP_CIPHER_CTX_cleanup(this); } }; +#endif -class Decrypter { - public: - virtual ~Decrypter() {} +static int do_crypt(CipherMode cipher, Dir dir, + const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const KeyByte *key, uint key_length, + const KeyByte *iv, uint iv_length, int no_padding) +{ + int tail= source_length % MY_AES_BLOCK_SIZE; - virtual Crypt_result SetTag(const uchar* tag, int tag_size) = 0; - virtual Crypt_result Decrypt(const uchar* ciphertext, - int ciphertext_size, - uchar* plaintext, - int* plaintext_used) = 0; - virtual Crypt_result CheckTag() = 0; -}; +#ifdef HAVE_YASSL + TaoCrypt::AES ctx(dir, cipher); -class Crypto { - public: - virtual ~Crypto(); + if (unlikely(key_length != 16 && key_length != 24 && key_length != 32)) + return MY_AES_BAD_KEYSIZE; - Crypt_result Crypt(const uchar* input, int input_size, - uchar* output, int* output_used); + ctx.SetKey(key, key_length); + if (iv) + { + ctx.SetIV(iv); + DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE == iv_length); + } + DBUG_ASSERT(TaoCrypt::AES::BLOCK_SIZE == MY_AES_BLOCK_SIZE); - protected: - Crypto(); + ctx.Process(dest, source, source_length - tail); + *dest_length= source_length - tail; - EVP_CIPHER_CTX ctx; -}; - - -/* Various crypto implementations */ - -class Aes128CtrCrypto : public Crypto { - public: - virtual Crypt_result Init(const uchar* key, const uchar* iv, - int iv_size); - - protected: - Aes128CtrCrypto() {} - - virtual int mode() = 0; -}; - -class Aes128CtrEncrypter : public Aes128CtrCrypto, public Encrypter { - public: - Aes128CtrEncrypter() {} - virtual Crypt_result Encrypt(const uchar* plaintext, - int plaintext_size, - uchar* ciphertext, - int* ciphertext_used); - - virtual Crypt_result GetTag(uchar* tag, int tag_size) { - DBUG_ASSERT(false); - return AES_INVALID; + /* unlike OpenSSL, YaSSL doesn't support PKCS#7 padding */ + if (!no_padding) + { + if (dir == CRYPT_ENCRYPT) + { + uchar buf[MY_AES_BLOCK_SIZE]; + memcpy(buf, source + source_length - tail, tail); + memset(buf + tail, MY_AES_BLOCK_SIZE - tail, MY_AES_BLOCK_SIZE - tail); + ctx.Process(dest + *dest_length, buf, MY_AES_BLOCK_SIZE); + *dest_length+= MY_AES_BLOCK_SIZE; + } + else + { + int n= dest[source_length - 1]; + if (tail || n == 0 || n > MY_AES_BLOCK_SIZE) + return MY_AES_BAD_DATA; + *dest_length-= n; + } } - protected: - virtual int mode() { - return CRYPT_ENCRYPT; +#else // HAVE_OPENSSL + int fin; + struct MyCTX ctx; + + if (unlikely(!cipher)) + return MY_AES_BAD_KEYSIZE; + + if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, dir)) + return MY_AES_OPENSSL_ERROR; + + EVP_CIPHER_CTX_set_padding(&ctx, !no_padding); + + DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length); + DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) == (int)iv_length); + DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == MY_AES_BLOCK_SIZE || !no_padding); + + /* use built-in OpenSSL padding, if possible */ + if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length, + source, source_length - (no_padding ? tail : 0))) + return MY_AES_OPENSSL_ERROR; + if (!EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin)) + return MY_AES_BAD_DATA; + *dest_length += fin; + +#endif + + if (no_padding && tail) + { + /* + Not much we can do, block ciphers cannot encrypt data that aren't + a multiple of the block length. At least not without padding. + What we do here, we XOR the tail with the previous encrypted block. + */ + + if (unlikely(source_length < MY_AES_BLOCK_SIZE)) + return MY_AES_BAD_DATA; + + const uchar *s= source + source_length - tail; + const uchar *e= source + source_length; + uchar *d= dest + source_length - tail; + const uchar *m= (dir == CRYPT_ENCRYPT ? d : s) - MY_AES_BLOCK_SIZE; + while (s < e) + *d++ = *s++ ^ *m++; + *dest_length= source_length; } - private: - Aes128CtrEncrypter(const Aes128CtrEncrypter& o); - Aes128CtrEncrypter& operator=(const Aes128CtrEncrypter& o); -}; - -class Aes128CtrDecrypter : public Aes128CtrCrypto, public Decrypter { - public: - Aes128CtrDecrypter() {} - virtual Crypt_result Decrypt(const uchar* ciphertext, - int ciphertext_size, - uchar* plaintext, - int* plaintext_used); - - virtual Crypt_result SetTag(const uchar* tag, int tag_size) { - DBUG_ASSERT(false); - return AES_INVALID; - } - - virtual Crypt_result CheckTag() { - DBUG_ASSERT(false); - return AES_INVALID; - } - - protected: - virtual int mode() { - return CRYPT_DECRYPT; - } - - private: - Aes128CtrDecrypter(const Aes128CtrDecrypter& o); - Aes128CtrDecrypter& operator=(const Aes128CtrDecrypter& o); -}; - -class Aes128EcbCrypto : public Crypto { - public: - virtual Crypt_result Init(const unsigned char* key); - - protected: - Aes128EcbCrypto() {} - - virtual int mode() = 0; -}; - -class Aes128EcbEncrypter : public Aes128EcbCrypto, public Encrypter { - public: - Aes128EcbEncrypter() {} - virtual Crypt_result Encrypt(const unsigned char* plaintext, - int plaintext_size, - unsigned char* ciphertext, - int* ciphertext_used); - - virtual Crypt_result GetTag(unsigned char* tag, int tag_size) { - DBUG_ASSERT(false); - return AES_INVALID; - } - - protected: - virtual int mode() { - return CRYPT_ENCRYPT; - } - - private: - Aes128EcbEncrypter(const Aes128EcbEncrypter& o); - Aes128EcbEncrypter& operator=(const Aes128EcbEncrypter& o); -}; - -class Aes128EcbDecrypter : public Aes128EcbCrypto, public Decrypter { - public: - Aes128EcbDecrypter() {} - virtual Crypt_result Decrypt(const unsigned char* ciphertext, - int ciphertext_size, - unsigned char* plaintext, - int* plaintext_used); - - virtual Crypt_result SetTag(const unsigned char* tag, int tag_size) { - DBUG_ASSERT(false); - return AES_INVALID; - } - - virtual Crypt_result CheckTag() { - DBUG_ASSERT(false); - return AES_INVALID; - } - - protected: - virtual int mode() { - return CRYPT_DECRYPT; - } - - private: - Aes128EcbDecrypter(const Aes128EcbDecrypter& o); - Aes128EcbDecrypter& operator=(const Aes128EcbDecrypter& o); -}; - - -Crypto::~Crypto() { - EVP_CIPHER_CTX_cleanup(&ctx); -} - -Crypto::Crypto() { - EVP_CIPHER_CTX_init(&ctx); -} - -/* - WARNING: It is allowed to have output == NULL, for special cases like AAD - support in AES GCM. output_used however must never be NULL. -*/ - -Crypt_result Crypto::Crypt(const uchar* input, int input_size, - uchar* output, int* output_used) { - DBUG_ASSERT(input != NULL); - DBUG_ASSERT(output_used != NULL); - if (!EVP_CipherUpdate(&ctx, output, output_used, input, input_size)) { - return AES_OPENSSL_ERROR; - } - - return AES_OK; -} - -Crypt_result Aes128CtrCrypto::Init(const uchar* key, - const uchar* iv, - int iv_size) { - if (iv_size != 16) { - DBUG_ASSERT(false); - return AES_BAD_IV; - } - - if (!EVP_CipherInit_ex(&ctx, EVP_aes_128_ctr(), NULL, key, iv, mode())) { - return AES_OPENSSL_ERROR; - } - - return AES_OK; -} - -Crypt_result Aes128CtrEncrypter::Encrypt(const uchar* plaintext, - int plaintext_size, - uchar* ciphertext, - int* ciphertext_used) { - Crypt_result res = Crypt(plaintext, plaintext_size, ciphertext, - ciphertext_used); - DBUG_ASSERT(*ciphertext_used == plaintext_size); - return res; -} - -Crypt_result Aes128CtrDecrypter::Decrypt(const uchar* ciphertext, - int ciphertext_size, - uchar* plaintext, - int* plaintext_used) { - Crypt_result res = Crypt(ciphertext, ciphertext_size, plaintext, - plaintext_used); - DBUG_ASSERT(*plaintext_used == ciphertext_size); - return res; -} - - -Crypt_result Aes128EcbCrypto::Init(const unsigned char* key) { - if (!EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, mode())) { - return AES_OPENSSL_ERROR; - } - - return AES_OK; -} - -Crypt_result Aes128EcbEncrypter::Encrypt(const unsigned char* plaintext, - int plaintext_size, - unsigned char* ciphertext, - int* ciphertext_used) { - Crypt_result res = Crypt(plaintext, plaintext_size, - ciphertext, ciphertext_used); - DBUG_ASSERT(*ciphertext_used == plaintext_size); - return res; -} - -Crypt_result Aes128EcbDecrypter::Decrypt(const unsigned char* ciphertext, - int ciphertext_size, - unsigned char* plaintext, - int* plaintext_used) { - Crypt_result res = Crypt(ciphertext, ciphertext_size, - plaintext, plaintext_used); - DBUG_ASSERT(*plaintext_used == ciphertext_size); - return res; + return MY_AES_OK; } C_MODE_START +#ifdef HAVE_EncryptAes128Ctr - /* Encrypt and decrypt according to Aes128Ctr */ - -Crypt_result my_aes_encrypt_ctr(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) +int my_aes_encrypt_ctr(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) { - Aes128CtrEncrypter encrypter; - Crypt_result res = encrypter.Init(key, iv, iv_length); - if (res != AES_OK) - return res; - return encrypter.Encrypt(source, source_length, dest, (int*)dest_length); + /* CTR is a stream cipher mode, it needs no special padding code */ + return do_crypt(aes_ctr(key_length), CRYPT_ENCRYPT, source, source_length, + dest, dest_length, key, key_length, iv, iv_length, 0); } -Crypt_result my_aes_decrypt_ctr(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) +int my_aes_decrypt_ctr(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) { - Aes128CtrDecrypter decrypter; - - Crypt_result res = decrypter.Init(key, iv, iv_length); - if (res != AES_OK) - return res; - return decrypter.Decrypt(source, source_length, dest, (int*)dest_length); + return do_crypt(aes_ctr(key_length), CRYPT_DECRYPT, source, source_length, + dest, dest_length, key, key_length, iv, iv_length, 0); } +#endif /* HAVE_EncryptAes128Ctr */ -Crypt_result my_aes_encrypt_ecb(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) +int my_aes_encrypt_ecb(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) { - Aes128EcbEncrypter encrypter; - Crypt_result res = encrypter.Init(key); - if (res != AES_OK) - return res; - return encrypter.Encrypt(source, source_length, dest, (int*)dest_length); + return do_crypt(aes_ecb(key_length), CRYPT_ENCRYPT, source, source_length, + dest, dest_length, key, key_length, 0, 0, no_padding); } -Crypt_result my_aes_decrypt_ecb(const uchar* source, uint32 source_length, - uchar* dest, uint32* dest_length, - const unsigned char* key, uint8 key_length, - const unsigned char* iv, uint8 iv_length, - uint noPadding) +int my_aes_decrypt_ecb(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) { - Aes128EcbDecrypter decrypter; + return do_crypt(aes_ecb(key_length), CRYPT_DECRYPT, source, source_length, + dest, dest_length, key, key_length, 0, 0, no_padding); +} - Crypt_result res = decrypter.Init(key); +int my_aes_encrypt_cbc(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) +{ + return do_crypt(aes_cbc(key_length), CRYPT_ENCRYPT, source, source_length, + dest, dest_length, key, key_length, iv, iv_length, no_padding); +} - if (res != AES_OK) - return res; - return decrypter.Decrypt(source, source_length, dest, (int*)dest_length); +int my_aes_decrypt_cbc(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding) +{ + return do_crypt(aes_cbc(key_length), CRYPT_DECRYPT, source, source_length, + dest, dest_length, key, key_length, iv, iv_length, no_padding); } C_MODE_END -#endif /* HAVE_EncryptAes128Ctr */ - #if defined(HAVE_YASSL) #include C_MODE_START -Crypt_result my_random_bytes(uchar* buf, int num) +int my_random_bytes(uchar* buf, int num) { TaoCrypt::RandomNumberGenerator rand; rand.GenerateBlock((TaoCrypt::byte*) buf, num); - return AES_OK; + return MY_AES_OK; } C_MODE_END @@ -353,7 +251,7 @@ C_MODE_END C_MODE_START -Crypt_result my_random_bytes(uchar* buf, int num) +int my_random_bytes(uchar* buf, int num) { /* Unfortunately RAND_bytes manual page does not provide any guarantees @@ -363,9 +261,26 @@ Crypt_result my_random_bytes(uchar* buf, int num) */ RAND_METHOD* rand = RAND_SSLeay(); if (rand == NULL || rand->bytes(buf, num) != 1) - return AES_OPENSSL_ERROR; - return AES_OK; + return MY_AES_OPENSSL_ERROR; + return MY_AES_OK; } C_MODE_END #endif /* HAVE_YASSL */ + +/** + Get size of buffer which will be large enough for encrypted data + + SYNOPSIS + my_aes_get_size() + @param source_length [in] Length of data to be encrypted + + @return + Size of buffer required to store encrypted data +*/ + +int my_aes_get_size(int source_length) +{ + return MY_AES_BLOCK_SIZE * (source_length / MY_AES_BLOCK_SIZE) + + MY_AES_BLOCK_SIZE; +} diff --git a/plugin/debug_key_management/CMakeLists.txt b/plugin/debug_key_management/CMakeLists.txt new file mode 100644 index 00000000000..eeb8a3bf4d2 --- /dev/null +++ b/plugin/debug_key_management/CMakeLists.txt @@ -0,0 +1,2 @@ +MYSQL_ADD_PLUGIN(DEBUG_KEY_MANAGEMENT debug_key_management_plugin.cc + MODULE_ONLY COMPONENT Test) diff --git a/plugin/debug_key_management/debug_key_management_plugin.cc b/plugin/debug_key_management/debug_key_management_plugin.cc new file mode 100644 index 00000000000..33e0c6ab318 --- /dev/null +++ b/plugin/debug_key_management/debug_key_management_plugin.cc @@ -0,0 +1,99 @@ +/* + Copyright (c) 2015 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + Debug key management plugin. + It's used to debug the encryption code with a fixed keys that change + only on user request. + + It does not support different key ids, the only valid key id is 1. + + THIS IS AN EXAMPLE ONLY! ENCRYPTION KEYS ARE HARD-CODED AND *NOT* SECRET! + DO NOT USE THIS PLUGIN IN PRODUCTION! EVER! +*/ + +#include +#include +#include +#include + +#define KEY_SIZE 16 + +static uint key_version; + +static MYSQL_SYSVAR_UINT(version, key_version, PLUGIN_VAR_RQCMDARG, + "Latest key version", NULL, NULL, 1, 0, UINT_MAX, 1); + +static struct st_mysql_sys_var* sysvars[] = { + MYSQL_SYSVAR(version), + NULL +}; + +static unsigned int get_latest_key_version(unsigned int keyid) +{ + if (keyid != 1) + return ENCRYPTION_KEY_VERSION_INVALID; + + return key_version; +} + +static unsigned int get_key(unsigned int keyid, unsigned int version, + unsigned char* dstbuf, unsigned *buflen) +{ + if (keyid != 1) + return ENCRYPTION_KEY_VERSION_INVALID; + + if (*buflen < KEY_SIZE) + { + *buflen= KEY_SIZE; + return ENCRYPTION_KEY_BUFFER_TOO_SMALL; + } + *buflen= KEY_SIZE; + if (!dstbuf) + return 0; + + memset(dstbuf, 0, KEY_SIZE); + mi_int4store(dstbuf, version); + return 0; +} + +struct st_mariadb_encryption debug_key_management_plugin= { + MariaDB_ENCRYPTION_INTERFACE_VERSION, + get_latest_key_version, + get_key, + 0, 0 // use default encrypt/decrypt functions +}; + +/* + Plugin library descriptor +*/ +maria_declare_plugin(debug_key_management) +{ + MariaDB_ENCRYPTION_PLUGIN, + &debug_key_management_plugin, + "debug_key_management", + "Sergei Golubchik", + "Debug key management plugin", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + sysvars, + "1.0", + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; diff --git a/plugin/example_key_management/CMakeLists.txt b/plugin/example_key_management/CMakeLists.txt new file mode 100644 index 00000000000..fe893e5368e --- /dev/null +++ b/plugin/example_key_management/CMakeLists.txt @@ -0,0 +1,2 @@ +MYSQL_ADD_PLUGIN(EXAMPLE_KEY_MANAGEMENT example_key_management_plugin.cc + MODULE_ONLY COMPONENT Test) diff --git a/plugin/example_key_management/example_key_management_plugin.cc b/plugin/example_key_management/example_key_management_plugin.cc new file mode 100644 index 00000000000..8bd6138364f --- /dev/null +++ b/plugin/example_key_management/example_key_management_plugin.cc @@ -0,0 +1,146 @@ +/* + Copyright (c) 2014 Google Inc. + Copyright (c) 2014, 2015 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + Example key management plugin. It demonstrates how to return + keys on request, how to change them. That the engine can have + different pages in the same tablespace encrypted with different keys + and what the background re-encryption thread does. + + It does not support different key ids, for all ids the key will be the same. + + THIS IS AN EXAMPLE ONLY! ENCRYPTION KEYS ARE HARD-CODED AND *NOT* SECRET! + DO NOT USE THIS PLUGIN IN PRODUCTION! EVER! +*/ + +#include +#include +#include +#include +#include + +/* rotate key randomly between 45 and 90 seconds */ +#define KEY_ROTATION_MIN 45 +#define KEY_ROTATION_MAX 90 + +static struct my_rnd_struct seed; +static unsigned int key_version = 0; +static unsigned int next_key_version = 0; +static pthread_mutex_t mutex; + +static unsigned int +get_latest_key_version(unsigned int key_id) +{ + uint now = time(0); + pthread_mutex_lock(&mutex); + if (now >= next_key_version) + { + key_version = now; + unsigned int interval = KEY_ROTATION_MAX - KEY_ROTATION_MIN; + next_key_version = now + KEY_ROTATION_MIN + my_rnd(&seed) * interval; + } + pthread_mutex_unlock(&mutex); + + return key_version; +} + +static unsigned int +get_key(unsigned int key_id, unsigned int version, + unsigned char* dstbuf, unsigned *buflen) +{ + if (*buflen < MY_MD5_HASH_SIZE) + { + *buflen= MY_MD5_HASH_SIZE; + return ENCRYPTION_KEY_BUFFER_TOO_SMALL; + } + *buflen= MY_MD5_HASH_SIZE; + if (!dstbuf) + return 0; + + my_md5(dstbuf, (const char*)&version, sizeof(version)); + + return 0; +} + +/* + for the sake of an example, let's use different encryption algorithms/modes + for different keys. +*/ +int encrypt(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int keyid, unsigned int key_version) +{ + return ((key_version & 1) ? my_aes_encrypt_cbc : my_aes_encrypt_ecb) + (src, slen, dst, dlen, key, klen, iv, ivlen, no_padding); +} + +int decrypt(const unsigned char* src, unsigned int slen, + unsigned char* dst, unsigned int* dlen, + const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int no_padding, unsigned int keyid, unsigned int key_version) +{ + return ((key_version & 1) ? my_aes_decrypt_cbc : my_aes_decrypt_ecb) + (src, slen, dst, dlen, key, klen, iv, ivlen, no_padding); +} + +static int example_key_management_plugin_init(void *p) +{ + /* init */ + my_rnd_init(&seed, time(0), 0); + pthread_mutex_init(&mutex, NULL); + get_latest_key_version(1); + + return 0; +} + +static int example_key_management_plugin_deinit(void *p) +{ + pthread_mutex_destroy(&mutex); + return 0; +} + +struct st_mariadb_encryption example_key_management_plugin= { + MariaDB_ENCRYPTION_INTERFACE_VERSION, + get_latest_key_version, + get_key, + encrypt, + decrypt +}; + +/* + Plugin library descriptor +*/ +maria_declare_plugin(example_key_management) +{ + MariaDB_ENCRYPTION_PLUGIN, + &example_key_management_plugin, + "example_key_management", + "Jonas Oreland", + "Example key management plugin", + PLUGIN_LICENSE_GPL, + example_key_management_plugin_init, + example_key_management_plugin_deinit, + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; diff --git a/plugin/example_key_management_plugin/CMakeLists.txt b/plugin/example_key_management_plugin/CMakeLists.txt deleted file mode 100644 index 250f77856c0..00000000000 --- a/plugin/example_key_management_plugin/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -IF(HAVE_EncryptAes128Ctr) - MYSQL_ADD_PLUGIN(EXAMPLE_KEY_MANAGEMENT_PLUGIN example_key_management_plugin.cc - MODULE_ONLY) -ENDIF() diff --git a/plugin/example_key_management_plugin/example_key_management_plugin.cc b/plugin/example_key_management_plugin/example_key_management_plugin.cc deleted file mode 100644 index 580e9ea7091..00000000000 --- a/plugin/example_key_management_plugin/example_key_management_plugin.cc +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2014 Google Inc. - -#include -#include -#include -#include -#include -#include -#include "sql_class.h" - -/* rotate key randomly between 45 and 90 seconds */ -#define KEY_ROTATION_MIN 45 -#define KEY_ROTATION_MAX 90 - -static struct my_rnd_struct seed; -static unsigned int key_version = 0; -static unsigned int next_key_version = 0; -static pthread_mutex_t mutex; - -static unsigned int -get_latest_key_version() -{ - uint now = time(0); - pthread_mutex_lock(&mutex); - if (now >= next_key_version) - { - key_version = now; - unsigned int interval = KEY_ROTATION_MAX - KEY_ROTATION_MIN; - next_key_version = now + KEY_ROTATION_MIN + my_rnd(&seed) * interval; - } - pthread_mutex_unlock(&mutex); - - return key_version; -} - -static int -get_key(unsigned int version, unsigned char* dstbuf, unsigned buflen) -{ - char *dst = (char*)dstbuf; // md5 function takes char* as argument... - unsigned len = 0; - for (; len + MD5_HASH_SIZE <= buflen; len += MD5_HASH_SIZE) - { - compute_md5_hash(dst, (const char*)&version, sizeof(version)); - dst += MD5_HASH_SIZE; - version++; - } - if (len < buflen) - { - memset(dst, 0, buflen - len); - } - return 0; -} - -static unsigned int has_key_func(unsigned int keyID) -{ - return true; -} - -static unsigned int get_key_size(unsigned int keyID) -{ - return 16; -} - -static int get_iv(unsigned int keyID, unsigned char* dstbuf, unsigned buflen) -{ - if (buflen < 16) - { - return CRYPT_BUFFER_TO_SMALL; - } - - for (int i=0; i<16; i++) - dstbuf[i] = 0; - - return CRYPT_KEY_OK; -} - - -static int example_key_management_plugin_init(void *p) -{ - /* init */ - my_rnd_init(&seed, time(0), 0); - get_latest_key_version(); - - if (current_aes_dynamic_method == MY_AES_ALGORITHM_NONE) - { - sql_print_error("No encryption method choosen with --encryption-algorithm. " - "example_key_management_plugin disabled"); - return 1; - } - - my_aes_init_dynamic_encrypt(current_aes_dynamic_method); - - pthread_mutex_init(&mutex, NULL); - - return 0; -} - -static int example_key_management_plugin_deinit(void *p) -{ - pthread_mutex_destroy(&mutex); - return 0; -} - -struct st_mariadb_encryption_key_management example_key_management_plugin= { - MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION, - get_latest_key_version, - has_key_func, - get_key_size, - get_key, - get_iv -}; - -/* - Plugin library descriptor -*/ -maria_declare_plugin(example_key_management_plugin) -{ - MariaDB_ENCRYPTION_KEY_MANAGEMENT_PLUGIN, - &example_key_management_plugin, - "example_key_management_plugin", - "Jonas Oreland", - "Example key management plugin", - PLUGIN_LICENSE_GPL, - example_key_management_plugin_init, - example_key_management_plugin_deinit, - 0x0100 /* 1.0 */, - NULL, /* status variables */ - NULL, /* system variables */ - "1.0", - MariaDB_PLUGIN_MATURITY_EXPERIMENTAL -} -maria_declare_plugin_end; diff --git a/plugin/file_key_management/CMakeLists.txt b/plugin/file_key_management/CMakeLists.txt new file mode 100644 index 00000000000..c2f13fb9f63 --- /dev/null +++ b/plugin/file_key_management/CMakeLists.txt @@ -0,0 +1,4 @@ +SET(FILE_KEY_MANAGEMENT_PLUGIN_SOURCES file_key_management_plugin.cc parser.cc) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) +MYSQL_ADD_PLUGIN(FILE_KEY_MANAGEMENT ${FILE_KEY_MANAGEMENT_PLUGIN_SOURCES}) diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc new file mode 100644 index 00000000000..08c0c9b74c8 --- /dev/null +++ b/plugin/file_key_management/file_key_management_plugin.cc @@ -0,0 +1,161 @@ +/* Copyright (c) 2002, 2012, eperi GmbH. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + +#include "parser.h" +#include +#include + +static char* filename; +static char* filekey; +static unsigned long encryption_algorithm; + +static const char *encryption_algorithm_names[]= +{ + "aes_cbc", +#ifdef HAVE_EncryptAes128Ctr + "aes_ctr", +#endif + 0 +}; + +static TYPELIB encryption_algorithm_typelib= +{ + array_elements(encryption_algorithm_names)-1,"", + encryption_algorithm_names, NULL +}; + + +static MYSQL_SYSVAR_STR(filename, filename, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Path and name of the key file.", + NULL, NULL, ""); + +static MYSQL_SYSVAR_STR(filekey, filekey, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Key to encrypt / decrypt the keyfile.", + NULL, NULL, ""); + +static MYSQL_SYSVAR_ENUM(encryption_algorithm, encryption_algorithm, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Encryption algorithm to use.", + NULL, NULL, 0, &encryption_algorithm_typelib); + +static struct st_mysql_sys_var* settings[] = { + MYSQL_SYSVAR(filename), + MYSQL_SYSVAR(filekey), + MYSQL_SYSVAR(encryption_algorithm), + NULL +}; + +Dynamic_array keys(static_cast(0)); + +static keyentry *get_key(unsigned int key_id) +{ + keyentry *a= keys.front(), *b= keys.back() + 1, *c; + while (b - a > 1) + { + c= a + (b - a)/2; + if (c->id == key_id) + return c; + else if (c->id < key_id) + a= c; + else + b= c; + } + return a->id == key_id ? a : 0; +} + +/* the version is always the same, no automatic key rotation */ +static unsigned int get_latest_version(uint key_id) +{ + return get_key(key_id) ? 1 : ENCRYPTION_KEY_VERSION_INVALID; +} + +static unsigned int get_key_from_key_file(unsigned int key_id, + unsigned int key_version, unsigned char* dstbuf, unsigned *buflen) +{ + if (key_version != 1) + return ENCRYPTION_KEY_VERSION_INVALID; + + keyentry* entry = get_key(key_id); + + if (entry == NULL) + return ENCRYPTION_KEY_VERSION_INVALID; + + if (*buflen < entry->length) + { + *buflen= entry->length; + return ENCRYPTION_KEY_BUFFER_TOO_SMALL; + } + + *buflen= entry->length; + if (dstbuf) + memcpy(dstbuf, entry->key, entry->length); + + return 0; +} + +struct st_mariadb_encryption file_key_management_plugin= { + MariaDB_ENCRYPTION_INTERFACE_VERSION, + get_latest_version, + get_key_from_key_file, + 0,0 +}; + +static int file_key_management_plugin_init(void *p) +{ + Parser parser(filename, filekey); + switch (encryption_algorithm) { + case 0: // AES_CBC + file_key_management_plugin.encrypt= + (encrypt_decrypt_func)my_aes_encrypt_cbc; + file_key_management_plugin.decrypt= + (encrypt_decrypt_func)my_aes_decrypt_cbc; + break; +#ifdef HAVE_EncryptAes128Ctr + case 1: // AES_CTR + file_key_management_plugin.encrypt= + (encrypt_decrypt_func)my_aes_encrypt_ctr; + file_key_management_plugin.decrypt= + (encrypt_decrypt_func)my_aes_decrypt_ctr; + break; +#endif + default: + return 1; // cannot happen + } + return parser.parse(&keys); +} + +/* + Plugin library descriptor +*/ +maria_declare_plugin(file_key_management) +{ + MariaDB_ENCRYPTION_PLUGIN, + &file_key_management_plugin, + "file_key_management", + "Denis Endro eperi GmbH", + "File-based key management plugin", + PLUGIN_LICENSE_GPL, + file_key_management_plugin_init, + NULL, + 0x0100 /* 1.0 */, + NULL, /* status variables */ + settings, + "1.0", + MariaDB_PLUGIN_MATURITY_ALPHA +} +maria_declare_plugin_end; diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc new file mode 100644 index 00000000000..1a2d48c2471 --- /dev/null +++ b/plugin/file_key_management/parser.cc @@ -0,0 +1,365 @@ +/* Copyright (C) 2014 eperi GmbH. + Copyright (C) 2015 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/******************************************************************//** + @file Parser.cc + A class to parse the key file + +How it works... +The location and usage can be configured via the configuration file. +Example + +[mysqld] +... +file_key_management_filename = /home/mdb/keys.enc +file_key_management_filekey = secret +... + +The keys are read from a file. +The filename is set up via the file_key_management_filename +configuration value. +file_key_management_filename is used to configure the absolute +path to this file. + +Examples: +file_key_management_filename = \\\\unc\\keys.enc (windows share) +file_key_management_filename = e:/tmp/keys.enc (windows path) +file_key_management_filename = /tmp/keys.enc (linux path) + +The key file contains AES keys as hex-encoded strings. +Supported are keys of size 128, 192 or 256 bits. +Example: +1;F5502320F8429037B8DAEF761B189D12 +2;770A8A65DA156D24EE2A093277530142770A8A65DA156D24EE2A093277530142 + +1 is the key identifier which can be used for table creation, +it is followed by a AES key + +The key file could be encrypted and the key to decrypt the file can +be given with the optional file_key_management_filekey +parameter. + +The file key can also be located if FILE: is prepended to the +key. Then the following part is interpreted as absolute path to the +file containing the file key (which must be a text - not binary - string). + +Example: + +file_key_management_filekey = FILE:y:/secret256.enc + +If the key file can not be read at server startup, for example if the +file key is not present, the plugin will not start +access to encrypted tables will not be possible. + +Open SSL command line utility can be used to create an encrypted key file. +Example: +openssl enc -aes-256-cbc -md sha1 -k "secret" -in keys.txt -out keys.enc +***********************************************************************/ + +#include "parser.h" +#include +#include + +#define FILE_PREFIX "FILE:" +#define MAX_KEY_FILE_SIZE 1024*1024 +#define MAX_SECRET_SIZE 256 + +/* + The values below are what one gets after + openssl enc -aes-256-cbc -md sha1 -k "secret" -in keys.txt -out keys.enc +*/ +#define OpenSSL_prefix "Salted__" +#define OpenSSL_prefix_len (sizeof(OpenSSL_prefix) - 1) +#define OpenSSL_salt_len 8 +#define OpenSSL_key_len 32 +#define OpenSSL_iv_len 16 + +/** + Calculate key and iv from a given salt and secret as in the + openssl command-line tool + + @param salt [in] the given salt as extracted from the encrypted file + @param secret [in] the given secret as String, provided by the user + @param key [out] 32 Bytes of key are written to this pointer + @param iv [out] 16 Bytes of iv are written to this pointer + + Note, that in openssl this whole function can be reduced to + + #include + EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, + secret, strlen(secret), 1, key, iv); + + but alas! we want to support yassl too +*/ + +void Parser::bytes_to_key(const unsigned char *salt, const char *input, + unsigned char *key, unsigned char *iv) +{ + unsigned char digest[MY_SHA1_HASH_SIZE]; + int key_left = OpenSSL_key_len; + int iv_left = OpenSSL_iv_len; + const size_t ilen= strlen(input); + const size_t slen= OpenSSL_salt_len; // either this or explicit (size_t) casts below + + my_sha1_multi(digest, input, ilen, salt, slen, NullS); + + while (iv_left) + { + int left= MY_SHA1_HASH_SIZE; + if (key_left) + { + int store = MY_MIN(key_left, MY_SHA1_HASH_SIZE); + memcpy(&key[OpenSSL_key_len - key_left], digest, store); + + key_left -= store; + left -= store; + } + + if (iv_left && left) + { + int store= MY_MIN(iv_left, left); + memcpy(&iv[OpenSSL_iv_len - iv_left], &digest[MY_SHA1_HASH_SIZE - left], store); + + iv_left -= store; + } + + if (iv_left) + my_sha1_multi(digest, digest, MY_SHA1_HASH_SIZE, + input, ilen, salt, slen, NullS); + } +} + + +bool Parser::parse(Dynamic_array *keys) +{ + const char *secret= filekey; + char buf[MAX_SECRET_SIZE + 1]; + + //If secret starts with FILE: interpret the secret as a filename. + if (is_prefix(filekey, FILE_PREFIX)) + { + if (read_filekey(filekey + sizeof(FILE_PREFIX) - 1, buf)) + return 1; + secret= buf; + } + + return parse_file(keys, secret); +} + + +/* + secret is limited to MAX_SECRET_SIZE characters +*/ + +bool Parser::read_filekey(const char *filekey, char *secret) +{ + int f= my_open(filekey, O_RDONLY, MYF(MY_WME)); + if (f == -1) + return 1; + int len= my_read(f, (uchar*)secret, MAX_SECRET_SIZE, MYF(MY_WME)); + my_close(f, MYF(MY_WME)); + if (len <= 0) + return 1; + secret[len]= '\0'; + return 0; +} + +static int sort_keys(const keyentry *k1, const keyentry *k2) +{ + return k1->id < k2->id ? -1 : k1->id > k2->id; +} + +/** + Get the keys from the key file and decrypt it with the + key . Store the keys with id smaller then in an + array of structs keyentry. + + @return 0 when ok, 1 for an error + */ + +bool Parser::parse_file(Dynamic_array *keys, const char *secret) +{ + char *buffer= read_and_decrypt_file(secret); + + if (!buffer) + return 1; + + keyentry key; + char *line=buffer; + + while (*line) + { + line_number++; + switch (parse_line(&line, &key)) { + case 1: // comment + break; + case -1: // error + my_free(buffer); + return 1; + case 0: + if (keys->push(key)) + return 1; + break; + } + } + + keys->sort(sort_keys); + + my_free(buffer); + return 0; +} + +void Parser::report_error(const char *reason, uint position) +{ + my_printf_error(EE_READ, "%s at %s line %u, column %u", + MYF(ME_NOREFRESH), reason, filename, line_number, position + 1); +} + +/* + return 0 - new key + 1 - comment + -1 - error +*/ +int Parser::parse_line(char **line_ptr, keyentry *key) +{ + int res= 1; + char *p= *line_ptr; + while (isspace(*p) && *p != '\n') p++; + if (*p != '#' && *p != '\n') + { + int error; + p+= 100; // the number will surely end here (on a non-digit or with an overflow) + longlong id= my_strtoll10(p - 100, &p, &error); + if (error) + { + report_error("Syntax error", p - *line_ptr); + return -1; + } + + if (id < 1 || id > UINT_MAX32) + { + report_error("Invalid key id", p - *line_ptr); + return -1; + } + + if (*p != ';') + { + report_error("Syntax error", p - *line_ptr); + return -1; + } + + p++; + key->id= id; + key->length=0; + while (isxdigit(p[0]) && isxdigit(p[1]) && key->length < sizeof(key->key)) + { + key->key[key->length++] = from_hex(p[0]) * 16 + from_hex(p[1]); + p+=2; + } + if (isxdigit(*p) || + (key->length != 16 && key->length != 24 && key->length != 32)) + { + report_error("Invalid key", p - *line_ptr); + return -1; + } + + res= 0; + } + while (*p && *p != '\n') p++; + *line_ptr= *p == '\n' ? p + 1 : p; + return res; +} + +/** + Decrypt the key file 'filename' if it is encrypted with the key + 'secret'. Store the content of the decrypted file in 'buffer'. The + buffer has to be freed in the calling function. + */ + +char* Parser::read_and_decrypt_file(const char *secret) +{ + int f= my_open(filename, O_RDONLY, MYF(MY_WME)); + if (f < 0) + goto err0; + + my_off_t file_size; + file_size= my_seek(f, 0, SEEK_END, MYF(MY_WME)); + + if (file_size == MY_FILEPOS_ERROR) + goto err1; + + if (file_size > MAX_KEY_FILE_SIZE) + { + my_error(EE_READ, MYF(0), filename, EFBIG); + goto err1; + } + + //Read file into buffer + uchar *buffer; + buffer= (uchar*)my_malloc(file_size + 1, MYF(MY_WME)); + if (!buffer) + goto err1; + + if (my_pread(f, buffer, file_size, 0, MYF(MY_WME)) != file_size) + goto err2; + +// Check for file encryption + uchar *decrypted; + if (is_prefix((char*)buffer, OpenSSL_prefix)) + { + uchar key[OpenSSL_key_len]; + uchar iv[OpenSSL_iv_len]; + + decrypted= (uchar*)my_malloc(file_size, MYF(MY_WME)); + if (!decrypted) + goto err2; + + bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv); + uint32 d_size; + if (my_aes_decrypt_cbc(buffer + OpenSSL_prefix_len + OpenSSL_salt_len, + file_size - OpenSSL_prefix_len - OpenSSL_salt_len, + decrypted, &d_size, key, OpenSSL_key_len, + iv, OpenSSL_iv_len, 0)) + + { + my_printf_error(EE_READ, "Cannot decrypt %s. Wrong key?", MYF(ME_NOREFRESH), filename); + goto err3; + } + + my_free(buffer); + buffer= decrypted; + file_size= d_size; + } + else if (*secret) + { + my_printf_error(EE_READ, "Cannot decrypt %s. Not encrypted", MYF(ME_NOREFRESH), filename); + goto err2; + } + + buffer[file_size]= '\0'; + my_close(f, MYF(MY_WME)); + return (char*) buffer; + +err3: + my_free(decrypted); +err2: + my_free(buffer); +err1: + my_close(f, MYF(MY_WME)); +err0: + return NULL; +} + diff --git a/plugin/file_key_management/parser.h b/plugin/file_key_management/parser.h new file mode 100644 index 00000000000..c8349db70a0 --- /dev/null +++ b/plugin/file_key_management/parser.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2014 eperi GmbH. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/******************************************************************//** +@file Parser.h +A structure and class to keep keys for encryption/decryption. + +Created 09/15/2014 +***********************************************************************/ + +#include +#include +#include + +struct keyentry { + unsigned int id; + unsigned char key[MY_AES_MAX_KEY_LENGTH]; + unsigned int length; +}; + +class Parser +{ + const char *filename; + const char *filekey; + unsigned int line_number; + + unsigned int from_hex(char c) + { return c <= '9' ? c - '0' : tolower(c) - 'a' + 10; } + + void bytes_to_key(const unsigned char *salt, const char *secret, + unsigned char *key, unsigned char *iv); + bool read_filekey(const char *filekey, char *secret); + bool parse_file(Dynamic_array *keys, const char *secret); + void report_error(const char *reason, unsigned int position); + int parse_line(char **line_ptr, keyentry *key); + char* read_and_decrypt_file(const char *secret); + +public: + Parser(const char* fn, const char *fk) : + filename(fn), filekey(fk), line_number(0) { } + bool parse(Dynamic_array *keys); +}; diff --git a/plugin/file_key_management_plugin/CMakeLists.txt b/plugin/file_key_management_plugin/CMakeLists.txt deleted file mode 100644 index 8a0429e979e..00000000000 --- a/plugin/file_key_management_plugin/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -SET(FILE_KEY_MANAGEMENT_PLUGIN_SOURCES file_key_management_plugin.cc EncKeys.cc KeySingleton.cc) - -IF(NOT SSL_SOURCES) - MYSQL_ADD_PLUGIN(FILE_KEY_MANAGEMENT_PLUGIN ${FILE_KEY_MANAGEMENT_PLUGIN_SOURCES} - LINK_LIBRARIES pcre) -ENDIF() diff --git a/plugin/file_key_management_plugin/EncKeys.cc b/plugin/file_key_management_plugin/EncKeys.cc deleted file mode 100644 index 266a88d2c3f..00000000000 --- a/plugin/file_key_management_plugin/EncKeys.cc +++ /dev/null @@ -1,479 +0,0 @@ -/* Copyright (C) 2014 eperi GmbH. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** - @file EncKeys.cc - A class to keep keys for encryption/decryption. - -How it works... -The location and usage can be configured via the configuration file. -Example - -[mysqld] -... -file_key_management_plugin_filename = /home/mdb/keys.enc -file_key_management_plugin_filekey = secret -file_key_management_plugin_encryption_method = aes_cbc - -... - -Optional configuration value -file_key_management_plugin_encryption_method determines the method -used for encryption. -Supported are aes_cbc, aes_ecb or aes_ctr. aes_cbc is default. -The plug-in sets the default aes encryption/decryption method to the given method. - -The keys are read from a file. -The filename is set up via the file_key_management_plugin_filename -configuration value. -file_key_management_plugin_filename is used to configure the absolute -path to this file. - -Examples: -file_key_management_plugin_filename = \\\\unc\\keys.enc (windows share) -file_key_management_plugin_filename = e:/tmp/keys.enc (windows path) -file_key_management_plugin_filename = /tmp/keys.enc (linux path) - -The key file contains AES keys and initialization vectors as -hex-encoded Strings. -Supported are keys of size 128, 192 or 256 bits. IV consists of 16 bytes. -Example: -1;F5502320F8429037B8DAEF761B189D12;770A8A65DA156D24EE2A093277530142 - -1 is the key identifier which can be used for table creation, a 16 -byte IV follows, and finally a 16 byte AES key. -255 entries are supported. - -The key file should be encrypted and the key to decrypt the file can -be given with the optional file_key_management_plugin_filekey -parameter. - -The file key can also be located if FILE: is prepended to the -key. Then the following part is interpreted as absolute path to the -file containing the file key. This file can optionally be encrypted, -currently with a fix key. - -Example: - -file_key_management_plugin_filekey = FILE:y:/secret256.enc - -If the key file can not be read at server startup, for example if the -file key is not present, page_encryption feature is not availabe and -access to page_encryption tables is not possible. - -Open SSL command line utility can be used to create an encrypted key file. -Examples: -openssl enc –aes-256-cbc –md sha1 –k secret –in keys.txt –out keys.enc -openssl enc –aes-256-cbc –md sha1 –k –in secret –out secret.enc - - Created 09/15/2014 -***********************************************************************/ - -#ifdef __WIN__ -#define PCRE_STATIC 1 -#endif - -#include -#include /* For sql_print_error */ -#include "EncKeys.h" -#include -#include -#include -#include -#include -#include - -const char* EncKeys::strMAGIC= "Salted__"; -const int EncKeys::magicSize= 8;//strlen(strMAGIC); // 8 byte -const char* EncKeys::newLine= "\n"; - -const char* EncKeys::errorNoKeyId= "KeyID %u not found or with error. Check the key and the log file.\n"; -const char* EncKeys::errorInMatches= "Wrong match of the keyID in line %u, see the template.\n"; -const char* EncKeys::errorExceedKeyFileSize= "The size of the key file %s exceeds " - "the maximum allowed of %u bytes.\n"; -const char* EncKeys::errorExceedKeySize= "The key size exceeds the maximum allowed size of %u in line %u.\n"; -const char* EncKeys::errorEqualDoubleKey= "More than one identical key with keyID %u found" - " in lines %u and %u.\nDelete one of them in the key file.\n"; -const char* EncKeys::errorUnequalDoubleKey= "More than one not identical key with keyID %u found" - " in lines %u and %u.\nChoose the right one and delete the other in the key file.\n" - "I'll take the key from line %u\n"; -#define errorNoInitializedKey "The key could not be initialized.\n" -const char* EncKeys::errorNotImplemented= "Initializing keys through key server is not" - " yet implemented.\nYou can not read encrypted tables or columns\n\n"; -const char* EncKeys::errorOpenFile= "Could not open %s for reading. You can not read encrypted tables or columns.\n\n"; -const char* EncKeys::errorReadingFile= "Could not read from %s. You can not read encrypted tables or columns\n\n"; -const char* EncKeys::errorFileSize= "Could not get the file size from %s. You can not read encrypted tables or columns\n\n"; -const char* EncKeys::errorFalseFileKey= "Wrong encryption / decryption key for keyfile '%s'.\n"; - -/* read this from a secret source in some later version */ -const char* EncKeys::initialPwd= "lg28s9ac5ffa537fd8798875c98e190df289da7e047c05"; - -EncKeys::EncKeys() -{ - countKeys= keyLineInKeyFile= 0; - for (int ii= 0; ii < MAX_KEYS; ii++) { - keys[ii].id= 0; - keys[ii].iv= keys[ii].key= NULL; - } - oneKey= NULL; -} - - -EncKeys::~EncKeys() -{ - for (int ii= MAX_KEYS - 1; ii >= 0 ; ii--) { - delete[] keys[ii].iv; - keys[ii].iv= NULL; - delete[] keys[ii].key; - keys[ii].key= NULL; - } -} - - -bool EncKeys::initKeys(const char *filename, const char *filekey) -{ - if (filename==NULL) - return false; - - const char *MAGIC= "FILE:"; - const short MAGIC_LEN= 5; - - char *secret= (char*) malloc(MAX_SECRET_SIZE +1 * sizeof(char)); - - if (filekey != NULL) - { - //If secret starts with FILE: interpret the secret as filename. - if(memcmp(MAGIC, filekey, MAGIC_LEN) == 0) - { - int fk_len= strlen(filekey); - char *secretfile= (char*)malloc((1 + fk_len - MAGIC_LEN)* sizeof(char)); - memcpy(secretfile, filekey+MAGIC_LEN, fk_len - MAGIC_LEN); - secretfile[fk_len-MAGIC_LEN]= '\0'; - parseSecret(secretfile, secret); - free(secretfile); - } else - { - sprintf(secret, "%s", filekey); - } - } - - int ret= parseFile((const char *)filename, 254, secret); - free(secret); - return (ret==NO_ERROR_KEY_FILE_PARSE_OK); -} - - -/* - secret is limited to MAX_SECRET_SIZE characters -*/ - -void EncKeys::parseSecret(const char *secretfile, char *secret) -{ - size_t maxSize= (MAX_SECRET_SIZE +16 + magicSize*2) ; - char* buf= (char*)malloc((maxSize) * sizeof(char)); - char* _initPwd= (char*)malloc((strlen(initialPwd)+1) * sizeof(char)); - FILE *fp= fopen(secretfile, "rb"); - fseek(fp, 0L, SEEK_END); - long file_size= ftell(fp); - rewind(fp); - size_t bytes_to_read= ((maxSize >= (size_t) file_size) ? (size_t) file_size : - maxSize); - bytes_to_read= fread(buf, 1, bytes_to_read, fp); - if (memcmp(buf, strMAGIC, magicSize)) - { - bytes_to_read= (bytes_to_read>MAX_SECRET_SIZE) ? MAX_SECRET_SIZE : - bytes_to_read; - memcpy(secret, buf, bytes_to_read); - secret[bytes_to_read]= '\0'; - } - else - { - unsigned char salt[magicSize]; - unsigned char *key= new unsigned char[keySize32]; - unsigned char *iv= new unsigned char[ivSize16]; - memcpy(&salt, buf + magicSize, magicSize); - memcpy(_initPwd, initialPwd, strlen(initialPwd)); - _initPwd[strlen(initialPwd)]= '\0'; - my_bytes_to_key((unsigned char *) salt, _initPwd, key, iv); - uint32 d_size= 0; - my_aes_decrypt_dynamic_type func= get_aes_decrypt_func(MY_AES_ALGORITHM_CBC); - int re= (* func)((const uchar*)buf + 2 * magicSize, - bytes_to_read - 2 * magicSize, - (uchar*)secret, &d_size, (const uchar*)key, keySize32, - iv, ivSize16, 0); - if (re) - d_size= 0; - if (d_size>EncKeys::MAX_SECRET_SIZE) - { - d_size= EncKeys::MAX_SECRET_SIZE; - } - secret[d_size]= '\0'; - delete[] key; - delete[] iv; - } - free(buf); - free(_initPwd); - fclose(fp); -} - - -/** - * Returns a struct keyentry with the asked 'id' or NULL. - */ -keyentry *EncKeys::getKeys(int id) -{ - if (KEY_MIN <= id && KEY_MAX >= id && (&keys[id - 1])->iv) - { - return &keys[id - 1]; - } -#ifndef DBUG_OFF - else - { - sql_print_error(errorNoKeyId, id); - } -#endif - return NULL; -} - -/** - Get the keys from the key file and decrypt it with the - key . Store the keys with id smaller then in an - array of structs keyentry. Returns NO_ERROR_PARSE_OK or an - appropriate error code. - */ - -int EncKeys::parseFile(const char* filename, const uint32 maxKeyId, - const char *secret) -{ - int errorCode= 0; - char *buffer= decryptFile(filename, secret, &errorCode); - uint32 id= 0; - - if (errorCode != NO_ERROR_PARSE_OK) - return errorCode; - errorCode= NO_ERROR_KEY_FILE_PARSE_OK; - - char *line= strtok(buffer, newLine); - while (NULL != line) - { - keyLineInKeyFile++; - switch (parseLine(line, maxKeyId)) { - case NO_ERROR_PARSE_OK: - id= oneKey->id; - keys[oneKey->id - 1]= *oneKey; - delete(oneKey); - countKeys++; - break; - case ERROR_ID_TOO_BIG: - sql_print_error(errorExceedKeySize, KEY_MAX, - keyLineInKeyFile); - sql_print_error(" ---> %s\n", line); - errorCode= ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS; - break; - case ERROR_NOINITIALIZEDKEY: - sql_print_error(errorNoInitializedKey); - sql_print_error(" ----> %s\n", line); - errorCode= ERROR_KEY_FILE_PARSE_NULL; - break; - case ERROR_WRONG_NUMBER_OF_MATCHES: - sql_print_error(errorInMatches, keyLineInKeyFile); - sql_print_error(" -----> %s\n", line); - errorCode= ERROR_KEY_FILE_PARSE_NULL; - break; - case NO_ERROR_KEY_GREATER_THAN_ASKED: - sql_print_error("No asked key in line %u: %s\n", - keyLineInKeyFile, line); - break; - case NO_ERROR_ISCOMMENT: - sql_print_error("Is comment in line %u: %s\n", - keyLineInKeyFile, line); - default: - break; - } - line= strtok(NULL, newLine); - } - - free(line); - line= NULL; - delete[] buffer; - buffer= NULL; - return errorCode; -} - - -int EncKeys::parseLine(const char *line, const uint32 maxKeyId) -{ - int ret= NO_ERROR_PARSE_OK; - if (isComment(line)) - ret= NO_ERROR_ISCOMMENT; - else - { - const char *error_p= NULL; - int offset; - pcre *pattern= pcre_compile( - "([0-9]+);([0-9,a-f,A-F]{32});([0-9,a-f,A-F]{64}|[0-9,a-f,A-F]{48}|[0-9,a-f,A-F]{32})", - 0, &error_p, &offset, NULL); - if (NULL != error_p) - sql_print_error("Error: %s\nOffset: %d\n", error_p, offset); - - int m_len= (int) strlen(line), ovector[MAX_OFFSETS_IN_PCRE_PATTERNS]; - int rc= pcre_exec(pattern, NULL, line, m_len, 0, 0, ovector, - MAX_OFFSETS_IN_PCRE_PATTERNS); - pcre_free(pattern); - if (4 == rc) - { - char lin[MAX_KEY_LINE_SIZE + 1]; - strncpy(lin, line, MAX_KEY_LINE_SIZE); - lin[MAX_KEY_LINE_SIZE]= '\0'; - char *substring_start= lin + ovector[2]; - int substr_length= ovector[3] - ovector[2]; - if (3 < substr_length) - ret= ERROR_ID_TOO_BIG; - else - { - char buffer[4]; - sprintf(buffer, "%.*s", substr_length, substring_start); - uint32 id= atoi(buffer); - if (0 == id) ret= ERROR_NOINITIALIZEDKEY; - else if (KEY_MAX < id) ret= ERROR_ID_TOO_BIG; - else if (maxKeyId < id) ret= NO_ERROR_KEY_GREATER_THAN_ASKED; - else - { - oneKey= new keyentry; - oneKey->id= id; - substring_start= lin + ovector[4]; - substr_length= ovector[5] - ovector[4]; - oneKey->iv= new char[substr_length + 1]; - sprintf(oneKey->iv, "%.*s", substr_length, substring_start); - substring_start= lin + ovector[6]; - substr_length= ovector[7] - ovector[6]; - oneKey->key= new char[substr_length + 1]; - sprintf(oneKey->key, "%.*s", substr_length, substring_start); - } - } - } - else - ret= ERROR_WRONG_NUMBER_OF_MATCHES; - } - return ret; -} - -/** - Decrypt the key file 'filename' if it is encrypted with the key - 'secret'. Store the content of the decrypted file in 'buffer'. The - buffer has to be freed in the calling function. - */ - -char* EncKeys::decryptFile(const char* filename, const char *secret, - int *errorCode) -{ - *errorCode= NO_ERROR_PARSE_OK; - FILE *fp= fopen(filename, "rb"); - if (NULL == fp) - { - sql_print_error(errorOpenFile, filename); - *errorCode= ERROR_OPEN_FILE; - return NULL; - } - - if (fseek(fp, 0L, SEEK_END)) - { - *errorCode= ERROR_READING_FILE; - return NULL; - } - long file_size= ftell(fp); // get the file size - if (MAX_KEY_FILE_SIZE < file_size) - { - sql_print_error(errorExceedKeyFileSize, filename, MAX_KEY_FILE_SIZE); - *errorCode= ERROR_KEY_FILE_TOO_BIG; - fclose(fp); - return NULL; - } - else if (-1L == file_size) - { - sql_print_error(errorFileSize, filename); - *errorCode= ERROR_READING_FILE; - return NULL; - } - - rewind(fp); - //Read file into buffer - uchar *buffer= new uchar[file_size + 1]; - file_size= fread(buffer, 1, file_size, fp); - buffer[file_size]= '\0'; - fclose(fp); - //Check for file encryption - if (0 == memcmp(buffer, strMAGIC, magicSize)) - { - //If file is encrypted, decrypt it first. - unsigned char salt[magicSize]; - unsigned char *key= new unsigned char[keySize32]; - unsigned char *iv= new unsigned char[ivSize16]; - uchar *decrypted= new uchar[file_size]; - memcpy(&salt, buffer + magicSize, magicSize); - my_bytes_to_key((unsigned char *) salt, secret, key, iv); - uint32 d_size= 0; - my_aes_decrypt_dynamic_type func= get_aes_decrypt_func(MY_AES_ALGORITHM_CBC); - int res= (* func)((const uchar*)buffer + 2 * magicSize, - file_size - 2 * magicSize, - decrypted, &d_size, (const uchar*) key, keySize32, - iv, ivSize16, 0); - if(0 != res) - { - *errorCode= ERROR_FALSE_FILE_KEY; - delete[] buffer; buffer= NULL; - sql_print_error(errorFalseFileKey, filename); - } - else - { - memcpy(buffer, decrypted, d_size); - buffer[d_size]= '\0'; - } - - delete[] decrypted; decrypted= NULL; - delete[] key; key= NULL; - delete[] iv; iv= NULL; - } - return (char*) buffer; -} - -bool EncKeys::isComment(const char *line) -{ - const char *error_p; - int offset, m_len= (int) strlen(line), - ovector[MAX_OFFSETS_IN_PCRE_PATTERNS]; - pcre *pattern= pcre_compile("\\s*#.*", 0, &error_p, &offset, NULL); - int rc= pcre_exec(pattern, NULL, line, m_len, 0, 0, ovector, - MAX_OFFSETS_IN_PCRE_PATTERNS); - pcre_free(pattern); - return (rc >= 0); -} - - -void EncKeys::printKeyEntry(uint32 id) -{ -#ifndef DBUG_OFF - keyentry *entry= getKeys(id); - if (NULL == entry) - { - sql_print_error("No such keyID: %u\n",id); - } - else - { - sql_print_error("Key: id: %3u\tiv:%lu bytes\tkey:%lu bytes\n", - entry->id, strlen(entry->iv)/2, strlen(entry->key)/2); - } -#endif /* DBUG_OFF */ -} diff --git a/plugin/file_key_management_plugin/EncKeys.h b/plugin/file_key_management_plugin/EncKeys.h deleted file mode 100644 index c0ab98b8e9d..00000000000 --- a/plugin/file_key_management_plugin/EncKeys.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (C) 2014 eperi GmbH. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** -@file EncKeys.h -A structure and class to keep keys for encryption/decryption. - -Created 09/15/2014 -***********************************************************************/ - -#ifndef ENCKEYS_H_ -#define ENCKEYS_H_ - -#include -#include -#include - - - - - -struct keyentry { - uint32 id; - char *iv; - char *key; -}; - - -class EncKeys -{ -private: - static const char *strMAGIC, *newLine; - static const int magicSize; - - enum constants { MAX_OFFSETS_IN_PCRE_PATTERNS = 30}; - enum keyAttributes { KEY_MIN = 1, KEY_MAX = 255, MAX_KEYS = 255, - MAX_IVLEN = 256, MAX_KEYLEN = 512, ivSize16 = 16, keySize32 = 32 }; - enum keyInitType { KEYINITTYPE_FILE = 1, KEYINITTYPE_SERVER = 2 }; - enum errorAttributes { MAX_KEY_LINE_SIZE = 3 * MAX_KEYLEN, MAX_KEY_FILE_SIZE = 1048576 }; - enum errorCodesLine { NO_ERROR_PARSE_OK = 0, NO_ERROR_ISCOMMENT = 10, NO_ERROR_KEY_GREATER_THAN_ASKED = 20, - ERROR_NOINITIALIZEDKEY = 30, ERROR_ID_TOO_BIG = 40, ERROR_WRONG_NUMBER_OF_MATCHES = 50, - ERROR_EQUAL_DOUBLE_KEY = 60, ERROR_UNEQUAL_DOUBLE_KEY = 70 }; - - static const char *errorNoKeyId, *errorInMatches, *errorExceedKeyFileSize, - *errorExceedKeySize, *errorEqualDoubleKey, *errorUnequalDoubleKey, - *errorNoInitializedKey, *errorFalseFileKey, - *errorNotImplemented, *errorOpenFile, *errorReadingFile, *errorFileSize; - - static const char* initialPwd; - uint32 countKeys, keyLineInKeyFile; - keyentry keys[MAX_KEYS], *oneKey; - - void printKeyEntry( uint32 id); - bool isComment( const char *line); - char * decryptFile( const char* filename, const char *secret, int *errorCode); - int parseFile( const char* filename, const uint32 maxKeyId, const char *secret); - int parseLine( const char *line, const uint32 maxKeyId); - -public: - static const size_t MAX_SECRET_SIZE = 256; - - enum errorCodesFile { NO_ERROR_KEY_FILE_PARSE_OK = 0, ERROR_KEY_FILE_PARSE_NULL = 110, - ERROR_KEY_FILE_TOO_BIG = 120, ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS = 130, - ERROR_OPEN_FILE = 140, ERROR_READING_FILE = 150, ERROR_FALSE_FILE_KEY = 160, - ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED = 170, ERROR_ENCRYPTION_SECRET_NULL = 180 }; - EncKeys(); - virtual ~EncKeys(); - bool initKeys( const char *filename, const char *filekey); - keyentry *getKeys( int id); - /* made public for unit testing */ - static void parseSecret( const char *filename, char *secret ); - -}; - -#endif /* ENCKEYS_H_ */ diff --git a/plugin/file_key_management_plugin/KeySingleton.cc b/plugin/file_key_management_plugin/KeySingleton.cc deleted file mode 100644 index 936a7cf71a9..00000000000 --- a/plugin/file_key_management_plugin/KeySingleton.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2014 eperi GmbH. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** -@file KeySingleton.cc -Implementation of single pattern to keep keys for encrypting/decrypting pages. - -Created 09/13/2014 -***********************************************************************/ - - -#include -#include -#include "KeySingleton.h" - -bool KeySingleton::instanceInited = false; -KeySingleton KeySingleton::theInstance; -EncKeys KeySingleton::encKeys; - -KeySingleton & KeySingleton::getInstance() -{ -#ifndef DBUG_OFF - if( !instanceInited) - { - sql_print_error("Encryption / decryption keys were not initialized. " - "You can not read encrypted tables or columns\n"); - } -#endif /* DBUG_OFF */ - return theInstance; -} - -KeySingleton & KeySingleton::getInstance(const char *filename, - const char *filekey) -{ - if (!instanceInited) - { - if (!(instanceInited = encKeys.initKeys(filename, filekey))) - sql_print_error("Could not initialize any of the encryption / " - "decryption keys. You can not read encrypted tables"); - } - return theInstance; -} - -keyentry *KeySingleton::getKeys(int id) -{ - return encKeys.getKeys(id); -} - -bool KeySingleton::hasKey(int id) -{ - return encKeys.getKeys(id) != NULL; -} diff --git a/plugin/file_key_management_plugin/KeySingleton.h b/plugin/file_key_management_plugin/KeySingleton.h deleted file mode 100644 index 37246c1b802..00000000000 --- a/plugin/file_key_management_plugin/KeySingleton.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2014 eperi GmbH. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** -@file KeySingletonPattern.h -Implementation of single pattern to keep keys for encrypting/decrypting pages. - -Created 09/13/2014 -***********************************************************************/ - - -#ifndef KEYSINGLETON_H_ -#define KEYSINGLETON_H_ - -#include "EncKeys.h" - - -class KeySingleton -{ -private: - static bool instanceInited; - static KeySingleton theInstance; - static EncKeys encKeys; - - // No new instance or object possible - KeySingleton() {} - - // No new instance possible through copy constructor - KeySingleton( const KeySingleton&) {} - - // No new instance possible through copy - KeySingleton & operator = (const KeySingleton&); - -public: - virtual ~KeySingleton() {encKeys.~EncKeys();} - static KeySingleton& getInstance(); - // Init the instance for only one time - static KeySingleton& getInstance(const char *filename, const char *filekey); - keyentry *getKeys(int id); - bool hasKey(int id); - static bool isAvailable() { - return instanceInited; - } -}; - -#endif /* KEYSINGLETON_H_ */ diff --git a/plugin/file_key_management_plugin/file_key_management_plugin.cc b/plugin/file_key_management_plugin/file_key_management_plugin.cc deleted file mode 100644 index cb6485f8596..00000000000 --- a/plugin/file_key_management_plugin/file_key_management_plugin.cc +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright (c) 2002, 2012, eperi GmbH. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include -#include -#include -#include -#include "sql_class.h" -#include "KeySingleton.h" -#include "EncKeys.h" - -/* Encryption for tables and columns */ -static char* filename = NULL; -static char* filekey = NULL; - -static MYSQL_SYSVAR_STR(filename, filename, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Path and name of the key file.", - NULL, NULL, NULL); - -static MYSQL_SYSVAR_STR(filekey, filekey, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Key to encrypt / decrypt the keyfile.", - NULL, NULL, NULL); - -static struct st_mysql_sys_var* settings[] = { - MYSQL_SYSVAR(filename), - MYSQL_SYSVAR(filekey), - NULL -}; - - - -/** - This method is using with the id 0 if exists. - This method is used by innobase/xtradb for the key - rotation feature of encrypting log files. -*/ - -static unsigned int get_highest_key_used_in_key_file() -{ - if (KeySingleton::getInstance().hasKey(0)) - { - return 0; - } - else - return CRYPT_KEY_UNKNOWN; -} - -static unsigned int has_key_from_key_file(unsigned int keyID) -{ - keyentry* entry = KeySingleton::getInstance().getKeys(keyID); - - return entry != NULL; -} - -static unsigned int get_key_size_from_key_file(unsigned int keyID) -{ - keyentry* entry = KeySingleton::getInstance().getKeys(keyID); - - if (entry != NULL) - { - char* keyString = entry->key; - size_t key_len = strlen(keyString)/2; - - return key_len; - } - else - { - return CRYPT_KEY_UNKNOWN; - } -} - -static int get_key_from_key_file(unsigned int keyID, unsigned char* dstbuf, - unsigned buflen) -{ - keyentry* entry = KeySingleton::getInstance().getKeys((int)keyID); - - if (entry != NULL) - { - char* keyString = entry->key; - size_t key_len = strlen(keyString)/2; - - if (buflen < key_len) - { - return CRYPT_BUFFER_TO_SMALL; - } - - my_aes_hex2uint(keyString, (unsigned char*)dstbuf, key_len); - - return CRYPT_KEY_OK; - } - else - { - return CRYPT_KEY_UNKNOWN; - } -} - -static int get_iv_from_key_file(unsigned int keyID, unsigned char* dstbuf, - unsigned buflen) -{ - keyentry* entry = KeySingleton::getInstance().getKeys((int)keyID); - - if (entry != NULL) - { - char* ivString = entry->iv; - size_t iv_len = strlen(ivString)/2; - - if (buflen < iv_len) - { - return CRYPT_BUFFER_TO_SMALL; - } - - my_aes_hex2uint(ivString, (unsigned char*)dstbuf, iv_len); - - return CRYPT_KEY_OK; - } - else - { - return CRYPT_KEY_UNKNOWN; - } -} - - -static int file_key_management_plugin_init(void *p) -{ - /* init */ - - if (current_aes_dynamic_method == MY_AES_ALGORITHM_NONE) - { - sql_print_error("No encryption method choosen with --encryption-algorithm. " - "file_key_management_plugin disabled"); - return 1; - } - - if (filename == NULL || strcmp("", filename) == 0) - { - sql_print_error("Parameter file_key_management_plugin_filename is required"); - - return 1; - } - - KeySingleton::getInstance(filename, filekey); - - return 0; -} - -static int file_key_management_plugin_deinit(void *p) -{ - KeySingleton::getInstance().~KeySingleton(); - - return 0; -} - -struct st_mariadb_encryption_key_management file_key_management_plugin= { - MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION, - get_highest_key_used_in_key_file, - has_key_from_key_file, - get_key_size_from_key_file, - get_key_from_key_file, - get_iv_from_key_file -}; - -/* - Plugin library descriptor -*/ -maria_declare_plugin(file_key_management_plugin) -{ - MariaDB_ENCRYPTION_KEY_MANAGEMENT_PLUGIN, - &file_key_management_plugin, - "file_key_management_plugin", - "Denis Endro eperi GmbH", - "File key management plugin", - PLUGIN_LICENSE_GPL, - file_key_management_plugin_init, /* Plugin Init */ - file_key_management_plugin_deinit, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - NULL, /* status variables */ - settings, - "1.0", - MariaDB_PLUGIN_MATURITY_UNKNOWN -} -maria_declare_plugin_end; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index cab320bb8c9..983c60ca254 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -117,7 +117,7 @@ SET (SQL_SOURCE my_json_writer.cc my_json_writer.h rpl_gtid.cc rpl_parallel.cc ${WSREP_SOURCES} - table_cache.cc encryption_keys.cc + table_cache.cc encryption.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} diff --git a/sql/create_options.cc b/sql/create_options.cc index 86fb805315a..c3796710f78 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -297,8 +297,7 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, (uchar*)val->name.str, val->name.length)) continue; - seen=true; - + /* skip duplicates (see engine_option_value constructor above) */ if (val->parsed && !val->value.str) continue; @@ -306,39 +305,58 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, *option_struct, suppress_warning || val->parsed, root)) DBUG_RETURN(TRUE); val->parsed= true; + seen=true; break; } - if (!seen) + if (!seen || (opt->var && !last->value.str)) { LEX_STRING default_val= null_lex_str; /* - If it's CREATE/ALTER TABLE parsing mode (options are created in the - transient thd->mem_root, not in the long living TABLE_SHARE::mem_root), - and variable-backed option was not explicitly set. + Okay, here's the logic for sysvar options: + 1. When we parse CREATE TABLE and sysvar option was not explicitly + mentioned we add it to the list as if it was specified with the + *current* value of the underlying sysvar. + 2. But only if the underlying sysvar value is different from the + sysvar's default. + 3. If it's ALTER TABLE and the sysvar option was not explicitly + mentioned - do nothing, do not add it to the list. + 4. But if it was ALTER TABLE with sysvar option = DEFAULT, we + add it to the list (under the same condition #2). + 5. If we're here parsing the option list from the .frm file + for a normal open_table() and the sysvar option was not there - + do not add it to the list (makes no sense anyway) and + use the *default* value of the underlying sysvar. Because + sysvar value can change, but it should not affect existing tables. - If it's not create, but opening of the existing frm (that was, - probably, created with the older version of the storage engine and - does not have this option stored), we take the *default* value of the - sysvar, not the *current* value. Because we don't want to have - different option values for the same table if it's opened many times. + This is how it's implemented: the current sysvar value is added + to the list if suppress_warning is FALSE (meaning a table is created, + that is CREATE TABLE or ALTER TABLE) and it's actually a CREATE TABLE + command or it's an ALTER TABLE and the option was seen (=DEFAULT). + + Note that if the option was set explicitly (not =DEFAULT) it wouldn't + have passes the if() condition above. */ - if (root == thd->mem_root && opt->var) + if (!suppress_warning && opt->var && + (thd->lex->sql_command == SQLCOM_CREATE_TABLE || seen)) { // take a value from the variable and add it to the list sys_var *sysvar= find_hton_sysvar(hton, opt->var); DBUG_ASSERT(sysvar); - char buf[256]; - String sbuf(buf, sizeof(buf), system_charset_info), *str; - if ((str= sysvar->val_str(&sbuf, thd, OPT_SESSION, &null_lex_str))) + if (!sysvar->session_is_default(thd)) { - LEX_STRING name= { const_cast(opt->name), opt->name_length }; - default_val.str= strmake_root(root, str->ptr(), str->length()); - default_val.length= str->length(); - val= new (root) engine_option_value(name, default_val, true, - option_list, &last); - val->parsed= true; + char buf[256]; + String sbuf(buf, sizeof(buf), system_charset_info), *str; + if ((str= sysvar->val_str(&sbuf, thd, OPT_SESSION, &null_lex_str))) + { + LEX_STRING name= { const_cast(opt->name), opt->name_length }; + default_val.str= strmake_root(root, str->ptr(), str->length()); + default_val.length= str->length(); + val= new (root) engine_option_value(name, default_val, + opt->type != HA_OPTION_TYPE_ULL, option_list, &last); + val->parsed= true; + } } } set_one_value(opt, thd, &default_val, *option_struct, diff --git a/sql/encryption.cc b/sql/encryption.cc new file mode 100644 index 00000000000..44208baf8b3 --- /dev/null +++ b/sql/encryption.cc @@ -0,0 +1,105 @@ +/* Copyright (C) 2015 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include "log.h" +#include "sql_plugin.h" +#include + +/* there can be only one encryption plugin enabled */ +static plugin_ref encryption_manager= 0; +struct encryption_service_st encryption_handler; + +unsigned int has_key_id(uint id) +{ + return encryption_key_get_latest_version(id) != ENCRYPTION_KEY_VERSION_INVALID; +} + +unsigned int has_key_version(uint id, uint version) +{ + uint unused; + return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID; +} + +uint no_key(uint) +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} + +static int no_crypt(const uchar* source, uint source_length, + uchar* dest, uint* dest_length, + const uchar* key, uint key_length, + const uchar* iv, uint iv_length, + int no_padding, uint key_id, uint key_version) +{ + return 1; +} + + +int initialize_encryption_plugin(st_plugin_int *plugin) +{ + if (encryption_manager) + return 1; + + if (plugin->plugin->init && plugin->plugin->init(plugin)) + { + sql_print_error("Plugin '%s' init function returned error.", + plugin->name.str); + return 1; + } + + encryption_manager= plugin_lock(NULL, plugin_int_to_ref(plugin)); + st_mariadb_encryption *handle= + (struct st_mariadb_encryption*) plugin->plugin->info; + + encryption_handler.encryption_encrypt_func= + handle->encrypt ? handle->encrypt + : (encrypt_decrypt_func)my_aes_encrypt_cbc; + + encryption_handler.encryption_decrypt_func= + handle->decrypt ? handle->decrypt + : (encrypt_decrypt_func)my_aes_decrypt_cbc; + + encryption_handler.encryption_key_get_func= + handle->get_key; + + encryption_handler.encryption_key_get_latest_version_func= + handle->get_latest_key_version; // must be the last + + return 0; +} + +int finalize_encryption_plugin(st_plugin_int *plugin) +{ + encryption_handler.encryption_encrypt_func= no_crypt; + encryption_handler.encryption_decrypt_func= no_crypt; + encryption_handler.encryption_key_id_exists_func= has_key_id; + encryption_handler.encryption_key_version_exists_func= has_key_version; + encryption_handler.encryption_key_get_func= + (uint (*)(uint, uint, uchar*, uint*))no_key; + encryption_handler.encryption_key_get_latest_version_func= no_key; + + if (plugin && plugin->plugin->deinit && plugin->plugin->deinit(NULL)) + { + DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", + plugin->name.str)); + } + if (encryption_manager) + plugin_unlock(NULL, encryption_manager); + encryption_manager= 0; + return 0; +} + diff --git a/sql/encryption_keys.cc b/sql/encryption_keys.cc deleted file mode 100644 index 07a5d346a05..00000000000 --- a/sql/encryption_keys.cc +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include "encryption_keys.h" -#include "log.h" -#include "sql_plugin.h" - -#ifndef DBUG_OFF -my_bool debug_use_static_encryption_keys = 0; -uint opt_debug_encryption_key_version = 0; -#endif - -/* there can be only one encryption key management plugin enabled */ -static plugin_ref encryption_key_manager= 0; -static struct st_mariadb_encryption_key_management *handle; - -unsigned int get_latest_encryption_key_version() -{ -#ifndef DBUG_OFF - if (debug_use_static_encryption_keys) - { - //mysql_mutex_lock(&LOCK_global_system_variables); - uint res = opt_debug_encryption_key_version; - //mysql_mutex_unlock(&LOCK_global_system_variables); - return res; - } -#endif - - if (encryption_key_manager) - return handle->get_latest_key_version(); - - return BAD_ENCRYPTION_KEY_VERSION; -} - -unsigned int has_encryption_key(uint version) -{ - if (encryption_key_manager) - return handle->has_key_version(version); - - return 0; -} - -unsigned int get_encryption_key_size(uint version) -{ - if (encryption_key_manager) - return handle->get_key_size(version); - - return 0; -} - -int get_encryption_key(uint version, uchar* key, uint size) -{ -#ifndef DBUG_OFF - if (debug_use_static_encryption_keys) - { - memset(key, 0, size); - // Just don't support tiny keys, no point anyway. - if (size < 4) - return 1; - - mi_int4store(key, version); - return 0; - } -#endif - - if (encryption_key_manager) - return handle->get_key(version, key, size); - - return 1; -} - -int get_encryption_iv(uint version, uchar* iv, uint size) -{ - if (encryption_key_manager) - return handle->get_iv(version, iv, size); - - return 1; -} - -int initialize_encryption_key_management_plugin(st_plugin_int *plugin) -{ - if (encryption_key_manager) - return 1; - - if (plugin->plugin->init && plugin->plugin->init(plugin)) - { - sql_print_error("Plugin '%s' init function returned error.", - plugin->name.str); - return 1; - } - - encryption_key_manager= plugin_lock(NULL, plugin_int_to_ref(plugin)); - handle= (struct st_mariadb_encryption_key_management*) - plugin->plugin->info; - return 0; -} - -int finalize_encryption_key_management_plugin(st_plugin_int *plugin) -{ - DBUG_ASSERT(encryption_key_manager); - - if (plugin->plugin->deinit && plugin->plugin->deinit(NULL)) - { - DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", - plugin->name.str)); - } - plugin_unlock(NULL, encryption_key_manager); - encryption_key_manager= 0; - return 0; -} - diff --git a/sql/encryption_keys.h b/sql/encryption_keys.h deleted file mode 100644 index 10907c1332a..00000000000 --- a/sql/encryption_keys.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SQL_CRYPTOKEY_INCLUDED -#define SQL_CRYPTOKEY_INCLUDED - -#include "my_global.h" - -#ifndef DBUG_OFF - extern my_bool debug_use_static_encryption_keys; -extern uint opt_debug_encryption_key_version; -#endif /* DBUG_OFF */ - -#endif // SQL_CRYPTOKEY_INCLUDED diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 32b6d6348ac..4bf8dd5ae1b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -54,7 +54,6 @@ #include #include #include "sha1.h" -#include "my_aes.h" #include C_MODE_START #include "../mysys/my_static.h" // For soundex_map @@ -366,29 +365,48 @@ void Item_func_sha2::fix_length_and_dec() } /* Implementation of AES encryption routines */ +void Item_aes_crypt::create_key(String *user_key, uchar *real_key) +{ + uchar *real_key_end= real_key + AES_KEY_LENGTH / 8; + uchar *ptr; + const char *sptr= user_key->ptr(); + const char *key_end= sptr + user_key->length(); -String *Item_func_aes_encrypt::val_str(String *str) + bzero(real_key, AES_KEY_LENGTH / 8); + + for (ptr= real_key; sptr < key_end; ptr++, sptr++) + { + if (ptr == real_key_end) + ptr= real_key; + *ptr ^= (uchar) *sptr; + } +} + + +String *Item_aes_crypt::val_str(String *str) { DBUG_ASSERT(fixed == 1); - char key_buff[80]; - String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); - String *sptr= args[0]->val_str(str); // String to encrypt - String *key= args[1]->val_str(&tmp_key_value); // key - int aes_length; - if (sptr && key) // we need both arguments to be not NULL + StringBuffer<80> user_key_buf; + String *sptr= args[0]->val_str(str); + String *user_key= args[1]->val_str(&user_key_buf); + uint32 aes_length; + + if (sptr && user_key) // we need both arguments to be not NULL { null_value=0; aes_length=my_aes_get_size(sptr->length()); // Calculate result length if (!str_value.alloc(aes_length)) // Ensure that memory is free { - // finally encrypt directly to allocated buffer. - if (my_aes_encrypt((const uchar*) sptr->ptr(), sptr->length(), (uchar*) str_value.ptr(), - key->ptr(), key->length()) == aes_length) + uchar rkey[AES_KEY_LENGTH / 8]; + create_key(user_key, rkey); + + if (!crypt((uchar*)sptr->ptr(), sptr->length(), + (uchar*)str_value.ptr(), &aes_length, + rkey, AES_KEY_LENGTH / 8, 0, 0, 0)) { - // We got the expected result length - str_value.length((uint) aes_length); - return &str_value; + str_value.length((uint) aes_length); + return &str_value; } } } @@ -396,43 +414,10 @@ String *Item_func_aes_encrypt::val_str(String *str) return 0; } - void Item_func_aes_encrypt::fix_length_and_dec() { max_length=my_aes_get_size(args[0]->max_length); -} - - -String *Item_func_aes_decrypt::val_str(String *str) -{ - DBUG_ASSERT(fixed == 1); - char key_buff[80]; - String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); - String *sptr, *key; - DBUG_ENTER("Item_func_aes_decrypt::val_str"); - - sptr= args[0]->val_str(str); // String to decrypt - key= args[1]->val_str(&tmp_key_value); // Key - if (sptr && key) // Need to have both arguments not NULL - { - null_value=0; - if (!str_value.alloc(sptr->length())) // Ensure that memory is free - { - // finally decrypt directly to allocated buffer. - int length; - length=my_aes_decrypt((const uchar*)sptr->ptr(), sptr->length(), - (uchar*) str_value.ptr(), - key->ptr(), key->length()); - if (length >= 0) // if we got correct data data - { - str_value.length((uint) length); - DBUG_RETURN(&str_value); - } - } - } - // Bad parameters. No memory or bad data will all go here - null_value=1; - DBUG_RETURN(0); + crypt= my_aes_encrypt_ecb; } @@ -440,6 +425,7 @@ void Item_func_aes_decrypt::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null= 1; + crypt= my_aes_decrypt_ecb; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index b79009c6778..ca699b28245 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -134,21 +134,35 @@ public: const char *func_name() const { return "from_base64"; } }; +#include -class Item_func_aes_encrypt :public Item_str_func +class Item_aes_crypt :public Item_str_func +{ + enum { AES_KEY_LENGTH = 128 }; + void create_key(String *user_key, uchar* key); + +protected: + int (*crypt)(const uchar* src, uint slen, uchar* dst, uint* dlen, + const uchar* key, uint klen, const uchar* iv, uint ivlen, + int no_padding); + +public: + Item_aes_crypt(Item *a, Item *b) :Item_str_func(a,b) {} + String *val_str(String *); +}; + +class Item_func_aes_encrypt :public Item_aes_crypt { public: - Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {} - String *val_str(String *); + Item_func_aes_encrypt(Item *a, Item *b) :Item_aes_crypt(a,b) {} void fix_length_and_dec(); const char *func_name() const { return "aes_encrypt"; } }; -class Item_func_aes_decrypt :public Item_str_func +class Item_func_aes_decrypt :public Item_aes_crypt { public: - Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {} - String *val_str(String *); + Item_func_aes_decrypt(Item *a, Item *b) :Item_aes_crypt(a,b) {} void fix_length_and_dec(); const char *func_name() const { return "aes_decrypt"; } }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 14d904bbe74..941ba505c20 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -105,7 +105,6 @@ #include "sp_rcontext.h" #include "sp_cache.h" #include "sql_reload.h" // reload_acl_and_cache -#include #ifdef HAVE_POLL_H #include @@ -630,7 +629,6 @@ char *mysqld_unix_port, *opt_mysql_tmpdir; ulong thread_handling; my_bool encrypt_tmp_disk_tables; -ulong encryption_algorithm; /** name of reference on left expression in rewritten IN subquery */ const char *in_left_expr_name= ""; @@ -4804,13 +4802,6 @@ static int init_server_components() my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); setup_fpu(); init_thr_lock(); - if (my_aes_init_dynamic_encrypt((enum_my_aes_encryption_algorithm) - encryption_algorithm)) - { - fprintf(stderr, "Can't initialize encryption algorithm to \"%s\".\nCheck that the program is linked with the right library (openssl?)\n", - encryption_algorithm_names[encryption_algorithm]); - unireg_abort(1); - } #ifndef EMBEDDED_LIBRARY if (init_thr_timer(thread_scheduler->max_threads + extra_max_connections)) @@ -7487,7 +7478,7 @@ static int show_queries(THD *thd, SHOW_VAR *var, char *buff, enum enum_var_type scope) { var->type= SHOW_LONGLONG; - var->value= (char *)&thd->query_id; + var->value= &thd->query_id; return 0; } @@ -7496,7 +7487,7 @@ static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff, enum enum_var_type scope) { var->type= SHOW_MY_BOOL; - var->value= (char *)&thd->net.compress; + var->value= &thd->net.compress; return 0; } @@ -7848,7 +7839,7 @@ static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff, if( thd->vio_ok() && thd->net.vio->ssl_arg ) var->value= const_cast(SSL_get_version((SSL*) thd->net.vio->ssl_arg)); else - var->value= (char *)""; + var->value= const_cast(""); return 0; } @@ -7907,7 +7898,7 @@ static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff, if( thd->vio_ok() && thd->net.vio->ssl_arg ) var->value= const_cast(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg)); else - var->value= (char *)""; + var->value= const_cast(""); return 0; } @@ -8055,14 +8046,14 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff, v= data->var; var->type= SHOW_ARRAY; - var->value= (char*)v; + var->value= v; get_key_cache_statistics(dflt_key_cache, 0, &data->stats); #define set_one_keycache_var(X,Y) \ v->name= X; \ v->type= SHOW_LONGLONG; \ - v->value= (char*)&data->stats.Y; \ + v->value= &data->stats.Y; \ v++; set_one_keycache_var("blocks_not_flushed", blocks_changed); @@ -8116,11 +8107,11 @@ static int debug_status_func(THD *thd, SHOW_VAR *var, char *buff, if (_db_keyword_(0, "role_merge_stats", 1)) { static SHOW_VAR roles[]= { - {"global", (char*) &role_global_merges, SHOW_ULONG}, - {"db", (char*) &role_db_merges, SHOW_ULONG}, - {"table", (char*) &role_table_merges, SHOW_ULONG}, - {"column", (char*) &role_column_merges, SHOW_ULONG}, - {"routine", (char*) &role_routine_merges, SHOW_ULONG}, + {"global", &role_global_merges, SHOW_ULONG}, + {"db", &role_db_merges, SHOW_ULONG}, + {"table", &role_table_merges, SHOW_ULONG}, + {"column", &role_column_merges, SHOW_ULONG}, + {"routine", &role_routine_merges, SHOW_ULONG}, {NullS, NullS, SHOW_LONG} }; diff --git a/sql/set_var.cc b/sql/set_var.cc index 278a05213a6..c65ca3d59b7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -147,7 +147,7 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg, flags(flags_arg), show_val_type(show_val_type_arg), guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func), deprecation_substitute(substitute), - is_os_charset(FALSE), default_val(FALSE) + is_os_charset(FALSE) { /* There is a limitation in handle_options() related to short options: @@ -790,7 +790,6 @@ int set_var::light_check(THD *thd) */ int set_var::update(THD *thd) { - var->set_is_default(value == 0); return value ? var->update(thd, this) : var->set_default(thd, this); } diff --git a/sql/set_var.h b/sql/set_var.h index 15c89f1e2b4..0215a452c07 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -88,7 +88,6 @@ protected: on_update_function on_update; const char *const deprecation_substitute; bool is_os_charset; ///< true if the value is in character_set_filesystem - bool default_val; public: sys_var(sys_var_chain *chain, const char *name_arg, const char *comment, @@ -194,8 +193,15 @@ public: return insert_dynamic(array, (uchar*)&option); } void do_deprecated_warning(THD *thd); - bool is_default() { return default_val; } - void set_is_default(bool def) { default_val= def; } + /** + whether session value of a sysvar is a default one. + + in this simple implementation we don't distinguish between default + and non-default values. for most variables it's ok, they don't treat + default values specially. this method is overwritten in descendant + classes as necessary. + */ + virtual bool session_is_default(THD *thd) { return false; } virtual uchar *default_value_ptr(THD *thd) { return (uchar*)&option.def_value; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3109b2ffe86..5eca972def3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2663,7 +2663,7 @@ mysql_execute_command(THD *thd) lex->free_arena_for_set_stmt(); goto error; } - if (v->var->is_default()) + if (v->var->session_is_default(thd)) o= new set_var(v->type, v->var, &v->base, NULL); else { diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index fe020d36f93..91b25ed417d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -37,12 +37,16 @@ #include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT #include #include -#include +#include #include "sql_plugin_compat.h" #define REPORT_TO_LOG 1 #define REPORT_TO_USER 2 +#ifdef HAVE_LINK_H +#include +#endif + extern struct st_maria_plugin *mysql_optional_plugins[]; extern struct st_maria_plugin *mysql_mandatory_plugins[]; @@ -87,7 +91,7 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]= { C_STRING_WITH_LEN("REPLICATION") }, { C_STRING_WITH_LEN("AUTHENTICATION") }, { C_STRING_WITH_LEN("PASSWORD VALIDATION") }, - { C_STRING_WITH_LEN("ENCRYPTION KEY MANAGEMENT") } + { C_STRING_WITH_LEN("ENCRYPTION") } }; extern int initialize_schema_table(st_plugin_int *plugin); @@ -96,8 +100,8 @@ extern int finalize_schema_table(st_plugin_int *plugin); extern int initialize_audit_plugin(st_plugin_int *plugin); extern int finalize_audit_plugin(st_plugin_int *plugin); -extern int initialize_encryption_key_management_plugin(st_plugin_int *plugin); -extern int finalize_encryption_key_management_plugin(st_plugin_int *plugin); +extern int initialize_encryption_plugin(st_plugin_int *plugin); +extern int finalize_encryption_plugin(st_plugin_int *plugin); /* The number of elements in both plugin_type_initialize and @@ -107,13 +111,13 @@ extern int finalize_encryption_key_management_plugin(st_plugin_int *plugin); plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= { 0, ha_initialize_handlerton, 0, 0,initialize_schema_table, - initialize_audit_plugin, 0, 0, 0, initialize_encryption_key_management_plugin + initialize_audit_plugin, 0, 0, 0, initialize_encryption_plugin }; plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= { 0, ha_finalize_handlerton, 0, 0, finalize_schema_table, - finalize_audit_plugin, 0, 0, 0, finalize_encryption_key_management_plugin + finalize_audit_plugin, 0, 0, 0, finalize_encryption_plugin }; /* @@ -124,7 +128,7 @@ plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= static int plugin_type_initialization_order[MYSQL_MAX_PLUGIN_TYPE_NUM]= { MYSQL_DAEMON_PLUGIN, - MariaDB_ENCRYPTION_KEY_MANAGEMENT_PLUGIN, + MariaDB_ENCRYPTION_PLUGIN, MYSQL_STORAGE_ENGINE_PLUGIN, MYSQL_INFORMATION_SCHEMA_PLUGIN, MYSQL_FTPARSER_PLUGIN, @@ -166,7 +170,7 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= MYSQL_REPLICATION_INTERFACE_VERSION, MIN_AUTHENTICATION_INTERFACE_VERSION, MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION, - MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION + MariaDB_ENCRYPTION_INTERFACE_VERSION }; static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= { @@ -179,7 +183,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= MYSQL_REPLICATION_INTERFACE_VERSION, MYSQL_AUTHENTICATION_INTERFACE_VERSION, MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION, - MariaDB_ENCRYPTION_KEY_MANAGEMENT_INTERFACE_VERSION + MariaDB_ENCRYPTION_INTERFACE_VERSION }; static struct @@ -303,6 +307,7 @@ public: virtual void global_save_default(THD *thd, set_var *var) {} bool session_update(THD *thd, set_var *var); bool global_update(THD *thd, set_var *var); + bool session_is_default(THD *thd); }; @@ -767,6 +772,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) } dlopen_count++; +#ifdef HAVE_LINK_H + if (global_system_variables.log_warnings > 2) + { + struct link_map *lm = (struct link_map*) plugin_dl.handle; + sql_print_information("Loaded '%s' with offset 0x%lx", dl->str, lm->l_addr); + } +#endif + /* Checks which plugin interface present and reads info */ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym))) { @@ -1385,16 +1398,6 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin, goto err; } - if (plugin->plugin_dl && global_system_variables.log_warnings >= 9) - { - void *sym= dlsym(plugin->plugin_dl->handle, - plugin->plugin_dl->mariaversion ? - maria_plugin_declarations_sym : plugin_declarations_sym); - DBUG_ASSERT(sym); - sql_print_information("Plugin %s loaded at %p", - plugin->name.str, sym); - } - if (plugin_type_initialize[plugin->plugin->type]) { if ((*plugin_type_initialize[plugin->plugin->type])(plugin)) @@ -1560,6 +1563,9 @@ int plugin_init(int *argc, char **argv, int flags) DBUG_ASSERT(strcmp(list_of_services[4].name, "debug_sync_service") == 0); list_of_services[4].service= *(void**)&debug_sync_C_callback_ptr; + /* prepare encryption_keys service */ + finalize_encryption_plugin(0); + mysql_mutex_lock(&LOCK_plugin); initialized= 1; @@ -1616,7 +1622,7 @@ int plugin_init(int *argc, char **argv, int flags) goto err_unlock; /* - initialize the global default storage engine so that it may + set the global default storage engine variable so that it will not be null in any child thread. */ global_system_variables.table_plugin= @@ -3335,6 +3341,39 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) } +bool sys_var_pluginvar::session_is_default(THD *thd) +{ + uchar *value= plugin_var->flags & PLUGIN_VAR_THDLOCAL + ? intern_sys_var_ptr(thd, *(int*) (plugin_var+1), true) + : *(uchar**) (plugin_var+1); + + real_value_ptr(thd, OPT_SESSION); + + switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) { + case PLUGIN_VAR_BOOL: + return option.def_value == *(my_bool*)value; + case PLUGIN_VAR_INT: + return option.def_value == *(int*)value; + case PLUGIN_VAR_LONG: + case PLUGIN_VAR_ENUM: + return option.def_value == *(long*)value; + case PLUGIN_VAR_LONGLONG: + case PLUGIN_VAR_SET: + return option.def_value == *(longlong*)value; + case PLUGIN_VAR_STR: + { + const char *a=(char*)option.def_value; + const char *b=(char*)value; + return (!a && !b) || (a && b && strcmp(a,b)); + } + case PLUGIN_VAR_DOUBLE: + return getopt_ulonglong2double(option.def_value) == *(double*)value; + default: + DBUG_ASSERT(0); + } +} + + TYPELIB* sys_var_pluginvar::plugin_var_typelib(void) { switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) { diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h index aeb2d75efc5..b848dfb8f6b 100644 --- a/sql/sql_plugin_services.h +++ b/sql/sql_plugin_services.h @@ -139,15 +139,6 @@ static struct wsrep_service_st wsrep_handler = { wsrep_unlock_rollback }; -static struct encryption_keys_service_st encryption_keys_handler= -{ - get_latest_encryption_key_version, - has_encryption_key, - get_encryption_key_size, - get_encryption_key, - get_encryption_iv -}; - static struct thd_specifics_service_st thd_specifics_handler= { thd_key_create, @@ -170,7 +161,7 @@ static struct st_service_ref list_of_services[]= { "logger_service", VERSION_logger, &logger_service_handler }, { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler }, { "wsrep_service", VERSION_wsrep, &wsrep_handler }, - { "encryption_keys_service", VERSION_encryption_keys, &encryption_keys_handler }, + { "encryption_service", VERSION_encryption, &encryption_handler }, { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler }, { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler }, }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a49d5b05bdd..20a829eae23 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16878,7 +16878,6 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, MARIA_UNIQUEDEF uniquedef; TABLE_SHARE *share= table->s; MARIA_CREATE_INFO create_info; - my_bool encrypt= encrypt_tmp_disk_tables; DBUG_ENTER("create_internal_tmp_table"); if (share->keys) @@ -16984,20 +16983,14 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, { enum data_file_type file_type= table->no_rows ? NO_RECORD : (share->reclength < 64 && !share->blob_fields ? STATIC_RECORD : - table->used_for_duplicate_elimination || table->keep_row_order ? - DYNAMIC_RECORD : BLOCK_RECORD); - uint create_flags= HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE; + table->used_for_duplicate_elimination ? DYNAMIC_RECORD : BLOCK_RECORD); + uint create_flags= HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE | + (table->keep_row_order ? HA_PRESERVE_INSERT_ORDER : 0); - if (file_type != NO_RECORD && MY_TEST(encrypt)) + if (file_type != NO_RECORD && encrypt_tmp_disk_tables) { /* encryption is only supported for BLOCK_RECORD */ file_type= BLOCK_RECORD; - create_flags|= HA_CREATE_ENCRYPTED; - if (table->keep_row_order) - { - create_flags|= HA_INSERT_ORDER; - } - if (table->used_for_duplicate_elimination) { /* diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bc25951bafa..c5748459d6d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6383,6 +6383,14 @@ static bool fill_alter_inplace_info(THD *thd, new_field->field->field_index != key_part->fieldnr - 1) goto index_changed; } + + /* Check that key comment is not changed. */ + if (table_key->comment.length != new_key->comment.length || + (table_key->comment.length && + memcmp(table_key->comment.str, new_key->comment.str, + table_key->comment.length) != 0)) + goto index_changed; + continue; index_changed: diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 734b6ed9171..cc29762c144 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -62,7 +62,6 @@ #include "sql_repl.h" #include "opt_range.h" #include "rpl_parallel.h" -#include "encryption_keys.h" /* The rule for this file: everything should be 'static'. When a sys_var @@ -1126,22 +1125,6 @@ static Sys_var_mybool Sys_log_bin( READ_ONLY GLOBAL_VAR(opt_bin_log), NO_CMD_LINE, DEFAULT(FALSE)); -#ifndef DBUG_OFF -static Sys_var_mybool Sys_debug_use_static_keys( - "debug_use_static_encryption_keys", - "Enable use of nonrandom encryption keys. Only to be used in " - "internal testing", - READ_ONLY GLOBAL_VAR(debug_use_static_encryption_keys), - CMD_LINE(OPT_ARG), DEFAULT(FALSE)); - -static Sys_var_uint Sys_debug_encryption_key_version( - "debug_encryption_key_version", - "Encryption key version. Only to be used in internal testing.", - GLOBAL_VAR(opt_debug_encryption_key_version), - CMD_LINE(REQUIRED_ARG), VALID_RANGE(0,UINT_MAX), DEFAULT(0), - BLOCK_SIZE(1)); -#endif - static Sys_var_mybool Sys_trust_function_creators( "log_bin_trust_function_creators", "If set to FALSE (the default), then when --log-bin is used, creation " @@ -3725,28 +3708,11 @@ static Sys_var_harows Sys_select_limit( SESSION_VAR(select_limit), NO_CMD_LINE, VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1)); -static bool update_timestamp(THD *thd, set_var *var) -{ - if (var->value) - { - my_hrtime_t hrtime = { hrtime_from_time(var->save_result.double_value) }; - thd->set_time(hrtime); - } - else // SET timestamp=DEFAULT - thd->user_time.val= 0; - return false; -} -static double read_timestamp(THD *thd) -{ - return thd->start_time + - thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR; -} -static Sys_var_session_special_double Sys_timestamp( +static Sys_var_timestamp Sys_timestamp( "timestamp", "Set the time for this client", sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, TIMESTAMP_MAX_VALUE), - NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0), - ON_UPDATE(update_timestamp), ON_READ(read_timestamp)); + NO_MUTEX_GUARD, IN_BINLOG); static bool update_last_insert_id(THD *thd, set_var *var) { @@ -5185,14 +5151,6 @@ static Sys_var_mybool Sys_encrypt_tmp_disk_tables( GLOBAL_VAR(encrypt_tmp_disk_tables), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); -const char *encryption_algorithm_names[]= -{ "none", "aes_ecb", "aes_cbc", "aes_ctr", 0 }; -static Sys_var_enum Sys_encryption_algorithm( - "encryption_algorithm", - "Which encryption algorithm to use for table encryption. aes_cbc is the recommended one.", - READ_ONLY GLOBAL_VAR(encryption_algorithm),CMD_LINE(REQUIRED_ARG), - encryption_algorithm_names, DEFAULT(0)); - static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var) { longlong previous_val= thd->variables.pseudo_slave_mode; diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 2b83e9747b7..7c0359a7427 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -1657,46 +1657,57 @@ public: }; -class Sys_var_session_special_double: public Sys_var_double -{ - typedef bool (*session_special_update_function)(THD *thd, set_var *var); - typedef double (*session_special_read_function)(THD *thd); +/* + Dedicated class because of a weird behavior of a default value. + Assigning timestamp to itself - session_special_read_function read_func; - session_special_update_function update_func; + SET @@timestamp = @@timestamp + + make it non-default and stops the time flow. +*/ +class Sys_var_timestamp: public Sys_var_double +{ public: - Sys_var_session_special_double(const char *name_arg, + Sys_var_timestamp(const char *name_arg, const char *comment, int flag_args, CMD_LINE getopt, double min_val, double max_val, - PolyLock *lock, enum binlog_status_enum binlog_status_arg, - on_check_function on_check_func, - session_special_update_function update_func_arg, - session_special_read_function read_func_arg, - const char *substitute=0) + PolyLock *lock, enum binlog_status_enum binlog_status_arg) : Sys_var_double(name_arg, comment, flag_args, 0, sizeof(double), getopt, min_val, - max_val, 0, lock, binlog_status_arg, on_check_func, 0, - substitute), - read_func(read_func_arg), update_func(update_func_arg) + max_val, 0, lock, binlog_status_arg) { SYSVAR_ASSERT(scope() == ONLY_SESSION); SYSVAR_ASSERT(getopt.id < 0); // NO_CMD_LINE, because the offset is fake } bool session_update(THD *thd, set_var *var) - { return update_func(thd, var); } + { + if (var->value) + { + my_hrtime_t hrtime = { hrtime_from_time(var->save_result.double_value) }; + thd->set_time(hrtime); + } + else // SET timestamp=DEFAULT + thd->user_time.val= 0; + return false; + } bool global_update(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); return true; } + bool session_is_default(THD *thd) + { + return thd->user_time.val == 0; + } void session_save_default(THD *thd, set_var *var) { var->value= 0; } void global_save_default(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); } uchar *session_value_ptr(THD *thd, const LEX_STRING *base) { - thd->sys_var_tmp.double_value= read_func(thd); + thd->sys_var_tmp.double_value= thd->start_time + + thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR; return (uchar*) &thd->sys_var_tmp.double_value; } uchar *global_value_ptr(THD *thd, const LEX_STRING *base) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 87c6a1467e6..94a913cbe4c 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -474,5 +474,5 @@ ENDIF() MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MODULE_ONLY MODULE_OUTPUT_NAME ha_innodb - LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT} pcre pcreposix) + LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 59cbe633dec..64f40fad1d9 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -40,6 +40,7 @@ Created 11/5/1995 Heikki Tuuri #include "mem0mem.h" #include "btr0btr.h" #include "fil0fil.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP #include "buf0buddy.h" #include "lock0lock.h" @@ -54,11 +55,18 @@ Created 11/5/1995 Heikki Tuuri #include "page0zip.h" #include "srv0mon.h" #include "buf0checksum.h" -#include "fil0pageencryption.h" #include "fil0pagecompress.h" #include "ut0byte.h" #include +#ifdef HAVE_LZO +#include "lzo/lzo1x.h" +#endif + +/* Number of temporary slots used for encryption/compression +memory allocation before/after I/O operations */ +#define BUF_MAX_TMP_SLOTS 200 + /* IMPLEMENTATION OF THE BUFFER POOL ================================= @@ -504,7 +512,7 @@ buf_page_is_corrupted( ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ { - ulint page_encrypted = fil_page_is_compressed_encrypted(read_buf) || fil_page_is_encrypted(read_buf); + ulint page_encrypted = fil_page_is_encrypted(read_buf); ulint checksum_field1; ulint checksum_field2; ibool crc32_inited = FALSE; @@ -1001,14 +1009,11 @@ buf_block_init( block->page.state = BUF_BLOCK_NOT_USED; block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; - block->page.crypt_buf = NULL; - block->page.crypt_buf_free = NULL; - block->page.comp_buf = NULL; - block->page.comp_buf_free = NULL; block->page.key_version = 0; - block->page.encrypt_later = false; - + block->page.real_size = 0; + block->page.write_size = 0; block->modify_clock = 0; + block->page.slot = NULL; #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG block->page.file_page_was_freed = FALSE; @@ -1361,6 +1366,11 @@ buf_pool_init_instance( /* Initialize the iterator for single page scan search */ new(&buf_pool->single_scan_itr) LRUItr(buf_pool, &buf_pool->mutex); + /* Initialize the temporal memory array and slots */ + buf_pool->tmp_arr = (buf_tmp_array_t *)mem_zalloc(sizeof(buf_tmp_array_t)); + buf_pool->tmp_arr->n_slots = BUF_MAX_TMP_SLOTS; + buf_pool->tmp_arr->slots = (buf_tmp_buffer_t*)mem_zalloc(sizeof(buf_tmp_buffer_t) * BUF_MAX_TMP_SLOTS); + buf_pool_mutex_exit(buf_pool); return(DB_SUCCESS); @@ -1412,6 +1422,25 @@ buf_pool_free_instance( ha_clear(buf_pool->page_hash); hash_table_free(buf_pool->page_hash); hash_table_free(buf_pool->zip_hash); + + /* Free all used temporary slots */ + for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { + buf_tmp_buffer_t* slot = &buf_pool->tmp_arr->slots[i]; +#ifdef HAVE_LZO + if (slot->lzo_mem) { + ut_free(slot->lzo_mem); + } +#endif + if (slot->crypt_buf_free) { + ut_free(slot->crypt_buf_free); + } + if (slot->comp_buf_free) { + ut_free(slot->comp_buf_free); + } + } + + mem_free(buf_pool->tmp_arr->slots); + mem_free(buf_pool->tmp_arr); } /********************************************************************//** @@ -3494,12 +3523,9 @@ buf_page_init_low( bpage->newest_modification = 0; bpage->oldest_modification = 0; bpage->write_size = 0; - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - bpage->comp_buf = NULL; - bpage->comp_buf_free = NULL; bpage->key_version = 0; - bpage->encrypt_later = false; + bpage->real_size = 0; + bpage->slot = NULL; HASH_INVALIDATE(bpage, hash); #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG @@ -3799,6 +3825,8 @@ err_exit: page_zip_set_size(&bpage->zip, zip_size); bpage->zip.data = (page_zip_t*) data; + bpage->slot = NULL; + mutex_enter(&buf_pool->zip_mutex); UNIV_MEM_DESC(bpage->zip.data, page_zip_get_size(&bpage->zip)); @@ -4366,7 +4394,11 @@ corrupt: } } else { /* io_type == BUF_IO_WRITE */ - buf_page_encrypt_after_write(bpage); + if (bpage->slot) { + /* Mark slot free */ + bpage->slot->reserved = false; + bpage->slot = NULL; + } } buf_pool_mutex_enter(buf_pool); @@ -5602,6 +5634,60 @@ buf_page_init_for_backup_restore( } #endif /* !UNIV_HOTBACKUP */ +/********************************************************************//** +Reserve unused slot from temporary memory array and allocate necessary +temporary memory if not yet allocated. +@return reserved slot */ +buf_tmp_buffer_t* +buf_pool_reserve_tmp_slot( +/*======================*/ + buf_pool_t* buf_pool, /*!< in: buffer pool where to + reserve */ + bool compressed) /*!< in: is file space compressed */ +{ + buf_tmp_buffer_t *free_slot=NULL; + + /* Array is protected by buf_pool mutex */ + buf_pool_mutex_enter(buf_pool); + + for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { + buf_tmp_buffer_t *slot = &buf_pool->tmp_arr->slots[i]; + + if(slot->reserved == false) { + free_slot = slot; + break; + } + } + + /* We assume that free slot is found */ + ut_a(free_slot != NULL); + free_slot->reserved = true; + /* Now that we have reserved this slot we can release + buf_pool mutex */ + buf_pool_mutex_exit(buf_pool); + + /* Allocate temporary memory for encryption/decryption */ + if (free_slot->crypt_buf_free == NULL) { + free_slot->crypt_buf_free = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); + free_slot->crypt_buf = static_cast(ut_align(free_slot->crypt_buf_free, UNIV_PAGE_SIZE)); + memset(free_slot->crypt_buf_free, 0, UNIV_PAGE_SIZE *2); + } + + /* For page compressed tables allocate temporary memory for + compression/decompression */ + if (compressed && free_slot->comp_buf_free == NULL) { + free_slot->comp_buf_free = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); + free_slot->comp_buf = static_cast(ut_align(free_slot->comp_buf_free, UNIV_PAGE_SIZE)); + memset(free_slot->comp_buf_free, 0, UNIV_PAGE_SIZE *2); +#ifdef HAVE_LZO + free_slot->lzo_mem = static_cast(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); + memset(free_slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); +#endif + } + + return (free_slot); +} + /********************************************************************//** Encrypts a buffer page right before it's flushed to disk */ @@ -5609,11 +5695,18 @@ byte* buf_page_encrypt_before_write( /*==========================*/ buf_page_t* bpage, /*!< in/out: buffer page to be flushed */ - const byte* src_frame) /*!< in: src frame */ + const byte* src_frame, /*!< in: src frame */ + ulint space_id) /*!< in: space id */ { - bpage->encrypt_later = false; + fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id); + bpage->real_size = UNIV_PAGE_SIZE; - if (srv_encrypt_tables == FALSE) { + if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + /* Encryption is disabled */ + return const_cast(src_frame); + } + + if (!srv_encrypt_tables && (crypt_data == NULL || crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { /* Encryption is disabled */ return const_cast(src_frame); } @@ -5638,103 +5731,63 @@ buf_page_encrypt_before_write( ulint zip_size = buf_page_get_zip_size(bpage); ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + bool page_compressed = fil_space_is_page_compressed(bpage->space); - /** - * TODO(jonaso): figure out more clever malloc strategy - * - * This implementation does a malloc/free per iop for encrypted - * tablespaces. Alternative strategies that have been considered are - * - * 1) use buf_block_alloc (i.e alloc from buffer pool) - * this does not work as buf_block_alloc will then be called - * when needing to flush a page, which might be triggered - * due to shortage of memory in buffer pool - * 2) allocate a buffer per fil_node_t - * this would break abstraction layers and has therfore not been - * considered a lot. - */ + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); + bpage->slot = slot; - if (bpage->crypt_buf_free == NULL) { - bpage->crypt_buf_free = (byte*)malloc(page_size*2); - // TODO: Is 4k aligment enough ? - bpage->crypt_buf = (byte *)ut_align(bpage->crypt_buf_free, page_size); - } + byte *dst_frame = slot->crypt_buf; - byte *dst_frame = bpage->crypt_buf; - - if (!fil_space_is_page_compressed(bpage->space)) { - // encrypt page content - fil_space_encrypt(bpage->space, bpage->offset, - bpage->newest_modification, - src_frame, zip_size, dst_frame, 0); + if (!page_compressed) { + /* Encrypt page content */ + fil_space_encrypt(bpage->space, + bpage->offset, + bpage->newest_modification, + src_frame, + zip_size, + dst_frame); unsigned key_version = mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); ut_ad(key_version == 0 || key_version >= bpage->key_version); bpage->key_version = key_version; + bpage->real_size = page_size; } else { - /** Compression and encryption is done later at os0file.cc */ - bpage->encrypt_later = true; - dst_frame = (byte *)src_frame; + /* First we compress the page content */ + ulint out_len = 0; + ulint block_size = fil_space_get_block_size(bpage->space, bpage->offset, page_size); + + byte *tmp = fil_compress_page(bpage->space, + (byte *)src_frame, + slot->comp_buf, + page_size, + fil_space_get_page_compression_level(bpage->space), + block_size, + &out_len, +#ifdef HAVE_LZO + slot->lzo_mem +#else + NULL +#endif + ); + + bpage->real_size = out_len; + + /* And then we encrypt the page content */ + fil_space_encrypt(bpage->space, + bpage->offset, + bpage->newest_modification, + tmp, + zip_size, + dst_frame); } // return dst_frame which will be written return dst_frame; } -/********************************************************************//** -Release memory after encrypted page has been written to disk -*/ -ibool -buf_page_encrypt_after_write( -/*=========================*/ - buf_page_t* bpage) /*!< in/out: buffer page flushed */ -{ - if (bpage->crypt_buf_free != NULL) { - free(bpage->crypt_buf_free); - bpage->crypt_buf_free = NULL; - bpage->crypt_buf = NULL; - } - - if (bpage->comp_buf_free != NULL) { - free(bpage->comp_buf_free); - bpage->comp_buf_free = NULL; - bpage->comp_buf = NULL; - } - - return (TRUE); -} - -/********************************************************************//** -Allocates memory to read in an encrypted page -*/ -byte* -buf_page_decrypt_before_read( -/*=========================*/ - buf_page_t* bpage, /*!< in/out: buffer page to be read */ - ulint zip_size) /*!< in: compressed page size, or 0 */ -{ - ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; - - /* - Here we only need to allocate space for not header pages - in case of file space encryption. Table encryption is handled - later. - */ - if (!srv_encrypt_tables || bpage->offset == 0 || - fil_space_check_encryption_read(bpage->space) == false) - return zip_size ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - - if (bpage->crypt_buf_free == NULL) - { - // allocate buffer to read data into - bpage->crypt_buf_free = (byte*)malloc(size*2); - // TODO: Is 4K aligment enough ? - bpage->crypt_buf = (byte*)ut_align(bpage->crypt_buf_free, size); - } - return bpage->crypt_buf; -} - /********************************************************************//** Decrypt page after it has been read from disk */ @@ -5744,104 +5797,66 @@ buf_page_decrypt_after_read( buf_page_t* bpage) /*!< in/out: buffer page read from disk */ { ut_ad(bpage->key_version == 0); + + if (bpage->offset == 0) { + /* File header pages are not encrypted */ + return (TRUE); + } + ulint zip_size = buf_page_get_zip_size(bpage); ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; byte* dst_frame = (zip_size) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - - if (bpage->offset == 0) { - /* File header pages are not encrypted */ - ut_a(bpage->crypt_buf == NULL); - return (TRUE); - } - - - const byte* src_frame = bpage->crypt_buf != NULL ? - bpage->crypt_buf : dst_frame; - unsigned key_version = - mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - bool page_compressed_encrypted = fil_page_is_compressed_encrypted(dst_frame); + bool page_compressed = fil_page_is_compressed(dst_frame); + + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); if (key_version == 0) { /* the page we read is unencrypted */ - if (fil_page_is_compressed(dst_frame)) { - if (bpage->comp_buf_free == NULL) { - bpage->comp_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - bpage->comp_buf = (byte*)ut_align(bpage->comp_buf_free, UNIV_PAGE_SIZE); - } + if (page_compressed) { + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - fil_decompress_page(bpage->comp_buf, dst_frame, size, NULL); - } else { - if (dst_frame != src_frame) { - /* but we had allocated a crypt_buf */ - // TODO: Can this be avoided ? - memcpy(dst_frame, src_frame, size); - } + fil_decompress_page(slot->comp_buf, + dst_frame, + size, + &bpage->write_size); + + /* Mark this slot as free */ + slot->reserved = false; } } else { /* the page we read is encrypted */ - if (dst_frame == src_frame) { - /* but we had NOT allocated a crypt buf - * malloc a buffer, copy page to it - * and then decrypt from that into real page*/ - bpage->crypt_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - src_frame = bpage->crypt_buf = (byte*)ut_align(bpage->crypt_buf_free, UNIV_PAGE_SIZE); - memcpy(bpage->crypt_buf, dst_frame, size); - } + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - /* decrypt from src_frame to dst_frame */ + memcpy(slot->crypt_buf, dst_frame, size); + + /* decrypt from crypt_buf to dst_frame */ fil_space_decrypt(bpage->space, - src_frame, size, dst_frame); + slot->crypt_buf, + size, + dst_frame); /* decompress from dst_frame to comp_buf and then copy to buffer pool */ - if (page_compressed_encrypted) { - if (bpage->comp_buf_free == NULL) { - bpage->comp_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - bpage->comp_buf = (byte*)ut_align(bpage->comp_buf_free, UNIV_PAGE_SIZE); - } - - fil_decompress_page(bpage->comp_buf, dst_frame, size, NULL); + if (page_compressed) { + fil_decompress_page(slot->comp_buf, + dst_frame, + size, + &bpage->write_size); } + + /* Mark this slot as free */ + slot->reserved = false; } bpage->key_version = key_version; - if (bpage->crypt_buf_free != NULL) { - // free temp page - free(bpage->crypt_buf_free); - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - } - - if (bpage->comp_buf_free != NULL) { - // free temp page - free(bpage->comp_buf_free); - bpage->comp_buf = NULL; - bpage->comp_buf_free = NULL; - } - return (TRUE); } - -/********************************************************************//** -Release memory allocated for decryption -*/ -void -buf_page_decrypt_cleanup( -/*=====================*/ - buf_page_t* bpage) /*!< in/out: buffer page */ -{ - if (bpage->crypt_buf != NULL) { - free(bpage->crypt_buf_free); - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - } -} diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 477bcfe0ee3..15a46abe55f 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -36,6 +36,7 @@ Created 2011/12/19 #include "srv0srv.h" #include "page0zip.h" #include "trx0sys.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP @@ -385,7 +386,7 @@ buf_dblwr_init_or_load_pages( /* Read the trx sys header to check if we are using the doublewrite buffer */ off_t trx_sys_page = TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE; - os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE, FALSE); + os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE); doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; @@ -430,9 +431,9 @@ buf_dblwr_init_or_load_pages( block_bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; - os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes, FALSE); + os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes); os_file_read(file, buf + block_bytes, block2 * UNIV_PAGE_SIZE, - block_bytes, FALSE); + block_bytes); /* Check if any of these pages is half-written in data files, in the intended position */ @@ -530,9 +531,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, read_buf, NULL, - 0, - 0, - false); + 0); if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { /* page is encrypted and checksum is OK */ @@ -593,9 +592,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, page, NULL, - 0, - 0, - false); + 0); ib_logf(IB_LOG_LEVEL_INFO, "Recovered the page from" @@ -620,9 +617,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, page, NULL, - 0, - 0, - false); + 0); } } } @@ -631,10 +626,6 @@ buf_dblwr_process() fil_flush_file_spaces(FIL_TABLESPACE); { - fprintf(stderr, - "Clear dblwr buffer after completing " - "processing of it...\n"); - size_t bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; byte *unaligned_buf = static_cast( ut_malloc(bytes + UNIV_PAGE_SIZE - 1)); @@ -644,9 +635,9 @@ buf_dblwr_process() memset(buf, 0, bytes); fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, - buf_dblwr->block1, 0, bytes, buf, NULL, NULL, 0, false); + buf_dblwr->block1, 0, bytes, buf, NULL, NULL); fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, - buf_dblwr->block2, 0, bytes, buf, NULL, NULL, 0, false); + buf_dblwr->block2, 0, bytes, buf, NULL, NULL); ut_free(unaligned_buf); } @@ -860,9 +851,7 @@ buf_dblwr_write_block_to_datafile( buf_page_get_zip_size(bpage), frame, (void*) bpage, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); return; } @@ -878,12 +867,10 @@ buf_dblwr_write_block_to_datafile( 0, buf_block_get_page_no(block), 0, - UNIV_PAGE_SIZE, + bpage->real_size, frame, (void*) block, - (ulint *)&bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + (ulint *)&bpage->write_size); } /********************************************************************//** @@ -977,7 +964,7 @@ try_again: fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, buf_dblwr->block1, 0, len, - (void*) write_buf, NULL, 0, 0, false); + (void*) write_buf, NULL, 0); if (buf_dblwr->first_free <= TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { /* No unwritten pages in the second block. */ @@ -993,7 +980,7 @@ try_again: fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, buf_dblwr->block2, 0, len, - (void*) write_buf, NULL, 0, 0, false); + (void*) write_buf, NULL, 0); flush: /* increment the doublewrite flushed pages counter */ @@ -1230,9 +1217,7 @@ retry: UNIV_PAGE_SIZE, (void*) (buf_dblwr->write_buf + UNIV_PAGE_SIZE * i), NULL, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); } else { /* It is a regular page. Write it directly to the doublewrite buffer */ @@ -1241,12 +1226,10 @@ retry: TRX_SYS_SPACE, 0, offset, 0, - UNIV_PAGE_SIZE, + bpage->real_size, frame, NULL, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); } /* Now flush the doublewrite buffer data to disk */ diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 9bd7a7c007d..d893d424b02 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -909,7 +909,7 @@ buf_flush_write_block_low( break; } - frame = buf_page_encrypt_before_write(bpage, frame); + frame = buf_page_encrypt_before_write(bpage, frame, space_id); if (!srv_use_doublewrite_buf || !buf_dblwr) { fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, @@ -918,12 +918,10 @@ buf_flush_write_block_low( zip_size, buf_page_get_page_no(bpage), 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, + zip_size ? zip_size : bpage->real_size, frame, bpage, - &bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + &bpage->write_size); } else { /* InnoDB uses doublewrite buffer and doublewrite buffer @@ -940,12 +938,10 @@ buf_flush_write_block_low( zip_size, buf_page_get_page_no(bpage), 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, + zip_size ? zip_size : bpage->real_size, frame, bpage, - &bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + &bpage->write_size); } else if (flush_type == BUF_FLUSH_SINGLE_PAGE) { buf_dblwr_write_single_page(bpage, sync); } else { diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index e91a5da6621..b4b474c547f 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -176,7 +176,7 @@ buf_read_page_low( ut_ad(buf_page_in_file(bpage)); - byte* frame = buf_page_decrypt_before_read(bpage, zip_size); + byte* frame = zip_size ? bpage->zip.data : ((buf_block_t*) bpage)->frame; if (sync) { thd_wait_begin(NULL, THD_WAIT_DISKIO); @@ -186,7 +186,7 @@ buf_read_page_low( *err = fil_io(OS_FILE_READ | wake_later | ignore_nonexistent_pages, sync, space, zip_size, offset, 0, zip_size, - frame, bpage, &bpage->write_size, 0, false); + frame, bpage, &bpage->write_size); } else { ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); @@ -194,7 +194,7 @@ buf_read_page_low( | ignore_nonexistent_pages, sync, space, 0, offset, 0, UNIV_PAGE_SIZE, frame, bpage, - &bpage->write_size, 0, false); + &bpage->write_size); } if (sync) { @@ -202,7 +202,6 @@ buf_read_page_low( } if (*err != DB_SUCCESS) { - buf_page_decrypt_cleanup(bpage); if (ignore_nonexistent_pages || *err == DB_TABLESPACE_DELETED) { buf_read_page_handle_error(bpage); return(0); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 9f8315a8016..04dad889d65 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -24,6 +24,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com *******************************************************/ #include "fil0fil.h" +#include "fil0crypt.h" #include "srv0srv.h" #include "srv0start.h" #include "mach0data.h" @@ -35,15 +36,10 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "btr0scrub.h" #include "fsp0fsp.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #include "ha_prototypes.h" // IB_LOG_ #include -#include -#include - - /** Mutex for keys */ UNIV_INTERN ib_mutex_t fil_crypt_key_mutex; @@ -52,7 +48,7 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; #endif /** Is encryption enabled/disabled */ -UNIV_INTERN my_bool srv_encrypt_tables = FALSE; +UNIV_INTERN ulong srv_encrypt_tables = 0; /** No of key rotation threads requested */ UNIV_INTERN uint srv_n_fil_crypt_threads = 0; @@ -119,67 +115,12 @@ static const unsigned char CRYPT_MAGIC[MAGIC_SZ] = { static const unsigned char EMPTY_PATTERN[MAGIC_SZ] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -/** - * CRYPT_SCHEME_UNENCRYPTED - * - * Used as intermediate state when convering a space from unencrypted - * to encrypted - */ -#define CRYPT_SCHEME_UNENCRYPTED 0 - -/** - * CRYPT_SCHEME_1 - * - * L = AES_ECB(KEY, IV) - * CRYPT(PAGE) = AES_CRT(KEY=L, IV=C, PAGE) - */ -#define CRYPT_SCHEME_1 1 -#define CRYPT_SCHEME_1_IV_LEN 16 -// cached L given key_version -struct key_struct -{ - uint key_version; - byte key[CRYPT_SCHEME_1_IV_LEN]; -}; - -struct fil_space_rotate_state_t -{ - time_t start_time; // time when rotation started - ulint active_threads; // active threads in space - ulint next_offset; // next "free" offset - ulint max_offset; // max offset needing to be rotated - uint min_key_version_found; // min key version found but not rotated - lsn_t end_lsn; // max lsn created when rotating this space - bool starting; // initial write of IV - bool flushing; // space is being flushed at end of rotate - struct { - bool is_active; // is scrubbing active in this space - time_t last_scrub_completed; // when was last scrub completed - } scrubbing; -}; - -struct fil_space_crypt_struct -{ - ulint type; // CRYPT_SCHEME - uint keyserver_requests; // no of key requests to key server - uint key_count; // No of initalized key-structs - key_struct keys[3]; // cached L = AES_ECB(KEY, IV) - uint min_key_version; // min key version for this space - ulint page0_offset; // byte offset on page 0 for crypt data - - ib_mutex_t mutex; // mutex protecting following variables - bool closing; // is tablespace being closed - fil_space_rotate_state_t rotate_state; - - uint iv_length; // length of IV - byte iv[1]; // IV-data -}; - /********************************************************************* Init space crypt */ UNIV_INTERN void fil_space_crypt_init() +/*==================*/ { mutex_create(fil_crypt_key_mutex_key, &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK); @@ -196,6 +137,7 @@ Cleanup space crypt */ UNIV_INTERN void fil_space_crypt_cleanup() +/*=====================*/ { os_event_free(fil_crypt_throttle_sleep_event); } @@ -204,94 +146,75 @@ fil_space_crypt_cleanup() Get key bytes for a space/key-version */ static void -fil_crypt_get_key(byte *dst, uint* key_length, - fil_space_crypt_t* crypt_data, uint version, bool page_encrypted) +fil_crypt_get_key( +/*==============*/ + byte* dst, /*mutex); - if (!page_encrypted) { - // Check if we already have key - for (uint i = 0; i < crypt_data->key_count; i++) { - if (crypt_data->keys[i].key_version == version) { - memcpy(dst, crypt_data->keys[i].key, - sizeof(crypt_data->keys[i].key)); - mutex_exit(&crypt_data->mutex); - return; - } + // Check if we already have key + for (uint i = 0; i < crypt_data->key_count; i++) { + if (crypt_data->keys[i].key_version == version) { + memcpy(dst, crypt_data->keys[i].key, + crypt_data->keys[i].key_length); + *key_length = crypt_data->keys[i].key_length; + mutex_exit(&crypt_data->mutex); + return; } - // Not found! - crypt_data->keyserver_requests++; + } - // Rotate keys to make room for a new - for (uint i = 1; i < array_elements(crypt_data->keys); i++) { - crypt_data->keys[i] = crypt_data->keys[i - 1]; - } - } + // Not found! + crypt_data->keyserver_requests++; - if (has_encryption_key(version)) { - int rc; - *key_length = get_encryption_key_size(version); + // Rotate keys to make room for a new + for (uint i = 1; i < array_elements(crypt_data->keys); i++) { + crypt_data->keys[i] = crypt_data->keys[i - 1]; + } - rc = get_encryption_key(version, (unsigned char*)keybuf, *key_length); - - if (rc != CRYPT_KEY_OK) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Key %d can not be found. Reason=%d", version, rc); - ut_error; - } - } else { + *key_length = sizeof(keybuf); + uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length); + if (rc) { ib_logf(IB_LOG_LEVEL_FATAL, - "Key %d not found", version); + "Key id %u version %u can not be found. Reason=%u", + crypt_data->key_id, version, rc); ut_error; } + /* Now compute L by encrypting IV using this key. Note + that we use random IV from crypt data. */ + const unsigned char* src = crypt_data->iv; + const int srclen = crypt_data->iv_length; + unsigned char* buf = crypt_data->keys[0].key; + uint32 buflen = CRYPT_SCHEME_1_IV_LEN; - // do ctr key initialization - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) - { - /* Now compute L by encrypting IV using this key. Note - that we use random IV from crypt data. */ - const unsigned char* src = crypt_data->iv; - const int srclen = crypt_data->iv_length; - unsigned char* buf = page_encrypted ? keybuf : crypt_data->keys[0].key; - uint32 buflen = page_encrypted ? *key_length : sizeof(crypt_data->keys[0].key); + /* We use AES_ECB to encrypt IV */ + rc = my_aes_encrypt_ecb(src, srclen, buf, &buflen, + keybuf, *key_length, NULL, 0, 1); - // call ecb explicit - my_aes_encrypt_dynamic_type func = get_aes_encrypt_func(MY_AES_ALGORITHM_ECB); - int rc = (*func)(src, srclen, - buf, &buflen, - (unsigned char*)keybuf, *key_length, - NULL, 0, - 1); - - if (rc != AES_OK) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Unable to encrypt key-block " - " src: %p srclen: %d buf: %p buflen: %d." - " return-code: %d. Can't continue!\n", - src, srclen, buf, buflen, rc); - ut_error; - } - - if (!page_encrypted) { - crypt_data->keys[0].key_version = version; - crypt_data->key_count++; - - if (crypt_data->key_count > array_elements(crypt_data->keys)) { - crypt_data->key_count = array_elements(crypt_data->keys); - } - } - - // set the key size to the aes block size because this encrypted data is the key - *key_length = MY_AES_BLOCK_SIZE; - memcpy(dst, buf, buflen); - } else { - // otherwise keybuf contains the right key - memcpy(dst, keybuf, *key_length); + if (rc != MY_AES_OK) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Unable to encrypt key-block " + " src: %p srclen: %d buf: %p buflen: %d." + " return-code: %d. Can't continue!\n", + src, srclen, buf, buflen, rc); + ut_error; } + crypt_data->keys[0].key_version = version; + crypt_data->key_count++; + *key_length = buflen; + crypt_data->keys[0].key_length = buflen; + + if (crypt_data->key_count > array_elements(crypt_data->keys)) { + crypt_data->key_count = array_elements(crypt_data->keys); + } + + memcpy(dst, buf, buflen); mutex_exit(&crypt_data->mutex); } @@ -299,46 +222,55 @@ fil_crypt_get_key(byte *dst, uint* key_length, Get key bytes for a space/latest(key-version) */ static inline void -fil_crypt_get_latest_key(byte *dst, uint* key_length, - fil_space_crypt_t* crypt_data, uint *version) +fil_crypt_get_latest_key( +/*=====================*/ + byte* dst, /*!< out: Key */ + uint* key_length, /*!< out: Key length */ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + uint* version) /*!< in: Key version */ { - if (srv_encrypt_tables) { - // used for key rotation - get the next key id from the key provider - int rc = get_latest_encryption_key_version(); + // used for key rotation - get the next key id from the key provider + uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id); - // if no new key was created use the last one - if (rc >= 0) { - *version = rc; - } + if (rc == ENCRYPTION_KEY_VERSION_INVALID) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Unknown key id %u. Can't continue!\n", + crypt_data->key_id); + ut_error; } - return fil_crypt_get_key(dst, key_length, crypt_data, *version, srv_encrypt_tables == FALSE); + return fil_crypt_get_key(dst, key_length, crypt_data, *version); } /****************************************************************** -Create a fil_space_crypt_t object */ +Create a fil_space_crypt_t object +@return crypt object */ UNIV_INTERN fil_space_crypt_t* -fil_space_create_crypt_data() +fil_space_create_crypt_data(uint key_id) +/*=========================*/ { const uint iv_length = CRYPT_SCHEME_1_IV_LEN; const uint sz = sizeof(fil_space_crypt_t) + iv_length; fil_space_crypt_t* crypt_data = static_cast(malloc(sz)); + memset(crypt_data, 0, sz); - if (srv_encrypt_tables == FALSE) { + if (!srv_encrypt_tables) { crypt_data->type = CRYPT_SCHEME_UNENCRYPTED; crypt_data->min_key_version = 0; } else { crypt_data->type = CRYPT_SCHEME_1; - crypt_data->min_key_version = get_latest_encryption_key_version(); + crypt_data->key_id = key_id; + crypt_data->min_key_version = encryption_key_get_latest_version(key_id); } mutex_create(fil_crypt_data_mutex_key, &crypt_data->mutex, SYNC_NO_ORDER_CHECK); crypt_data->iv_length = iv_length; my_random_bytes(crypt_data->iv, iv_length); + crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT; return crypt_data; } @@ -346,11 +278,14 @@ fil_space_create_crypt_data() Compare two crypt objects */ UNIV_INTERN int -fil_space_crypt_compare(const fil_space_crypt_t* crypt_data1, - const fil_space_crypt_t* crypt_data2) +fil_space_crypt_compare( +/*====================*/ + const fil_space_crypt_t* crypt_data1,/*!< in: Crypt data */ + const fil_space_crypt_t* crypt_data2)/*!< in: Crypt data */ { ut_a(crypt_data1->type == CRYPT_SCHEME_UNENCRYPTED || crypt_data1->type == CRYPT_SCHEME_1); + ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED || crypt_data2->type == CRYPT_SCHEME_1); @@ -365,10 +300,15 @@ fil_space_crypt_compare(const fil_space_crypt_t* crypt_data1, } /****************************************************************** -Read crypt data from a page (0) */ +Read crypt data from a page (0) +@return crypt data from page 0. */ UNIV_INTERN fil_space_crypt_t* -fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) +fil_space_read_crypt_data( +/*======================*/ + ulint space, /*!< in: file space id*/ + const byte* page, /*!< in: page 0 */ + ulint offset) /*!< in: offset */ { if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) { /* crypt is not stored */ @@ -395,6 +335,7 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) if (! (type == CRYPT_SCHEME_UNENCRYPTED || type == CRYPT_SCHEME_1)) { + ib_logf(IB_LOG_LEVEL_ERROR, "Found non sensible crypt scheme: %lu for space %lu " " offset: %lu bytes: " @@ -429,6 +370,12 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) uint min_key_version = mach_read_from_4 (page + offset + MAGIC_SZ + 2 + iv_length); + uint key_id = mach_read_from_4 + (page + offset + MAGIC_SZ + 2 + iv_length + 4); + + fil_encryption_t encryption = (fil_encryption_t)mach_read_from_1( + page + offset + MAGIC_SZ + 2 + iv_length + 8); + const uint sz = sizeof(fil_space_crypt_t) + iv_length; fil_space_crypt_t* crypt_data = static_cast( malloc(sz)); @@ -436,7 +383,9 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) crypt_data->type = type; crypt_data->min_key_version = min_key_version; + crypt_data->key_id = key_id; crypt_data->page0_offset = offset; + crypt_data->encryption = encryption; mutex_create(fil_crypt_data_mutex_key, &crypt_data->mutex, SYNC_NO_ORDER_CHECK); crypt_data->iv_length = iv_length; @@ -449,13 +398,11 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) Free a crypt data object */ UNIV_INTERN void -fil_space_destroy_crypt_data(fil_space_crypt_t **crypt_data) +fil_space_destroy_crypt_data( +/*=========================*/ + fil_space_crypt_t **crypt_data) /*!< out: crypt data */ { if (crypt_data != NULL && (*crypt_data) != NULL) { - /* lock (and unlock) mutex to make sure no one has it locked - * currently */ - mutex_enter(& (*crypt_data)->mutex); - mutex_exit(& (*crypt_data)->mutex); mutex_free(& (*crypt_data)->mutex); free(*crypt_data); (*crypt_data) = NULL; @@ -466,18 +413,24 @@ fil_space_destroy_crypt_data(fil_space_crypt_t **crypt_data) Write crypt data to a page (0) */ static void -fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, - ulint type, - byte* page, ulint offset, - ulint maxsize, mtr_t* mtr) +fil_space_write_crypt_data_low( +/*===========================*/ + fil_space_crypt_t* crypt_data, /* 0 && offset < UNIV_PAGE_SIZE); ulint space_id = mach_read_from_4( page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); const uint len = crypt_data->iv_length; const uint min_key_version = crypt_data->min_key_version; + const uint key_id = crypt_data->key_id; + const fil_encryption_t encryption = crypt_data->encryption; crypt_data->page0_offset = offset; - ut_a(2 + len + 4 + MAGIC_SZ < maxsize); + ut_a(2 + len + 4 + 1 + 4 + MAGIC_SZ < maxsize); /* redo log this as bytewise updates to page 0 @@ -491,11 +444,13 @@ fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, mtr); mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len, min_key_version, MLOG_4BYTES, mtr); + mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len, key_id, + MLOG_4BYTES, mtr); + mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len + 8, encryption, + MLOG_1BYTE, mtr); - DBUG_EXECUTE_IF("ib_file_crypt_redo_crash_1", - ut_error;); + byte* log_ptr = mlog_open(mtr, 11 + 17 + len); - byte* log_ptr = mlog_open(mtr, 11 + 12 + len); if (log_ptr != NULL) { log_ptr = mlog_write_initial_log_record_fast( page, @@ -511,29 +466,34 @@ fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, log_ptr += 1; mach_write_to_4(log_ptr, min_key_version); log_ptr += 4; + mach_write_to_4(log_ptr, key_id); + log_ptr += 4; + mach_write_to_1(log_ptr, encryption); + log_ptr += 1; mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, crypt_data->iv, len); } - - DBUG_EXECUTE_IF("ib_file_crypt_redo_crash_2", - ut_error;); } /****************************************************************** Write crypt data to a page (0) */ UNIV_INTERN void -fil_space_write_crypt_data(ulint space, byte* page, ulint offset, - ulint maxsize, mtr_t* mtr) +fil_space_write_crypt_data( +/*=======================*/ + ulint space, /*page0_offset = offset; crypt_data->min_key_version = min_key_version; + crypt_data->encryption = encryption; memcpy(crypt_data->iv, ptr, len); ptr += len; @@ -595,7 +569,10 @@ fil_parse_write_crypt_data(byte* ptr, byte* end_ptr, Clear crypt data from a page (0) */ UNIV_INTERN void -fil_space_clear_crypt_data(byte* page, ulint offset) +fil_space_clear_crypt_data( +/*=======================*/ + byte* page, /*!< in/out: Page 0 */ + ulint offset) /*!< in: Offset */ { //TODO(jonaso): pass crypt-data and read len from there ulint len = CRYPT_SCHEME_1_IV_LEN; @@ -604,19 +581,22 @@ fil_space_clear_crypt_data(byte* page, ulint offset) 1 + // type 1 + // len len + // iv - 4; // min key version + 4 + // min key version + 4 + // key id + 1; // fil_encryption_t memset(page + offset, 0, size); } /********************************************************************* -Check if page shall be encrypted before write */ +Check if page shall be encrypted before write +@return true if page should be encrypted, false if not */ UNIV_INTERN bool fil_space_check_encryption_write( /*==============================*/ ulint space) /*!< in: tablespace id */ { - if (srv_encrypt_tables == FALSE) + if (!srv_encrypt_tables) return false; fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -636,23 +616,29 @@ fil_space_check_encryption_write( Encrypt a page */ UNIV_INTERN void -fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, - const byte* src_frame, ulint zip_size, byte* dst_frame, ulint encryption_key) +fil_space_encrypt( +/*==============*/ + ulint space, /*!< in: Space id */ + ulint offset, /*!< in: Page offset */ + lsn_t lsn, /*!< in: lsn */ + const byte* src_frame, /*!< in: Source page to be encrypted */ + ulint zip_size, /*!< in: compressed size if + row_format compressed */ + byte* dst_frame) /*!< in: outbut buffer */ { - fil_space_crypt_t* crypt_data=NULL; + fil_space_crypt_t* crypt_data = NULL; ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; - - // get key (L) - uint key_version = encryption_key; - byte key[MY_AES_MAX_KEY_LENGTH]; - uint key_length=MY_AES_MAX_KEY_LENGTH; + uint key_version; + unsigned char key[MY_AES_MAX_KEY_LENGTH]; + uint key_length = MY_AES_MAX_KEY_LENGTH; + unsigned char iv[MY_AES_BLOCK_SIZE]; ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); if (orig_page_type==FIL_PAGE_TYPE_FSP_HDR - || orig_page_type==FIL_PAGE_TYPE_XDES - || orig_page_type== FIL_PAGE_PAGE_ENCRYPTED - || orig_page_type== FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { + || orig_page_type==FIL_PAGE_TYPE_XDES) { + /* File space header or extent descriptor do not need to be + encrypted. */ //TODO: is this really needed ? memcpy(dst_frame, src_frame, page_size); return; @@ -669,63 +655,42 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version); - /* Load the iv or counter (depending to the encryption algorithm used) */ - unsigned char iv[MY_AES_BLOCK_SIZE]; - - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) { - // create counter block (C) - mach_write_to_4(iv + 0, space); - ulint space_offset = mach_read_from_4( - src_frame + FIL_PAGE_OFFSET); - mach_write_to_4(iv + 4, space_offset); - mach_write_to_8(iv + 8, lsn); - } else { - // Get random IV from crypt_data - mutex_enter(&crypt_data->mutex); - memcpy(iv, crypt_data->iv, crypt_data->iv_length); - mutex_exit(&crypt_data->mutex); - } + /* create iv/counter */ + mach_write_to_4(iv + 0, space); + mach_write_to_4(iv + 4, offset); + mach_write_to_8(iv + 8, lsn); ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED); - ibool page_encrypted = fil_space_is_page_encrypted(space); - ulint compression_alg = mach_read_from_8(src_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - // copy page header + /* FIL page header is not encrypted */ memcpy(dst_frame, src_frame, FIL_PAGE_DATA); - if (page_encrypted && !page_compressed) { - // key id - mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - key_version); - // original page type - mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2, - orig_page_type); - // new page type - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_ENCRYPTED); - } else { - // store key version - mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - key_version); - } + /* Store key version */ + mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, key_version); - // encrypt page data + /* Calculate the start offset in a page */ ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END; ulint srclen = page_size - unencrypted_bytes; const byte* src = src_frame + FIL_PAGE_DATA; byte* dst = dst_frame + FIL_PAGE_DATA; - uint32 dstlen; + uint32 dstlen = 0; + /* For page compressed tables we encrypt only the actual compressed + payload. Note that first two bytes of page data is actual payload + size and that should not be encrypted. */ if (page_compressed) { - srclen = page_size - FIL_PAGE_DATA; + ulint payload = mach_read_from_2(src_frame + FIL_PAGE_DATA); + mach_write_to_2(dst_frame + FIL_PAGE_DATA, payload); + srclen = payload; + src+=2; + dst+=2; } - int rc = (* my_aes_encrypt_dynamic)(src, srclen, - dst, &dstlen, - (unsigned char*)key, key_length, - (unsigned char*)iv, sizeof(iv), - 1); + int rc = encryption_encrypt(src, srclen, dst, &dstlen, + key, key_length, iv, sizeof(iv), 1, + crypt_data->key_id, key_version); - if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) { + if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { ib_logf(IB_LOG_LEVEL_FATAL, "Unable to encrypt data-block " " src: %p srclen: %ld buf: %p buflen: %d." @@ -735,8 +700,12 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, ut_error; } + /* For compressed tables we do not store the FIL header because + the whole page is not stored to the disk. In compressed tables only + the FIL header + compressed (and now encrypted) payload alligned + to sector boundary is written. */ if (!page_compressed) { - // copy page trailer + /* FIL page trailer is also not encrypted */ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END, src_frame + page_size - FIL_PAGE_DATA_END, FIL_PAGE_DATA_END); @@ -772,28 +741,18 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, // store the post-encryption checksum after the key-version mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum); - } else { - /* Page compressed and encrypted tables have different - FIL_HEADER */ - ulint page_len = log10((double)page_size)/log10((double)2); - /* Set up the correct page type */ - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); - /* Set up the compression algorithm */ - mach_write_to_2(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4, orig_page_type); - /* Set up the compressed size */ - mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6, page_len); - /* Set up the compression method */ - mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7, compression_alg); } + srv_stats.pages_encrypted.inc(); } /********************************************************************* -Check if extra buffer shall be allocated for decrypting after read */ +Check if extra buffer shall be allocated for decrypting after read +@return true if fil space has encryption data. */ UNIV_INTERN bool fil_space_check_encryption_read( -/*==============================*/ +/*=============================*/ ulint space) /*!< in: tablespace id */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -806,107 +765,78 @@ fil_space_check_encryption_read( return false; } + if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + return false; + } + return true; } /****************************************************************** -Decrypt a page */ +Decrypt a page +@return true if page was encrypted */ UNIV_INTERN bool -fil_space_decrypt(fil_space_crypt_t* crypt_data, - const byte* src_frame, ulint page_size, byte* dst_frame) +fil_space_decrypt( +/*==============*/ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + const byte* src_frame, /*!< in: input buffer */ + ulint page_size, /*!< in: page size */ + byte* dst_frame) /*!< out: output buffer */ { ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); - // key version - uint key_version; - bool page_encrypted = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED - || page_type == FIL_PAGE_PAGE_ENCRYPTED); + uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED); - bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED - || page_type == FIL_PAGE_PAGE_COMPRESSED); - - ulint orig_page_type=0; - - if (page_type == FIL_PAGE_PAGE_ENCRYPTED) { - key_version = mach_read_from_2( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - orig_page_type = mach_read_from_2( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2); - } else { - key_version = mach_read_from_4( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - } - - if (key_version == 0 && !page_encrypted) { + if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) { //TODO: is this really needed ? memcpy(dst_frame, src_frame, page_size); return false; /* page not decrypted */ } - // read space & offset & lsn + /* read space & offset & lsn */ ulint space = mach_read_from_4( src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); ulint offset = mach_read_from_4( src_frame + FIL_PAGE_OFFSET); ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN); - // copy page header + /* Copy FIL page header, it is not encrypted */ memcpy(dst_frame, src_frame, FIL_PAGE_DATA); - if (page_type == FIL_PAGE_PAGE_ENCRYPTED) { - // orig page type - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, orig_page_type); - } - - // get key + /* Get key */ byte key[MY_AES_MAX_KEY_LENGTH]; uint key_length; - fil_crypt_get_key(key, &key_length, crypt_data, key_version, page_encrypted); - - // get the iv unsigned char iv[MY_AES_BLOCK_SIZE]; + fil_crypt_get_key(key, &key_length, crypt_data, key_version); - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) { - // create counter block - - mach_write_to_4(iv + 0, space); - mach_write_to_4(iv + 4, offset); - mach_write_to_8(iv + 8, lsn); - } else { - // Get random IV from crypt_data - mutex_enter(&crypt_data->mutex); - memcpy(iv, crypt_data->iv, crypt_data->iv_length); - mutex_exit(&crypt_data->mutex); - } + /* create iv/counter */ + mach_write_to_4(iv + 0, space); + mach_write_to_4(iv + 4, offset); + mach_write_to_8(iv + 8, lsn); + /* Calculate the offset where decryption starts */ const byte* src = src_frame + FIL_PAGE_DATA; byte* dst = dst_frame + FIL_PAGE_DATA; - uint32 dstlen; + uint32 dstlen = 0; ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END); - ulint compressed_len; - ulint compression_method; + /* For page compressed tables we decrypt only the actual compressed + payload. Note that first two bytes of page data is actual payload + size and that should not be decrypted. */ if (page_compressed) { - orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4); - compressed_len = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6); - compression_method = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7); + ulint compressed_len = mach_read_from_2(src_frame + FIL_PAGE_DATA); + src+=2; + dst+=2; + mach_write_to_2(dst_frame + FIL_PAGE_DATA, compressed_len); + srclen = compressed_len; } - if (page_encrypted && !page_compressed) { - orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+2); - } + int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length, + iv, sizeof(iv), 1, + crypt_data->key_id, key_version); - if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - srclen = pow((double)2, (double)((int)compressed_len)) - FIL_PAGE_DATA; - } - - int rc = (* my_aes_decrypt_dynamic)(src, srclen, - dst, &dstlen, - (unsigned char*)key, key_length, - (unsigned char*)iv, sizeof(iv), - 1); - - if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) { + if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { ib_logf(IB_LOG_LEVEL_FATAL, "Unable to decrypt data-block " " src: %p srclen: %ld buf: %p buflen: %d." @@ -916,24 +846,22 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data, ut_error; } - if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - // copy page trailer + /* For compressed tables we do not store the FIL header because + the whole page is not stored to the disk. In compressed tables only + the FIL header + compressed (and now encrypted) payload alligned + to sector boundary is written. */ + if (!page_compressed) { + /* Copy FIL trailer */ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END, src_frame + page_size - FIL_PAGE_DATA_END, FIL_PAGE_DATA_END); // clear key-version & crypt-checksum from dst memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8); - } else { - /* For page compressed tables we set up the FIL_HEADER again */ - /* setting original page type */ - mach_write_to_2(dst_frame + FIL_PAGE_TYPE, orig_page_type); - /* page_compression uses BUF_NO_CHECKSUM_MAGIC as checksum */ - mach_write_to_4(dst_frame + FIL_PAGE_SPACE_OR_CHKSUM, BUF_NO_CHECKSUM_MAGIC); - /* Set up the flush lsn to be compression algorithm */ - mach_write_to_8(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, compression_method); } + srv_stats.pages_decrypted.inc(); + return true; /* page was decrypted */ } @@ -941,8 +869,12 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data, Decrypt a page */ UNIV_INTERN void -fil_space_decrypt(ulint space, - const byte* src_frame, ulint page_size, byte* dst_frame) +fil_space_decrypt( +/*==============*/ + ulint space, /*!< in: Fil space id */ + const byte* src_frame, /*!< in: input buffer */ + ulint page_size, /*!< in: page size */ + byte* dst_frame) /*!< out: output buffer */ { fil_space_decrypt(fil_space_get_crypt_data(space), src_frame, page_size, dst_frame); @@ -953,8 +885,13 @@ Verify checksum for a page (iff it's encrypted) NOTE: currently this function can only be run in single threaded mode as it modifies srv_checksum_algorithm (temporarily) @return true if page is encrypted AND OK, false otherwise */ +UNIV_INTERN bool -fil_space_verify_crypt_checksum(const byte* src_frame, ulint zip_size) +fil_space_verify_crypt_checksum( +/*============================*/ + const byte* src_frame, /*!< in: page the verify */ + ulint zip_size) /*!< in: compressed size if + row_format compressed */ { // key version uint key_version = mach_read_from_4( @@ -1041,12 +978,15 @@ struct key_state_t { Copy global key state */ static void fil_crypt_get_key_state( - key_state_t *new_state) +/*====================*/ + key_state_t *new_state) /*!< out: key state */ { - if (srv_encrypt_tables == TRUE) { - new_state->key_version = get_latest_encryption_key_version(); + if (srv_encrypt_tables) { + new_state->key_version = + encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; - ut_a(new_state->key_version > 0); + ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID); + ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED); } else { new_state->key_version = 0; new_state->rotate_key_age = 0; @@ -1054,9 +994,13 @@ fil_crypt_get_key_state( } /*********************************************************************** -Check if a key needs rotation given a key_state */ +Check if a key needs rotation given a key_state +@return true if key needs rotation, false if not */ static bool -fil_crypt_needs_rotation(uint key_version, const key_state_t *key_state) +fil_crypt_needs_rotation( +/*=====================*/ + uint key_version, /*!< in: Key version */ + const key_state_t* key_state) /*!< in: Key state */ { // TODO(jonaso): Add support for rotating encrypted => unencrypted @@ -1081,9 +1025,13 @@ fil_crypt_needs_rotation(uint key_version, const key_state_t *key_state) } /*********************************************************************** -Check if a space is closing (i.e just before drop) */ -UNIV_INTERN bool -fil_crypt_is_closing(ulint space) +Check if a space is closing (i.e just before drop) +@return true if space is closing, false if not. */ +UNIV_INTERN +bool +fil_crypt_is_closing( +/*=================*/ + ulint space) /*!< in: FIL space id */ { bool closing; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -1097,8 +1045,13 @@ fil_crypt_is_closing(ulint space) Start encrypting a space @return true if a pending op (fil_inc_pending_ops/fil_decr_pending_ops) is held */ -static bool -fil_crypt_start_encrypting_space(ulint space, bool *recheck) { +static +bool +fil_crypt_start_encrypting_space( +/*=============================*/ + ulint space, /*!< in: FIL space id */ + bool* recheck)/*!< out: true if recheck needed */ +{ /* we have a pending op when entering function */ bool pending_op = true; @@ -1106,7 +1059,7 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); - ibool page_encrypted = fil_space_is_page_encrypted(space); + ibool page_encrypted = (crypt_data != NULL); /*If spage is not encrypted and encryption is not enabled, then do not continue encrypting the space. */ @@ -1131,7 +1084,7 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { * crypt data in page 0 */ /* 1 - create crypt data */ - crypt_data = fil_space_create_crypt_data(); + crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY); if (crypt_data == NULL) { mutex_exit(&fil_crypt_threads_mutex); return pending_op; @@ -1257,10 +1210,14 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { } /*********************************************************************** -Check if space needs rotation given a key_state */ -static bool -fil_crypt_space_needs_rotation(uint space, const key_state_t *key_state, - bool *recheck) +Check if space needs rotation given a key_state +@return true if space needs key rotation */ +static +bool +fil_crypt_space_needs_rotation( + uint space, /*!< in: FIL space id */ + const key_state_t* key_state, /*!< in: Key state */ + bool* recheck) /*!< out: needs recheck ? */ { if (fil_space_get_type(space) != FIL_TABLESPACE) { return false; @@ -1296,6 +1253,11 @@ fil_crypt_space_needs_rotation(uint space, const key_state_t *key_state, mutex_enter(&crypt_data->mutex); do { + if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + /* This space is unencrypted by user request */ + break; + } + /* prevent threads from starting to rotate space */ if (crypt_data->rotate_state.starting) { /* recheck this space later */ @@ -1374,7 +1336,9 @@ struct rotate_thread_t { /*********************************************************************** Update global statistics with thread statistics */ static void -fil_crypt_update_total_stat(rotate_thread_t *state) +fil_crypt_update_total_stat( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { mutex_enter(&crypt_stat_mutex); crypt_stat.pages_read_from_cache += @@ -1397,9 +1361,13 @@ fil_crypt_update_total_stat(rotate_thread_t *state) /*********************************************************************** Allocate iops to thread from global setting, -used before starting to rotate a space */ -static bool -fil_crypt_alloc_iops(rotate_thread_t *state) +used before starting to rotate a space. +@return true if allocation succeeded, false if failed */ +static +bool +fil_crypt_alloc_iops( +/*=================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { ut_ad(state->allocated_iops == 0); @@ -1429,8 +1397,11 @@ fil_crypt_alloc_iops(rotate_thread_t *state) /*********************************************************************** Reallocate iops to thread, used when inside a space */ -static void -fil_crypt_realloc_iops(rotate_thread_t *state) +static +void +fil_crypt_realloc_iops( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { ut_a(state->allocated_iops > 0); @@ -1519,8 +1490,11 @@ fil_crypt_realloc_iops(rotate_thread_t *state) /*********************************************************************** Return allocated iops to global */ -static void -fil_crypt_return_iops(rotate_thread_t *state) +static +void +fil_crypt_return_iops( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { if (state->allocated_iops > 0) { uint iops = state->allocated_iops; @@ -1544,11 +1518,14 @@ fil_crypt_return_iops(rotate_thread_t *state) /*********************************************************************** Search for a space needing rotation */ +UNIV_INTERN bool fil_crypt_find_space_to_rotate( - const key_state_t *key_state, - rotate_thread_t *state, - bool *recheck) +/*===========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state, /*!< in: Key rotation state */ + bool* recheck) /*!< out: true if recheck + needed */ { /* we need iops to start rotating */ while (!state->should_shutdown() && !fil_crypt_alloc_iops(state)) { @@ -1591,8 +1568,9 @@ Start rotating a space */ static void fil_crypt_start_rotate_space( - const key_state_t *key_state, - rotate_thread_t *state) +/*=========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -1629,12 +1607,14 @@ fil_crypt_start_rotate_space( } /*********************************************************************** -Search for batch of pages needing rotation */ +Search for batch of pages needing rotation +@return true if page needing key rotation found, false if not found */ static bool fil_crypt_find_page_to_rotate( - const key_state_t *key_state, - rotate_thread_t *state) +/*==========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint batch = srv_alloc_time * state->allocated_iops; ulint space = state->space; @@ -1665,9 +1645,15 @@ fil_crypt_find_page_to_rotate( } /*********************************************************************** -Check if a page is uninitialized (doesn't need to be rotated) */ -static bool -fil_crypt_is_page_uninitialized(const byte* frame, uint zip_size) +Check if a page is uninitialized (doesn't need to be rotated) +@return true if page is uninitialized, false if not.*/ +static +bool +fil_crypt_is_page_uninitialized( +/*============================*/ + const byte *frame, /*!< in: Page */ + uint zip_size) /*!< in: compressed size if + row_format compressed */ { if (zip_size) { ulint stored_checksum = mach_read_from_4( @@ -1696,15 +1682,20 @@ fil_crypt_is_page_uninitialized(const byte* frame, uint zip_size) sleeptime_ms, __FILE__, __LINE__) /*********************************************************************** -Get a page and compute sleep time */ +Get a page and compute sleep time +@return page */ static buf_block_t* -fil_crypt_get_page_throttle_func(rotate_thread_t *state, - ulint space, uint zip_size, ulint offset, - mtr_t *mtr, - ulint *sleeptime_ms, - const char *file, - ulint line) +fil_crypt_get_page_throttle_func( + rotate_thread_t* state, /*!< in/out: Key rotation state */ + ulint space, /*!< in: FIL space id */ + uint zip_size, /*!< in: compressed size if + row_format compressed */ + ulint offset, /*!< in: page offsett */ + mtr_t* mtr, /*!< in/out: minitransaction */ + ulint* sleeptime_ms, /*!< out: sleep time */ + const char* file, /*!< in: file name */ + ulint line) /*!< in: file line */ { buf_block_t* block = buf_page_try_get_func(space, offset, RW_X_LATCH, true, @@ -1753,17 +1744,22 @@ Get block and allocation status note: innodb locks fil_space_latch and then block when allocating page but locks block and then fil_space_latch when freeing page. +@return block */ static buf_block_t* btr_scrub_get_block_and_allocation_status( - rotate_thread_t *state, - ulint space, - ulint zip_size, - ulint offset, - mtr_t *mtr, +/*======================================*/ + rotate_thread_t* state, /*!< in/out: Key rotation state */ + ulint space, /*!< in: FIL space id */ + uint zip_size, /*!< in: compressed size if + row_format compressed */ + ulint offset, /*!< in: page offsett */ + mtr_t* mtr, /*!< in/out: minitransaction + */ btr_scrub_page_allocation_status_t *allocation_status, - ulint *sleeptime_ms) + /*!< in/out: allocation status */ + ulint* sleeptime_ms) /*!< out: sleep time */ { mtr_t local_mtr; buf_block_t *block = NULL; @@ -1807,8 +1803,9 @@ Rotate one page */ static void fil_crypt_rotate_page( - const key_state_t *key_state, - rotate_thread_t *state) +/*===================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; ulint offset = state->offset; @@ -1960,8 +1957,9 @@ Rotate a batch of pages */ static void fil_crypt_rotate_pages( - const key_state_t *key_state, - rotate_thread_t *state) +/*===================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; ulint end = state->offset + state->batch; @@ -1989,7 +1987,10 @@ fil_crypt_rotate_pages( Flush rotated pages and then update page 0 */ static void -fil_crypt_flush_space(rotate_thread_t *state, ulint space) +fil_crypt_flush_space( +/*==================*/ + rotate_thread_t* state, /*!< in: Key rotation state */ + ulint space) /*!< in: FIL space id */ { fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -2033,9 +2034,10 @@ fil_crypt_flush_space(rotate_thread_t *state, ulint space) RW_X_LATCH, NULL, BUF_GET, __FILE__, __LINE__, &mtr); byte* frame = buf_block_get_frame(block); - ulint maxsize = 0; + ulint maxsize; crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); + fil_space_write_crypt_data(space, frame, crypt_data->page0_offset, ULINT_MAX, &mtr); @@ -2048,8 +2050,9 @@ Complete rotating a space */ static void fil_crypt_complete_rotate_space( - const key_state_t *key_state, - rotate_thread_t *state) +/*============================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -2123,7 +2126,7 @@ A thread which monitors global key state and rotates tablespaces accordingly extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(fil_crypt_thread)( -/*===============================*/ +/*=============================*/ void* arg __attribute__((unused))) /*!< in: a dummy parameter required * by os_thread_create */ { @@ -2240,13 +2243,19 @@ DECLARE_THREAD(fil_crypt_thread)( Adjust thread count for key rotation */ UNIV_INTERN void -fil_crypt_set_thread_cnt(uint new_cnt) +fil_crypt_set_thread_cnt( +/*=====================*/ + uint new_cnt) /*!< in: New key rotation thread count */ { if (new_cnt > srv_n_fil_crypt_threads) { uint add = new_cnt - srv_n_fil_crypt_threads; srv_n_fil_crypt_threads = new_cnt; for (uint i = 0; i < add; i++) { - os_thread_create(fil_crypt_thread, NULL, NULL); + os_thread_id_t rotation_thread_id; + os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); + ib_logf(IB_LOG_LEVEL_INFO, + "Creating #%d thread id %lu total threads %du\n", + i, os_thread_pf(rotation_thread_id), new_cnt); } } else if (new_cnt < srv_n_fil_crypt_threads) { srv_n_fil_crypt_threads = new_cnt; @@ -2263,7 +2272,9 @@ fil_crypt_set_thread_cnt(uint new_cnt) Adjust max key age */ UNIV_INTERN void -fil_crypt_set_rotate_key_age(uint val) +fil_crypt_set_rotate_key_age( +/*=========================*/ + uint val) /*!< in: New max key age */ { srv_fil_crypt_rotate_key_age = val; os_event_set(fil_crypt_threads_event); @@ -2273,7 +2284,9 @@ fil_crypt_set_rotate_key_age(uint val) Adjust rotation iops */ UNIV_INTERN void -fil_crypt_set_rotation_iops(uint val) +fil_crypt_set_rotation_iops( +/*========================*/ + uint val) /*!< in: New iops setting */ { srv_n_fil_crypt_iops = val; os_event_set(fil_crypt_threads_event); @@ -2284,6 +2297,7 @@ Init threads for key rotation */ UNIV_INTERN void fil_crypt_threads_init() +/*====================*/ { fil_crypt_event = os_event_create(); fil_crypt_threads_event = os_event_create(); @@ -2300,6 +2314,7 @@ End threads for key rotation */ UNIV_INTERN void fil_crypt_threads_end() +/*===================*/ { /* stop threads */ fil_crypt_set_thread_cnt(0); @@ -2309,7 +2324,9 @@ fil_crypt_threads_end() Clean up key rotation threads resources */ UNIV_INTERN void -fil_crypt_threads_cleanup() { +fil_crypt_threads_cleanup() +/*=======================*/ +{ os_event_free(fil_crypt_event); os_event_free(fil_crypt_threads_event); } @@ -2319,7 +2336,8 @@ Mark a space as closing */ UNIV_INTERN void fil_space_crypt_mark_space_closing( - ulint space) +/*===============================*/ + ulint space) /*!< in: Space id */ { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -2340,7 +2358,8 @@ Wait for crypt threads to stop accessing space */ UNIV_INTERN void fil_space_crypt_close_tablespace( - ulint space) +/*=============================*/ + ulint space) /*!< in: Space id */ { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -2352,11 +2371,14 @@ fil_space_crypt_close_tablespace( uint start = time(0); uint last = start; + mutex_enter(&crypt_data->mutex); mutex_exit(&fil_crypt_threads_mutex); crypt_data->closing = true; + uint cnt = crypt_data->rotate_state.active_threads; bool flushing = crypt_data->rotate_state.flushing; + while (cnt > 0 || flushing) { mutex_exit(&crypt_data->mutex); /* release dict mutex so that scrub threads can release their @@ -2386,11 +2408,12 @@ fil_space_crypt_close_tablespace( /********************************************************************* Get crypt status for a space (used by information_schema) return 0 if crypt data present */ +UNIV_INTERN int fil_space_crypt_get_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_crypt_status_t* status) /*!< out: status */ +/*=======================*/ + ulint id, /*!< in: space id */ + struct fil_space_crypt_status_t* status) /*!< out: status */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(id); @@ -2400,6 +2423,7 @@ fil_space_crypt_get_status( mutex_enter(&crypt_data->mutex); status->keyserver_requests = crypt_data->keyserver_requests; status->min_key_version = crypt_data->min_key_version; + if (crypt_data->rotate_state.active_threads > 0 || crypt_data->rotate_state.flushing) { status->rotating = true; @@ -2413,22 +2437,27 @@ fil_space_crypt_get_status( status->rotating = false; } mutex_exit(&crypt_data->mutex); + + if (srv_encrypt_tables) { + status->current_key_version = + encryption_key_get_latest_version(crypt_data->key_id); + } else { + status->current_key_version = 0; + } } else { memset(status, 0, sizeof(*status)); } - if (srv_encrypt_tables == TRUE) { - status->current_key_version = get_latest_encryption_key_version(); - } else { - status->current_key_version = 0; - } return crypt_data == NULL ? 1 : 0; } /********************************************************************* Return crypt statistics */ +UNIV_INTERN void -fil_crypt_total_stat(fil_crypt_stat_t *stat) +fil_crypt_total_stat( +/*=================*/ + fil_crypt_stat_t *stat) /*!< out: Crypt statistics */ { mutex_enter(&crypt_stat_mutex); *stat = crypt_stat; @@ -2438,11 +2467,12 @@ fil_crypt_total_stat(fil_crypt_stat_t *stat) /********************************************************************* Get scrub status for a space (used by information_schema) return 0 if data found */ +UNIV_INTERN int fil_space_get_scrub_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_scrub_status_t* status) /*!< out: status */ +/*=======================*/ + ulint id, /*!< in: space id */ + struct fil_space_scrub_status_t* status) /*!< out: status */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(id); memset(status, 0, sizeof(*status)); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 8b0a788b7b9..172696df3ba 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -27,8 +27,7 @@ Created 10/25/1995 Heikki Tuuri #include "fil0fil.h" #include "fil0pagecompress.h" #include "fsp0pagecompress.h" -#include "fil0pageencryption.h" -#include "fsp0pageencryption.h" +#include "fil0crypt.h" #include #include @@ -284,7 +283,7 @@ fil_read( actual page size does not decrease. */ { return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset, - byte_offset, len, buf, message, write_size, 0, false)); + byte_offset, len, buf, message, write_size)); } /********************************************************************//** @@ -311,18 +310,16 @@ fil_write( this must be appropriately aligned */ void* message, /*!< in: message for aio handler if non-sync aio used, else ignored */ - ulint* write_size, /*!< in/out: Actual write size initialized + ulint* write_size) /*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: encrypt later ? */ { ut_ad(!srv_read_only_mode); return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset, - byte_offset, len, buf, message, write_size, lsn, encrypt_later)); + byte_offset, len, buf, message, write_size)); } /*******************************************************************//** @@ -648,22 +645,7 @@ fil_node_open_file( set */ page = static_cast(ut_align(buf2, UNIV_PAGE_SIZE)); - success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE, - space->flags); - - if (fil_page_encryption_status(page)) { - /* if page is (still) encrypted, write an error and return. - * Otherwise the server would crash if decrypting is not possible. - * This may be the case, if the key file could not be - * opened on server startup. - */ - ib_logf(IB_LOG_LEVEL_ERROR, - "InnoDB: can not decrypt page, because " - "keys could not be read.\n" - ); - return false; - - } + success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); space_id = fsp_header_get_space_id(page); flags = fsp_header_get_flags(page); @@ -1156,21 +1138,6 @@ fil_space_create( ut_a(fil_system); - if (fsp_flags_is_page_encrypted(flags)) { - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - /* by returning here it should be avoided that - * the server crashes, if someone tries to access an - * encrypted table and the encryption key is not available. - * The the table is treaded as non-existent. - */ - ib_logf(IB_LOG_LEVEL_WARN, - "Tablespace '%s' can not be opened, because " - " encryption key can not be found (space id: %lu, key %lu)\n" - , name, (ulong) id, fsp_flags_get_page_encryption_key(flags)); - return (FALSE); - } - } - /* Look for a matching tablespace and if found free it. */ do { mutex_enter(&fil_system->mutex); @@ -1836,7 +1803,7 @@ fil_write_lsn_and_arch_no_to_file( lsn); err = fil_write(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0, lsn, false); + UNIV_PAGE_SIZE, buf, NULL, 0); } mem_free(buf1); @@ -1915,7 +1882,6 @@ fil_check_first_page( { ulint space_id; ulint flags; - ulint page_is_encrypted; if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { return(NULL); @@ -1923,23 +1889,14 @@ fil_check_first_page( space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page); flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - /* Note: the 1st page is usually not encrypted. If the Key Provider - or the encryption key is not available, the - check for reading the first page should intentionally fail - with "can not decrypt" message. */ - page_is_encrypted = fil_page_encryption_status(page); - if (page_is_encrypted == PAGE_ENCRYPTION_KEY_MISSING && page_is_encrypted) { - page_is_encrypted = 1; - } else { - page_is_encrypted = 0; - if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { - fprintf(stderr, - "InnoDB: Error: Current page size %lu != " - " page size on page %lu\n", - UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags)); - return("innodb-page-size mismatch"); - } + if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { + fprintf(stderr, + "InnoDB: Error: Current page size %lu != " + " page size on page %lu\n", + UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags)); + + return("innodb-page-size mismatch"); } if (!space_id && !flags) { @@ -1955,17 +1912,9 @@ fil_check_first_page( } } - if (!page_is_encrypted && buf_page_is_corrupted( + if (buf_page_is_corrupted( false, page, fsp_flags_get_zip_size(flags))) { return("checksum mismatch"); - } else { - if (page_is_encrypted) { - /* this error message is interpreted by the calling method, which is - * executed if the server starts in recovery mode. - */ - return(MSG_CANNOT_DECRYPT); - - } } if (page_get_space_id(page) == space_id @@ -2009,6 +1958,7 @@ fil_read_first_page( byte* page; lsn_t flushed_lsn; const char* check_msg = NULL; + fil_space_crypt_t* cdata; buf = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); @@ -2016,10 +1966,7 @@ fil_read_first_page( page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); - os_file_read(data_file, page, 0, UNIV_PAGE_SIZE, - orig_space_id != ULINT_UNDEFINED ? - fil_space_is_page_compressed(orig_space_id) : - FALSE); + os_file_read(data_file, page, 0, UNIV_PAGE_SIZE); /* The FSP_HEADER on page 0 is only valid for the first file in a tablespace. So if this is not the first datafile, leave @@ -2030,13 +1977,6 @@ fil_read_first_page( *space_id = fsp_header_get_space_id(page); } - /* Page is page compressed page, need to decompress, before - continue. */ - if (fil_page_is_compressed(page)) { - ulint write_size=0; - fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, &write_size); - } - if (!one_read_already) { check_msg = fil_check_first_page(page); } @@ -2044,12 +1984,29 @@ fil_read_first_page( flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + ulint space = fsp_header_get_space_id(page); + ulint offset = fsp_header_get_crypt_offset( + fsp_flags_get_zip_size(*flags), NULL); + cdata = fil_space_read_crypt_data(space, page, offset); + + /* If file space is encrypted we need to have at least some + encryption service available where to get keys */ + if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) || + (srv_encrypt_tables && + cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { + uint rc = encryption_key_get_latest_version(cdata->key_id); + + if (rc == ENCRYPTION_KEY_VERSION_INVALID) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Tablespace id %ld encrypted but encryption service" + " not available. Can't continue opening tablespace.\n", + space); + ut_error; + } + } + if (crypt_data) { - ulint space = fsp_header_get_space_id(page); - ulint offset = - fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(*flags), NULL); - *crypt_data = fil_space_read_crypt_data(space, page, offset); + *crypt_data = cdata; } ut_free(buf); @@ -3518,7 +3475,7 @@ fil_create_new_single_table_tablespace( } success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE, - fil_space_create_crypt_data()); + fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY)); if (!success || !fil_node_create(path, size, space_id, FALSE)) { err = DB_ERROR; @@ -4082,8 +4039,7 @@ fil_user_tablespace_find_space_id( for (ulint j = 0; j < page_count; ++j) { - st = os_file_read(fsp->file, page, (j* page_size), page_size, - fsp_flags_is_page_compressed(fsp->flags)); + st = os_file_read(fsp->file, page, (j* page_size), page_size); if (!st) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4229,14 +4185,6 @@ check_first_page: "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); fsp->success = FALSE; - if (strncmp(check_msg, MSG_CANNOT_DECRYPT, strlen(check_msg))==0) { - /* by returning here, it should be avoided, that the server crashes, - * if started in recovery mode and can not decrypt tables, if - * the key file can not be read. - */ - fsp->encryption_error = 1; - return; - } } if (!fsp->success) { @@ -5221,7 +5169,7 @@ retry: success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC, node->name, node->handle, buf, offset, page_size * n_pages, - node, NULL, 0, FALSE, 0, 0, 0, 0, false); + node, NULL, 0); #endif /* UNIV_HOTBACKUP */ @@ -5569,6 +5517,74 @@ fil_report_invalid_page_access( (ulong) byte_offset, (ulong) len, (ulong) type); } +/********************************************************************//** +Find correct node from file space +@return node */ +static +fil_node_t* +fil_space_get_node( + fil_space_t* space, /*!< in: file spage */ + ulint space_id, /*!< in: space id */ + ulint* block_offset, /*!< in/out: offset in number of blocks */ + ulint byte_offset, /*!< in: remainder of offset in bytes; in + aio this must be divisible by the OS block + size */ + ulint len) /*!< in: how many bytes to read or write; this + must not cross a file boundary; in aio this + must be a block size multiple */ +{ + fil_node_t* node; + ut_ad(mutex_own(&fil_system->mutex)); + + node = UT_LIST_GET_FIRST(space->chain); + + for (;;) { + if (node == NULL) { + return(NULL); + } else if (fil_is_user_tablespace_id(space->id) + && node->size == 0) { + + /* We do not know the size of a single-table tablespace + before we open the file */ + break; + } else if (node->size > *block_offset) { + /* Found! */ + break; + } else { + *block_offset -= node->size; + node = UT_LIST_GET_NEXT(chain, node); + } + } + + return (node); +} +/********************************************************************//** +Return block size of node in file space +@return file block size */ +UNIV_INTERN +ulint +fil_space_get_block_size( +/*=====================*/ + ulint space_id, + ulint block_offset, + ulint len) +{ + ulint block_size = 512; + fil_space_t* space = fil_space_get_space(space_id); + + if (space) { + mutex_enter(&fil_system->mutex); + fil_node_t* node = fil_space_get_node(space, space_id, &block_offset, 0, len); + mutex_exit(&fil_system->mutex); + + if (node) { + block_size = node->file_block_size; + } + } + + return block_size; +} + /********************************************************************//** Reads or writes data. This operation is asynchronous (aio). @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do @@ -5602,13 +5618,11 @@ fil_io( appropriately aligned */ void* message, /*!< in: message for aio handler if non-sync aio used, else ignored */ - ulint* write_size, /*!< in/out: Actual write size initialized + ulint* write_size) /*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: encrypt later ? */ { ulint mode; fil_space_t* space; @@ -5617,11 +5631,7 @@ fil_io( ulint is_log; ulint wake_later; os_offset_t offset; - ibool ignore_nonexistent_pages; - ibool page_compressed = FALSE; - ulint page_compression_level = 0; - ibool page_encrypted; - ulint page_encryption_key; + bool ignore_nonexistent_pages; is_log = type & OS_FILE_LOG; type = type & ~OS_FILE_LOG; @@ -5706,34 +5716,18 @@ fil_io( ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE); - node = UT_LIST_GET_FIRST(space->chain); + node = fil_space_get_node(space, space_id, &block_offset, byte_offset, len); - for (;;) { - if (node == NULL) { - if (ignore_nonexistent_pages) { - mutex_exit(&fil_system->mutex); - return(DB_ERROR); - } - - fil_report_invalid_page_access( + if (!node) { + if (ignore_nonexistent_pages) { + mutex_exit(&fil_system->mutex); + return(DB_ERROR); + } + fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - ut_error; - - } else if (fil_is_user_tablespace_id(space->id) - && node->size == 0) { - - /* We do not know the size of a single-table tablespace - before we open the file */ - break; - } else if (node->size > block_offset) { - /* Found! */ - break; - } else { - block_offset -= node->size; - node = UT_LIST_GET_NEXT(chain, node); - } + ut_error; } /* Open file if closed */ @@ -5805,11 +5799,6 @@ fil_io( ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0); - page_compressed = fsp_flags_is_page_compressed(space->flags); - page_compression_level = fsp_flags_get_page_compression_level(space->flags); - page_encrypted = fsp_flags_is_page_encrypted(space->flags); - page_encryption_key = fsp_flags_get_page_encryption_key(space->flags); - #ifdef UNIV_HOTBACKUP /* In mysqlbackup do normal i/o, not aio */ if (type == OS_FILE_READ) { @@ -5831,13 +5820,7 @@ fil_io( len, node, message, - write_size, - page_compressed, - page_compression_level, - page_encrypted, - page_encryption_key, - lsn, - encrypt_later); + write_size); #endif /* UNIV_HOTBACKUP */ @@ -6387,9 +6370,7 @@ fil_iterate( readptr = iter.crypt_io_buffer; } - if (!os_file_read(iter.file, readptr, offset, - (ulint) n_bytes, - fil_space_is_page_compressed(space_id))) { + if (!os_file_read(iter.file, readptr, offset, (ulint) n_bytes)) { ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed"); @@ -6540,8 +6521,7 @@ fil_tablespace_iterate( /* Read the first page and determine the page and zip size. */ - if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE, - dict_tf_get_page_compression(table->flags))) { + if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) { err = DB_IO_ERROR; @@ -6601,7 +6581,7 @@ fil_tablespace_iterate( if (iter.crypt_data != NULL) { /* clear crypt data from page 0 and write it back */ - os_file_read(file, page, 0, UNIV_PAGE_SIZE, 0); + os_file_read(file, page, 0, UNIV_PAGE_SIZE); fil_space_clear_crypt_data(page, crypt_data_offset); lsn_t lsn = mach_read_from_8(page + FIL_PAGE_LSN); if (callback.get_zip_size() == 0) { @@ -6779,79 +6759,6 @@ fil_system_exit(void) mutex_exit(&fil_system->mutex); } -/*******************************************************************//** -Return space name */ -char* -fil_space_name( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->name); -} - -/*******************************************************************//** -Return space flags */ -ulint -fil_space_flags( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->flags); -} - -/*******************************************************************//** -Return page type name */ -const char* -fil_get_page_type_name( -/*===================*/ - ulint page_type) /*!< in: FIL_PAGE_TYPE */ -{ - switch(page_type) { - case FIL_PAGE_PAGE_COMPRESSED: - return (const char*)"PAGE_COMPRESSED"; - case FIL_PAGE_INDEX: - return (const char*)"INDEX"; - case FIL_PAGE_UNDO_LOG: - return (const char*)"UNDO LOG"; - case FIL_PAGE_INODE: - return (const char*)"INODE"; - case FIL_PAGE_IBUF_FREE_LIST: - return (const char*)"IBUF_FREE_LIST"; - case FIL_PAGE_TYPE_ALLOCATED: - return (const char*)"ALLOCATED"; - case FIL_PAGE_IBUF_BITMAP: - return (const char*)"IBUF_BITMAP"; - case FIL_PAGE_TYPE_SYS: - return (const char*)"SYS"; - case FIL_PAGE_TYPE_TRX_SYS: - return (const char*)"TRX_SYS"; - case FIL_PAGE_TYPE_FSP_HDR: - return (const char*)"FSP_HDR"; - case FIL_PAGE_TYPE_XDES: - return (const char*)"XDES"; - case FIL_PAGE_TYPE_BLOB: - return (const char*)"BLOB"; - case FIL_PAGE_TYPE_ZBLOB: - return (const char*)"ZBLOB"; - case FIL_PAGE_TYPE_ZBLOB2: - return (const char*)"ZBLOB2"; - case FIL_PAGE_TYPE_COMPRESSED: - return (const char*)"ORACLE PAGE COMPRESSED"; - default: - return (const char*)"PAGE TYPE CORRUPTED"; - } -} -/****************************************************************//** -Get block size from fil node -@return block size*/ -ulint -fil_node_get_block_size( -/*====================*/ - fil_node_t* node) /*!< in: Node where to get block - size */ -{ - return (node->file_block_size); -} /****************************************************************** Get id of first tablespace or ULINT_UNDEFINED if none */ diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index caed038b4ee..1c3db26372d 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -83,172 +83,6 @@ static ulint srv_data_read, srv_data_written; /* Used for debugging */ //#define UNIV_PAGECOMPRESS_DEBUG 1 -/****************************************************************//** -For page compressed pages decompress the page after actual read -operation. */ -static -void -fil_decompress_page_2( -/*==================*/ - byte* page_buf, /*!< out: destination buffer for - uncompressed data */ - byte* buf, /*!< in: source compressed data */ - ulong len, /*!< in: length of output buffer.*/ - ulint* write_size) /*!< in/out: Actual payload size of - the compressed data. */ -{ - ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - - if (page_type != FIL_PAGE_TYPE_COMPRESSED) { - /* It is not a compressed page */ - return; - } - - byte* ptr = buf + FIL_PAGE_DATA; - ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION); - int err = 0; - - ut_a(version == 1); - - /* Read the original page type, before we compressed the data. */ - page_type = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_TYPE_V1); - - ulint original_len = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_SIZE_V1); - - if (original_len < UNIV_PAGE_SIZE_MIN - (FIL_PAGE_DATA + 8) - || original_len > UNIV_PAGE_SIZE_MAX - FIL_PAGE_DATA - || len < original_len + FIL_PAGE_DATA) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: We try to uncompress corrupted page. " - "Original len %lu len %lu.", - original_len, len); - - fflush(stderr); - ut_error; - - } - - ulint algorithm = mach_read_from_1(buf + FIL_PAGE_ALGORITHM_V1); - - switch(algorithm) { - case PAGE_ZLIB_ALGORITHM: { - - err = uncompress(page_buf, &len, ptr, original_len); - - /* If uncompress fails it means that page is corrupted */ - if (err != Z_OK) { - - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed " - "but uncompress failed with error %d " - " size %lu len %lu.", - err, original_len, len); - - fflush(stderr); - - ut_error; - } - - break; - } -#ifdef HAVE_LZ4 - case PAGE_LZ4_ALGORITHM: { - - err = LZ4_decompress_fast( - (const char*) ptr, (char*) (page_buf), original_len); - - if (err < 0) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %d bytes" - " size %lu len %lu.", - err, original_len, len); - fflush(stderr); - - ut_error; - } - break; - } -#endif /* HAVE_LZ4 */ - -#ifdef HAVE_LZMA - case PAGE_LZMA_ALGORITHM: { - - lzma_ret ret; - size_t src_pos = 0; - size_t dst_pos = 0; - uint64_t memlimit = UINT64_MAX; - - ret = lzma_stream_buffer_decode( - &memlimit, - 0, - NULL, - ptr, - &src_pos, - original_len, - (page_buf), - &dst_pos, - len); - - - if (ret != LZMA_OK || (dst_pos <= 0 || dst_pos > len)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %ld bytes" - " size %lu len %lu.", - dst_pos, original_len, len); - fflush(stderr); - - ut_error; - } - - break; - } -#endif /* HAVE_LZMA */ - -#ifdef HAVE_LZO - case PAGE_LZO_ALGORITHM: { - ulint olen = 0; - - err = lzo1x_decompress((const unsigned char *)ptr, - original_len,(unsigned char *)(page_buf), &olen, NULL); - - if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %ld bytes" - " size %lu len %lu.", - olen, original_len, len); - fflush(stderr); - - ut_error; - } - break; - } -#endif /* HAVE_LZO */ - - default: - ib_logf(IB_LOG_LEVEL_ERROR, - " Corruption: Page is marked as compressed " - " but compression algorithm %s" - " is not known." - ,fil_get_compression_alg_name(algorithm)); - - fflush(stderr); - ut_error; - break; - } - - /* Leave the header alone */ - memmove(buf+FIL_PAGE_DATA, page_buf, original_len); - - mach_write_to_2(buf + FIL_PAGE_TYPE, page_type); - - ut_ad(memcmp(buf + FIL_PAGE_LSN + 4, - buf + (original_len + FIL_PAGE_DATA) - - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4) == 0); -} - /****************************************************************//** For page compressed pages compress the page before actual write operation. @@ -289,8 +123,7 @@ fil_compress_page( if (orig_page_type == 0 || orig_page_type == FIL_PAGE_TYPE_FSP_HDR || orig_page_type == FIL_PAGE_TYPE_XDES || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { + orig_page_type == FIL_PAGE_PAGE_COMPRESSED) { *out_len = len; return (buf); } @@ -579,16 +412,6 @@ fil_decompress_page( in_buf = page_buf; } - if (ptype == FIL_PAGE_TYPE_COMPRESSED) { - - fil_decompress_page_2(in_buf, buf, len, write_size); - // Need to free temporal buffer if no buffer was given - if (page_buf == NULL) { - ut_free(in_buf); - } - return; - } - /* Before actual decompress, make sure that page type is correct */ if (mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) != BUF_NO_CHECKSUM_MAGIC || diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index ee1f2fd9510..1cf30a56a98 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -31,6 +31,7 @@ Created 11/29/1995 Heikki Tuuri #include "buf0buf.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "mtr0log.h" #include "ut0byte.h" #include "page0page.h" diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3a5f961a9bb..eee3f9920a9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -79,6 +79,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fsp0fsp.h" #include "sync0sync.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "trx0xa.h" #include "row0merge.h" #include "dict0boot.h" @@ -103,7 +104,6 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fts0priv.h" #include "page0zip.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X)) @@ -236,7 +236,6 @@ static char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; -extern my_bool srv_encrypt_tables; extern uint srv_n_fil_crypt_threads; extern uint srv_fil_crypt_rotate_key_age; extern uint srv_n_fil_crypt_iops; @@ -548,6 +547,11 @@ ib_cb_t innodb_api_cb[] = { (ib_cb_t) ib_cursor_stmt_begin }; +static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG, + "Default encryption key id used for table encryption.", + NULL, NULL, + FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0); + /** Structure for CREATE TABLE options (table options). It needs to be called ha_table_option_struct. @@ -566,10 +570,10 @@ ha_create_table_option innodb_table_option_list[]= HA_TOPTION_NUMBER("PAGE_COMPRESSION_LEVEL", page_compression_level, 0, 1, 9, 1), /* With this option user can enable atomic writes feature for this table */ HA_TOPTION_ENUM("ATOMIC_WRITES", atomic_writes, "DEFAULT,ON,OFF", 0), - /* With this option the user can enable page encryption for the table */ - HA_TOPTION_BOOL("PAGE_ENCRYPTION", page_encryption, 0), + /* With this option the user can enable encryption for the table */ + HA_TOPTION_ENUM("ENCRYPTED", encryption, "DEFAULT,YES,NO", 0), /* With this option the user defines the key identifier using for the encryption */ - HA_TOPTION_NUMBER("PAGE_ENCRYPTION_KEY", page_encryption_key, 0, 1, 255, 1), + HA_TOPTION_SYSVAR("ENCRYPTION_KEY_ID", encryption_key_id, default_encryption_key_id), HA_TOPTION_END }; @@ -815,12 +819,10 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_pages_page_decompressed, SHOW_LONGLONG}, {"num_pages_page_compression_error", (char*) &export_vars.innodb_pages_page_compression_error, SHOW_LONGLONG}, - {"num_pages_page_encrypted", - (char*) &export_vars.innodb_pages_page_encrypted, SHOW_LONGLONG}, - {"num_pages_page_decrypted", - (char*) &export_vars.innodb_pages_page_decrypted, SHOW_LONGLONG}, - {"num_pages_page_encryption_error", - (char*) &export_vars.innodb_pages_page_encryption_error, SHOW_LONGLONG}, + {"num_pages_encrypted", + (char*) &export_vars.innodb_pages_encrypted, SHOW_LONGLONG}, + {"num_pages_decrypted", + (char*) &export_vars.innodb_pages_decrypted, SHOW_LONGLONG}, {"have_lz4", (char*) &innodb_have_lz4, SHOW_BOOL}, {"have_lzo", @@ -11047,8 +11049,6 @@ innobase_table_flags( modified by another thread while the table is being created. */ const ulint default_compression_level = page_zip_level; - const ulint default_encryption_key = srv_default_page_encryption_key; - *flags = 0; *flags2 = 0; @@ -11250,10 +11250,7 @@ index_bad: options->page_compressed, options->page_compression_level == 0 ? default_compression_level : options->page_compression_level, - options->atomic_writes, - options->page_encryption, - options->page_encryption_key == 0 ? - default_encryption_key : options->page_encryption_key); + options->atomic_writes); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { *flags2 |= DICT_TF2_TEMPORARY; @@ -11290,36 +11287,27 @@ ha_innobase::check_table_options( enum row_type row_format = table->s->row_type; ha_table_option_struct *options= table->s->option_struct; atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes; + fil_encryption_t encrypt = (fil_encryption_t)options->encryption; - if (options->page_encryption) { - if (srv_encrypt_tables) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION not available if innodb_encrypt_tables=ON"); - return "INNODB_ENCRYPT_TABLES"; - } - if (!use_tablespace) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION requires" - " innodb_file_per_table."); - return "PAGE_ENCRYPTION"; - } + if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT && !use_tablespace) { + push_warning( + thd, Sql_condition::WARN_LEVEL_WARN, + HA_WRONG_CREATE_OPTION, + "InnoDB: ENCRYPTED requires innodb_file_per_table"); + return "ENCRYPTED"; + } + + if (encrypt == FIL_SPACE_ENCRYPTION_OFF && srv_encrypt_tables == 2) { + push_warning( + thd, Sql_condition::WARN_LEVEL_WARN, + HA_WRONG_CREATE_OPTION, + "InnoDB: ENCRYPTED=OFF cannot be used when innodb_encrypt_tables=FORCE"); + return "ENCRYPTED"; } /* Check page compression requirements */ if (options->page_compressed) { - if (srv_encrypt_tables) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_COMPRESSION not available if innodb_encrypt_tables=ON"); - return "PAGE_COMPRESSED"; - } - if (row_format == ROW_TYPE_COMPRESSED) { push_warning( thd, Sql_condition::WARN_LEVEL_WARN, @@ -11389,29 +11377,16 @@ ha_innobase::check_table_options( } } - if (options->page_encryption_key != 0) { - if (options->page_encryption == false) { - /* ignore this to allow alter table without changing page_encryption_key ...*/ - } - - if (options->page_encryption_key < 1 || options->page_encryption_key > 255) { + if (encrypt == FIL_SPACE_ENCRYPTION_ON || + (encrypt == FIL_SPACE_ENCRYPTION_DEFAULT && srv_encrypt_tables)) { + if (!encryption_key_id_exists(options->encryption_key_id)) { push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, - "InnoDB: invalid PAGE_ENCRYPTION_KEY = %lu." - " Valid values are [1..255]", - options->page_encryption_key); - return "PAGE_ENCRYPTION_KEY"; - } - - if (!has_encryption_key(options->page_encryption_key)) { - push_warning_printf( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION_KEY encryption key %lu not available", - options->page_encryption_key + "InnoDB: ENCRYPTION_KEY_ID %lu not available", + options->encryption_key_id ); - return "PAGE_ENCRYPTION_KEY"; + return "ENCRYPTION_KEY_ID"; } } @@ -11472,6 +11447,10 @@ ha_innobase::create( const char* stmt; size_t stmt_len; + /* Cache table options */ + ha_table_option_struct *options= form->s->option_struct; + fil_encryption_t encrypt = (fil_encryption_t)options->encryption; + ulint key_id = options->encryption_key_id; DBUG_ENTER("ha_innobase::create"); @@ -11724,6 +11703,27 @@ ha_innobase::create( DBUG_ASSERT(innobase_table != 0); + /* If user has requested that table should be encrypted or table + should remain as unencrypted store crypt data */ + if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) { + ulint maxsize; + ulint zip_size = fil_space_get_zip_size(innobase_table->space); + fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space); + fil_space_crypt_t* crypt_data; + + crypt_data = fil_space_create_crypt_data(key_id); + crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); + crypt_data->encryption = encrypt; + + /* If there is old crypt data, copy IV */ + if (old_crypt_data) { + memcpy(crypt_data->iv, old_crypt_data->iv, old_crypt_data->iv_length); + crypt_data->iv_length = old_crypt_data->iv_length; + } + + fil_space_set_crypt_data(innobase_table->space, crypt_data); + } + innobase_copy_frm_flags_from_create_info(innobase_table, create_info); dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE); @@ -19124,13 +19124,20 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa UINT_MAX32, /* Maximum setting */ 0); -static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0, - "Encrypt all tables in the storage engine", - 0, 0, 0); +static const char* srv_encrypt_tables_names[] = { "OFF", "ON", "FORCE", 0 }; +static TYPELIB srv_encrypt_tables_typelib = { + array_elements(srv_encrypt_tables_names)-1, 0, srv_encrypt_tables_names, + NULL +}; +static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables, + PLUGIN_VAR_OPCMDARG, + "Enable encryption for tables. " + "Don't forget to enable --innodb-encrypt-log too", + NULL, NULL, 0, &srv_encrypt_tables_typelib); static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, PLUGIN_VAR_RQCMDARG, - "No of threads performing background key rotation and " + "Number of threads performing background key rotation and " "scrubbing", NULL, innodb_encryption_threads_update, @@ -19139,7 +19146,9 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, static MYSQL_SYSVAR_UINT(encryption_rotate_key_age, srv_fil_crypt_rotate_key_age, PLUGIN_VAR_RQCMDARG, - "Rotate any page having a key older than this", + "Key rotation - re-encrypt in background " + "all pages that were encrypted with a key that " + "many (or more) versions behind", NULL, innodb_encryption_rotate_key_age_update, srv_fil_crypt_rotate_key_age, 0, UINT_MAX32, 0); @@ -19151,37 +19160,22 @@ static MYSQL_SYSVAR_UINT(encryption_rotation_iops, srv_n_fil_crypt_iops, innodb_encryption_rotation_iops_update, srv_n_fil_crypt_iops, 0, UINT_MAX32, 0); -static MYSQL_SYSVAR_UINT(default_page_encryption_key, srv_default_page_encryption_key, - PLUGIN_VAR_RQCMDARG, - "Encryption key used for page encryption.", - NULL, - NULL, - DEFAULT_ENCRYPTION_KEY, 1, 255, 0); - static MYSQL_SYSVAR_BOOL(scrub_log, srv_scrub_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log scrubbing", + "Enable background redo log (ib_logfile0, ib_logfile1...) scrubbing", 0, 0, 0); -/* - If innodb_scrub_log is on, logs will be scrubbed in less than - (((innodb_log_file_size * innodb_log_files_in_group) / 512 ) / - ((1000 * 86400) / innodb_scrub_log_interval)) - days. - In above formula, the first line calculates the number of log blocks to scrub, - and the second line calculates the number of log blocks scrubbed in one day. -*/ -static MYSQL_SYSVAR_ULONGLONG(scrub_log_interval, innodb_scrub_log_interval, +static MYSQL_SYSVAR_ULONGLONG(scrub_log_speed, innodb_scrub_log_speed, PLUGIN_VAR_OPCMDARG, - "Innodb redo log scrubbing interval in ms", + "Background redo log scrubbing speed in bytes/sec", NULL, NULL, - 2000, /* default */ - 10, /* min */ - ULONGLONG_MAX, 0);/* max */ + 256, /* 256 bytes/sec, corresponds to 2000 ms scrub_log_interval */ + 1, /* min */ + 50000, 0); /* 50Kbyte/sec, corresponds to 10 ms scrub_log_interval */ static MYSQL_SYSVAR_BOOL(encrypt_log, srv_encrypt_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log encryption/decryption.", + "Enable redo log encryption", NULL, NULL, FALSE); static MYSQL_SYSVAR_BOOL(immediate_scrub_data_uncompressed, @@ -19226,7 +19220,7 @@ static MYSQL_SYSVAR_UINT(background_scrub_data_interval, UINT_MAX32, 0); #ifdef UNIV_DEBUG -static MYSQL_SYSVAR_BOOL(scrub_force_testing, +static MYSQL_SYSVAR_BOOL(debug_force_scrubbing, srv_scrub_force_testing, 0, "Perform extra scrubbing to increase test exposure", @@ -19423,10 +19417,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(encryption_rotate_key_age), MYSQL_SYSVAR(encryption_rotation_iops), MYSQL_SYSVAR(scrub_log), - MYSQL_SYSVAR(scrub_log_interval), + MYSQL_SYSVAR(scrub_log_speed), MYSQL_SYSVAR(encrypt_log), - MYSQL_SYSVAR(default_page_encryption_key), - + MYSQL_SYSVAR(default_encryption_key_id), /* Scrubing feature */ MYSQL_SYSVAR(immediate_scrub_data_uncompressed), MYSQL_SYSVAR(background_scrub_data_uncompressed), @@ -19434,7 +19427,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(background_scrub_data_interval), MYSQL_SYSVAR(background_scrub_data_check_interval), #ifdef UNIV_DEBUG - MYSQL_SYSVAR(scrub_force_testing), + MYSQL_SYSVAR(debug_force_scrubbing), #endif MYSQL_SYSVAR(instrument_semaphores), NULL @@ -19454,7 +19447,7 @@ maria_declare_plugin(innobase) innodb_status_variables_export,/* status variables */ innobase_system_variables, /* system variables */ INNODB_VERSION_STR, /* string version */ - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ + MariaDB_PLUGIN_MATURITY_BETA /* maturity */ }, i_s_innodb_trx, i_s_innodb_locks, diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 7807c7ca7e6..b613053a992 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -70,8 +70,8 @@ struct ha_table_option_struct srv_use_atomic_writes=1. Atomic writes are not used if value OFF.*/ - bool page_encryption; /*!< Flag for an encrypted table */ - int page_encryption_key; /*!< ID of the encryption key */ + uint encryption; /*!< DEFAULT, ON, OFF */ + int encryption_key_id; /*!< encryption key id*/ }; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 94f17e75358..dc5c5d85b8d 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -278,8 +278,8 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (new_options->page_encryption != old_options->page_encryption || - new_options->page_encryption_key != old_options->page_encryption_key) { + if (new_options->encryption != old_options->encryption || + new_options->encryption_key_id != old_options->encryption_key_id) { ha_alter_info->unsupported_reason = innobase_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 65fcb7051ef..c5624252a9e 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -61,6 +61,8 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits) #include "btr0btr.h" #include "page0zip.h" #include "sync0arr.h" +#include "fil0fil.h" +#include "fil0crypt.h" /** structure associates a name string with a file page type and/or buffer page state. */ @@ -781,7 +783,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_trx = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ @@ -1041,7 +1043,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_locks = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ @@ -1224,7 +1226,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -1560,7 +1562,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = @@ -1610,7 +1612,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic tables @@ -1910,7 +1912,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_per_index = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_per_index_reset = @@ -1960,7 +1962,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_per_index_reset = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table information_schema.innodb_cmpmem. */ @@ -2203,7 +2205,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = @@ -2253,7 +2255,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_metrics */ @@ -2777,7 +2779,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_metrics = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_ft_default_stopword */ static ST_FIELD_INFO i_s_stopword_fields_info[] = @@ -2890,7 +2892,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_default_stopword = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED @@ -3058,7 +3060,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_deleted = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -3141,7 +3143,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_being_deleted = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED and @@ -3431,7 +3433,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_index_cache = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -3866,7 +3868,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_index_table = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG */ @@ -4060,7 +4062,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_config = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */ @@ -4609,7 +4611,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_stats = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */ @@ -5321,7 +5323,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] = @@ -5868,7 +5870,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page_lru = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -6162,7 +6164,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_TABLESTATS ***********************************************/ @@ -6452,7 +6454,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablestats = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_INDEXES **************************************************/ @@ -6704,7 +6706,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_COLUMNS **************************************************/ @@ -6941,7 +6943,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_columns = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_FIELDS ***************************************************/ @@ -7151,7 +7153,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_FOREIGN ********************************************/ @@ -7376,7 +7378,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_FOREIGN_COLS ********************************************/ @@ -7593,7 +7595,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_TABLESPACES ********************************************/ @@ -7861,7 +7863,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablespaces = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_DATAFILES ************************************************/ @@ -8050,7 +8052,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_datafiles = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** TABLESPACES_ENCRYPTION ********************************************/ @@ -8332,7 +8334,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_encryption = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) }; /** TABLESPACES_SCRUBBING ********************************************/ @@ -8630,7 +8632,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_scrubbing = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) }; /** INNODB_MUTEXES *********************************************/ @@ -8844,7 +8846,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_mutexes = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_SEMAPHORE_WAITS ************************************************/ @@ -9121,5 +9123,5 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 1c84e68167e..d22d344162a 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1445,16 +1445,19 @@ buf_flush_update_zip_checksum( The hook that is called just before a page is written to disk. The function encrypts the content of the page and returns a pointer to a frame that will be written instead of the real frame. */ +UNIV_INTERN byte* buf_page_encrypt_before_write( /*==========================*/ buf_page_t* page, /*!< in/out: buffer page to be flushed */ - const byte* frame); + const byte* frame, + ulint space_id); /********************************************************************** The hook that is called after page is written to disk. The function releases any resources needed for encryption that was allocated in buf_page_encrypt_before_write */ +UNIV_INTERN ibool buf_page_encrypt_after_write( /*=========================*/ @@ -1464,6 +1467,7 @@ buf_page_encrypt_after_write( The hook that is called just before a page is read from disk. The function allocates memory that is used to temporarily store disk content before getting decrypted */ +UNIV_INTERN byte* buf_page_decrypt_before_read( /*=========================*/ @@ -1474,19 +1478,35 @@ buf_page_decrypt_before_read( The hook that is called just after a page is read from disk. The function decrypt disk content into buf_page_t and releases the temporary buffer that was allocated in buf_page_decrypt_before_read */ +UNIV_INTERN ibool buf_page_decrypt_after_read( /*========================*/ buf_page_t* page); /*!< in/out: buffer page read from disk */ -/********************************************************************//** -Release memory allocated for page decryption. -Only used in scenarios where read fails, e.g due to tablespace being dropped */ -void -buf_page_decrypt_cleanup( -/*=====================*/ - buf_page_t* page); /*!< in/out: buffer page read from disk */ +/** @brief The temporary memory structure. +NOTE! The definition appears here only for other modules of this +directory (buf) to see it. Do not use from outside! */ + +typedef struct { + bool reserved; /*!< true if this slot is reserved + */ +#ifdef HAVE_LZO + byte* lzo_mem; /*!< Temporal memory used by LZO */ +#endif + byte* crypt_buf; /*!< for encryption the data needs to be + copied to a separate buffer before it's + encrypted&written. this as a page can be + read while it's being flushed */ + byte* crypt_buf_free; /*!< for encryption, allocated buffer + that is then alligned */ + byte* comp_buf; /*!< for compression we need + temporal buffer because page + can be read while it's being flushed */ + byte* comp_buf_free; /*!< for compression, allocated + buffer that is then alligned */ +} buf_tmp_buffer_t; /** The common buffer control block structure for compressed and uncompressed frames */ @@ -1559,20 +1579,15 @@ struct buf_page_t{ operation needed. */ unsigned key_version; /*!< key version for this block */ - byte* crypt_buf; /*!< for encryption the data needs to be - copied to a separate buffer before it's - encrypted&written. this as a page can be - read while it's being flushed */ - byte* crypt_buf_free; /*!< for encryption, allocated buffer - that is then alligned */ - byte* comp_buf; /*!< for compression we need - temporal buffer because page - can be read while it's being flushed */ - byte* comp_buf_free; /*!< for compression, allocated - buffer that is then alligned */ - bool encrypt_later; /*!< should we encrypt the page - at os0file.cc ? */ + ulint real_size; /*!< Real size of the page + Normal pages == UNIV_PAGE_SIZE + page compressed pages, payload + size alligned to sector boundary. + */ + buf_tmp_buffer_t* slot; /*!< Slot for temporary memory + used for encryption/compression + or NULL */ #ifndef UNIV_HOTBACKUP buf_page_t* hash; /*!< node used in chaining to buf_pool->page_hash or @@ -2017,6 +2032,17 @@ struct buf_buddy_stat_t { ib_uint64_t relocated_usec; }; +/** @brief The temporary memory array structure. + +NOTE! The definition appears here only for other modules of this +directory (buf) to see it. Do not use from outside! */ + +typedef struct { + ulint n_slots; /*!< Total number of slots */ + buf_tmp_buffer_t *slots; /*!< Pointer to the slots in the + array */ +} buf_tmp_array_t; + /** @brief The buffer pool structure. NOTE! The definition appears here only for other modules of this @@ -2200,6 +2226,10 @@ struct buf_pool_t{ pool watches. Protected by buf_pool->mutex. */ + buf_tmp_array_t* tmp_arr; + /*!< Array for temporal memory + used in compression and encryption */ + #if BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN # error "BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN" #endif diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index aed03307601..7b90ecb947d 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -1457,27 +1457,16 @@ buf_get_nth_chunk_block( return(chunk->blocks); } -/********************************************************************//** -Get crypt buffer. */ -UNIV_INLINE -byte* -buf_page_get_crypt_buffer( -/*=========================*/ - const buf_page_t* bpage) /*!< in: buffer pool page */ -{ - return bpage->crypt_buf; -} - /********************************************************************//** Get buf frame. */ UNIV_INLINE void * buf_page_get_frame( -/*=========================*/ +/*===============*/ const buf_page_t* bpage) /*!< in: buffer pool page */ { - if (bpage->crypt_buf) { - return buf_page_get_crypt_buffer(bpage); + if (bpage->slot && bpage->slot->crypt_buf) { + return bpage->slot->crypt_buf; } else if (bpage->zip.data) { return bpage->zip.data; } else { diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 326b9e7c986..20014e05784 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -929,10 +929,8 @@ dict_tf_set( pages */ ulint page_compression_level, /*!< in: table page compression level */ - ulint atomic_writes, /*!< in: table atomic + ulint atomic_writes) /*!< in: table atomic writes option value*/ - bool page_encrypted,/*!< in: table uses page encryption */ - ulint page_encryption_key) /*!< in: page encryption key */ __attribute__((nonnull)); /********************************************************************//** Convert a 32 bit integer table flags to the 32 bit integer that is diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 7c51faf844e..dd42b478c1f 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -543,9 +543,6 @@ dict_tf_is_valid( ulint data_dir = DICT_TF_HAS_DATA_DIR(flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags); - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(flags); - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(flags); - /* Make sure there are no bits that we do not know about. */ if (unused != 0) { fprintf(stderr, @@ -555,12 +552,10 @@ dict_tf_is_valid( "InnoDB: compact %ld atomic_blobs %ld\n" "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n" - "InnoDB: page_encryption %ld page_encryption_key %ld\n", + "InnoDB: atomic_writes %ld\n", unused, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes, - page_encryption, page_encryption_key + page_compression, page_compression_level, atomic_writes ); return(false); @@ -857,9 +852,7 @@ dict_tf_set( pages */ ulint page_compression_level, /*!< in: table page compression level */ - ulint atomic_writes, /*!< in: table atomic writes setup */ - bool page_encrypted, /*!< in: table uses page encryption */ - ulint page_encryption_key /*!< in: page encryption key */) + ulint atomic_writes) /*!< in: table atomic writes setup */ { atomic_writes_t awrites = (atomic_writes_t)atomic_writes; @@ -900,11 +893,6 @@ dict_tf_set( if (use_data_dir) { *flags |= (1 << DICT_TF_POS_DATA_DIR); } - - if (page_encrypted) { - *flags |= (1 << DICT_TF_POS_PAGE_ENCRYPTION) - | (page_encryption_key << DICT_TF_POS_PAGE_ENCRYPTION_KEY); - } } /********************************************************************//** @@ -927,10 +915,6 @@ dict_tf_to_fsp_flags( ulint fsp_flags; ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); - - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(table_flags); - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(table_flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure", @@ -958,14 +942,6 @@ dict_tf_to_fsp_flags( if page compression is used for this table. */ fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level); - /* In addition, tablespace flags also contain if the page - encryption is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_ENCRYPTION(fsp_flags, page_encryption); - - /* In addition, tablespace flags also contain page encryption key if the page - encryption is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_ENCRYPTION_KEY(fsp_flags, page_encryption_key); - /* In addition, tablespace flags also contain flag if atomic writes is used for this table */ fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes); @@ -1007,8 +983,6 @@ dict_sys_tables_type_to_tf( | DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL | DICT_TF_MASK_ATOMIC_WRITES - | DICT_TF_MASK_PAGE_ENCRYPTION - | DICT_TF_MASK_PAGE_ENCRYPTION_KEY ); @@ -1045,9 +1019,7 @@ dict_tf_to_sys_tables_type( | DICT_TF_MASK_DATA_DIR | DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL - | DICT_TF_MASK_ATOMIC_WRITES - | DICT_TF_MASK_PAGE_ENCRYPTION - | DICT_TF_MASK_PAGE_ENCRYPTION_KEY); + | DICT_TF_MASK_ATOMIC_WRITES); return(type); } diff --git a/storage/innobase/include/dict0pagecompress.ic b/storage/innobase/include/dict0pagecompress.ic index a71b2b34b07..811976434a8 100644 --- a/storage/innobase/include/dict0pagecompress.ic +++ b/storage/innobase/include/dict0pagecompress.ic @@ -42,8 +42,6 @@ dict_tf_verify_flags( ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(table_flags); - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(table_flags); ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags); ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags); @@ -52,9 +50,6 @@ dict_tf_verify_flags( ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags); - ulint fsp_page_encryption = FSP_FLAGS_GET_PAGE_ENCRYPTION(fsp_flags); - ulint fsp_page_encryption_key = FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(fsp_flags); - DBUG_EXECUTE_IF("dict_tf_verify_flags_failure", return(ULINT_UNDEFINED);); @@ -112,27 +107,6 @@ dict_tf_verify_flags( return (FALSE); } - if (page_encryption != fsp_page_encryption) { - fprintf(stderr, - "InnoDB: Error: table flags has page_encryption %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_encryption %ld\n", - page_encryption, fsp_page_encryption); - - return (FALSE); - } - - if (page_encryption_key != fsp_page_encryption_key) { - fprintf(stderr, - "InnoDB: Error: table flags has page_encryption_key %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_encryption_key %ld\n", - page_encryption_key, fsp_page_encryption_key); - - return (FALSE); - } - - return(TRUE); } diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h new file mode 100644 index 00000000000..65c51c75d41 --- /dev/null +++ b/storage/innobase/include/fil0crypt.h @@ -0,0 +1,387 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0crypt.h +The low-level file system encryption support functions + +Created 04/01/2015 Jan Lindström +*******************************************************/ + +#ifndef fil0crypt_h +#define fil0crypt_h + +/* This key will be used if nothing else is given */ +#define FIL_DEFAULT_ENCRYPTION_KEY 1 + +/** Enum values for encryption table option */ +typedef enum { + FIL_SPACE_ENCRYPTION_DEFAULT = 0, /* Tablespace encrypted if + srv_encrypt_tables = ON */ + FIL_SPACE_ENCRYPTION_ON = 1, /* Tablespace is encrypted always */ + FIL_SPACE_ENCRYPTION_OFF = 2 /* Tablespace is not encrypted */ +} fil_encryption_t; + +/** + * CRYPT_SCHEME_UNENCRYPTED + * + * Used as intermediate state when convering a space from unencrypted + * to encrypted + */ +/** + * CRYPT_SCHEME_1 + * + * xxx is AES_CTR or AES_CBC (or another block cypher with the same key and iv lengths) + * L = AES_ECB(KEY, IV) + * CRYPT(PAGE) = xxx(KEY=L, IV=C, PAGE) + */ + +#define CRYPT_SCHEME_1 1 +#define CRYPT_SCHEME_1_IV_LEN 16 +#define CRYPT_SCHEME_UNENCRYPTED 0 + +/* Cached L or key for given key_version */ +struct key_struct +{ + uint key_version; /*!< Version of the key */ + uint key_length; /*!< Key length */ + unsigned char key[MY_AES_MAX_KEY_LENGTH]; /*!< Cached key + (that is L in CRYPT_SCHEME_1) */ +}; + +struct fil_space_rotate_state_t +{ + time_t start_time; // time when rotation started + ulint active_threads; // active threads in space + ulint next_offset; // next "free" offset + ulint max_offset; // max offset needing to be rotated + uint min_key_version_found; // min key version found but not rotated + lsn_t end_lsn; // max lsn created when rotating this space + bool starting; // initial write of IV + bool flushing; // space is being flushed at end of rotate + struct { + bool is_active; // is scrubbing active in this space + time_t last_scrub_completed; // when was last scrub completed + } scrubbing; +}; + +struct fil_space_crypt_struct +{ + ulint type; // CRYPT_SCHEME + uint keyserver_requests; // no of key requests to key server + uint key_count; // No of initalized key-structs + uint key_id; // Key id for this space + key_struct keys[3]; // cached L = AES_ECB(KEY, IV) + uint min_key_version; // min key version for this space + ulint page0_offset; // byte offset on page 0 for crypt data + fil_encryption_t encryption; // Encryption setup + + ib_mutex_t mutex; // mutex protecting following variables + bool closing; // is tablespace being closed + fil_space_rotate_state_t rotate_state; + + uint iv_length; // length of IV + byte iv[1]; // IV-data +}; + +/* structure containing encryption specification */ +typedef struct fil_space_crypt_struct fil_space_crypt_t; + +/********************************************************************* +Init global resources needed for tablespace encryption/decryption */ +UNIV_INTERN +void +fil_space_crypt_init(); + +/********************************************************************* +Cleanup global resources needed for tablespace encryption/decryption */ +UNIV_INTERN +void +fil_space_crypt_cleanup(); + +/********************************************************************* +Create crypt data, i.e data that is used for a single tablespace */ +UNIV_INTERN +fil_space_crypt_t * +fil_space_create_crypt_data(uint key_id); + +/********************************************************************* +Destroy crypt data */ +UNIV_INTERN +void +fil_space_destroy_crypt_data( +/*=========================*/ + fil_space_crypt_t **crypt_data); /*!< in/out: crypt data */ + +/********************************************************************* +Get crypt data for a space*/ +UNIV_INTERN +fil_space_crypt_t * +fil_space_get_crypt_data( +/*======================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Set crypt data for a space*/ +UNIV_INTERN +void +fil_space_set_crypt_data( +/*======================*/ + ulint space, /*!< in: tablespace id */ + fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */ + +/********************************************************************* +Compare crypt data*/ +UNIV_INTERN +int +fil_space_crypt_compare( +/*======================*/ + const fil_space_crypt_t* crypt_data1, /*!< in: crypt data */ + const fil_space_crypt_t* crypt_data2); /*!< in: crypt data */ + +/********************************************************************* +Read crypt data from buffer page */ +UNIV_INTERN +fil_space_crypt_t * +fil_space_read_crypt_data( +/*======================*/ + ulint space, /*!< in: tablespace id */ + const byte* page, /*!< in: buffer page */ + ulint offset); /*!< in: offset where crypt data is stored */ + +/********************************************************************* +Write crypt data to buffer page */ +UNIV_INTERN +void +fil_space_write_crypt_data( +/*=======================*/ + ulint space, /*!< in: tablespace id */ + byte* page, /*!< in: buffer page */ + ulint offset, /*!< in: offset where to store data */ + ulint maxsize, /*!< in: max space available to store crypt data in */ + mtr_t * mtr); /*!< in: mini-transaction */ + +/********************************************************************* +Clear crypt data from page 0 (used for import tablespace) */ +UNIV_INTERN +void +fil_space_clear_crypt_data( +/*======================*/ + byte* page, /*!< in: buffer page */ + ulint offset); /*!< in: offset where crypt data is stored */ + +/********************************************************************* +Parse crypt data log record */ +UNIV_INTERN +byte* +fil_parse_write_crypt_data( +/*=======================*/ + byte* ptr, /*!< in: start of log record */ + byte* end_ptr, /*!< in: end of log record */ + buf_block_t*); /*!< in: buffer page to apply record to */ + +/********************************************************************* +Check if extra buffer shall be allocated for decrypting after read */ +UNIV_INTERN +bool +fil_space_check_encryption_read( +/*==============================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Check if page shall be encrypted before write */ +UNIV_INTERN +bool +fil_space_check_encryption_write( +/*==============================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Encrypt buffer page */ +UNIV_INTERN +void +fil_space_encrypt( +/*===============*/ + ulint space, /*!< in: tablespace id */ + ulint offset, /*!< in: page no */ + lsn_t lsn, /*!< in: page lsn */ + const byte* src_frame,/*!< in: page frame */ + ulint size, /*!< in: size of data to encrypt */ + byte* dst_frame); /*!< in: where to encrypt to */ + +/********************************************************************* +Decrypt buffer page */ +UNIV_INTERN +void +fil_space_decrypt( +/*===============*/ + ulint space, /*!< in: tablespace id */ + const byte* src_frame,/*!< in: page frame */ + ulint page_size, /*!< in: size of data to encrypt */ + byte* dst_frame); /*!< in: where to decrypt to */ + + +/********************************************************************* +Decrypt buffer page +@return true if page was encrypted */ +UNIV_INTERN +bool +fil_space_decrypt( +/*===============*/ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + const byte* src_frame,/*!< in: page frame */ + ulint page_size, /*!< in: page size */ + byte* dst_frame); /*!< in: where to decrypt to */ + +/********************************************************************* +fil_space_verify_crypt_checksum +NOTE: currently this function can only be run in single threaded mode +as it modifies srv_checksum_algorithm (temporarily) +@return true if page is encrypted AND OK, false otherwise */ +UNIV_INTERN +bool +fil_space_verify_crypt_checksum( +/*===============*/ + const byte* src_frame,/*!< in: page frame */ + ulint zip_size); /*!< in: size of data to encrypt */ + +/********************************************************************* +Init threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_init(); + +/********************************************************************* +Set thread count (e.g start or stops threads) used for key rotation */ +UNIV_INTERN +void +fil_crypt_set_thread_cnt( +/*=====================*/ + uint new_cnt); /*!< in: requested #threads */ + +/********************************************************************* +End threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_end(); + +/********************************************************************* +Cleanup resources for threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_cleanup(); + +/********************************************************************* +Set rotate key age */ +UNIV_INTERN +void +fil_crypt_set_rotate_key_age( +/*=====================*/ + uint rotate_age); /*!< in: requested rotate age */ + +/********************************************************************* +Set rotation threads iops */ +UNIV_INTERN +void +fil_crypt_set_rotation_iops( +/*=====================*/ + uint iops); /*!< in: requested iops */ + +/********************************************************************* +Mark a space as closing */ +UNIV_INTERN +void +fil_space_crypt_mark_space_closing( +/*===============*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Wait for crypt threads to stop accessing space */ +UNIV_INTERN +void +fil_space_crypt_close_tablespace( +/*===============*/ + ulint space); /*!< in: tablespace id */ + +/** Struct for retreiving info about encryption */ +struct fil_space_crypt_status_t { + ulint space; /*!< tablespace id */ + ulint scheme; /*!< encryption scheme */ + uint min_key_version; /*!< min key version */ + uint current_key_version;/*!< current key version */ + uint keyserver_requests;/*!< no of key requests to key server */ + bool rotating; /*!< is key rotation ongoing */ + bool flushing; /*!< is flush at end of rotation ongoing */ + ulint rotate_next_page_number; /*!< next page if key rotating */ + ulint rotate_max_page_number; /*!< max page if key rotating */ +}; + +/********************************************************************* +Get crypt status for a space +@return 0 if crypt data found */ +UNIV_INTERN +int +fil_space_crypt_get_status( +/*==================*/ + ulint id, /*!< in: space id */ + struct fil_space_crypt_status_t * status); /*!< out: status */ + +/** Struct for retreiving statistics about encryption key rotation */ +struct fil_crypt_stat_t { + ulint pages_read_from_cache; + ulint pages_read_from_disk; + ulint pages_modified; + ulint pages_flushed; + ulint estimated_iops; +}; + +/********************************************************************* +Get crypt rotation statistics */ +UNIV_INTERN +void +fil_crypt_total_stat( +/*==================*/ + fil_crypt_stat_t* stat); /*!< out: crypt stat */ + +/** Struct for retreiving info about scrubbing */ +struct fil_space_scrub_status_t { + ulint space; /*!< tablespace id */ + bool compressed; /*!< is space compressed */ + time_t last_scrub_completed; /*!< when was last scrub completed */ + bool scrubbing; /*!< is scrubbing ongoing */ + time_t current_scrub_started; /*!< when started current scrubbing */ + ulint current_scrub_active_threads; /*!< current scrub active threads */ + ulint current_scrub_page_number; /*!< current scrub page no */ + ulint current_scrub_max_page_number; /*!< current scrub max page no */ +}; + +/********************************************************************* +Get scrub status for a space +@return 0 if no scrub info found */ +UNIV_INTERN +int +fil_space_get_scrub_status( +/*==================*/ + ulint id, /*!< in: space id */ + struct fil_space_scrub_status_t * status); /*!< out: status */ + +#ifndef UNIV_NONINL +#include "fil0crypt.ic" +#endif + +#endif /* fil0crypt_h */ diff --git a/storage/innobase/include/fil0crypt.ic b/storage/innobase/include/fil0crypt.ic new file mode 100644 index 00000000000..5fafa6cd3f0 --- /dev/null +++ b/storage/innobase/include/fil0crypt.ic @@ -0,0 +1,68 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0fil.h +The low-level file system encryption support functions + +Created 04/01/2015 Jan Lindström +*******************************************************/ + +/*******************************************************************//** +Find out whether the page is page encrypted +@return true if page is page encrypted, false if not */ +UNIV_INLINE +bool +fil_page_is_encrypted( +/*==================*/ + const byte *buf) /*!< in: page */ +{ + return(mach_read_from_4(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) != 0); +} + +/*******************************************************************//** +Find out whether the page can be decrypted. +The function for decrypting the page should already be executed before this. +@return 1 if key provider not available or key is not available + 0 if decryption should be possible +*/ +UNIV_INLINE +bool +fil_page_encryption_status( +/*===================*/ + const byte *buf, /*!< in: page */ + ulint space_id) /*!< in: space_id */ +{ + fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id); + ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE); + + if (page_type == FIL_PAGE_TYPE_FSP_HDR) { + if (crypt_data != NULL) { + if (!encryption_key_id_exists(crypt_data->key_id)) { + /* accessing table would surely fail, because no key or no key provider available */ + return 1; + } + } + } else { + ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + if (!encryption_key_version_exists(crypt_data->key_id, key)) { + return 1; + } + } + return 0; +} diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index e4f16b24392..7f2c00eb168 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -26,7 +26,6 @@ Created 10/25/1995 Heikki Tuuri #ifndef fil0fil_h #define fil0fil_h -#define MSG_CANNOT_DECRYPT "can not decrypt" #include "univ.i" #ifndef UNIV_INNOCHECKSUM @@ -136,24 +135,6 @@ extern fil_addr_t fil_addr_null; used to encrypt the page + 32-bit checksum or 64 bits of zero if no encryption */ -/** If page type is FIL_PAGE_COMPRESSED then the 8 bytes starting at -FIL_PAGE_FILE_FLUSH_LSN are broken down as follows: */ - -/** Control information version format (u8) */ -static const ulint FIL_PAGE_VERSION = FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; - -/** Compression algorithm (u8) */ -static const ulint FIL_PAGE_ALGORITHM_V1 = FIL_PAGE_VERSION + 1; - -/** Original page type (u16) */ -static const ulint FIL_PAGE_ORIGINAL_TYPE_V1 = FIL_PAGE_ALGORITHM_V1 + 1; - -/** Original data size in bytes (u16)*/ -static const ulint FIL_PAGE_ORIGINAL_SIZE_V1 = FIL_PAGE_ORIGINAL_TYPE_V1 + 2; - -/** Size after compression (u16)*/ -static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; - #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this contains the space id of the page */ #define FIL_PAGE_SPACE_ID FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID @@ -173,10 +154,7 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; /* @} */ /** File page types (values of FIL_PAGE_TYPE) @{ */ -#define FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED 35631 /* page compressed + - encrypted page */ #define FIL_PAGE_PAGE_COMPRESSED 34354 /*!< page compressed page */ -#define FIL_PAGE_PAGE_ENCRYPTED 34355 /*!< Page encrypted page */ #define FIL_PAGE_INDEX 17855 /*!< B-tree node */ #define FIL_PAGE_UNDO_LOG 2 /*!< Undo log page */ #define FIL_PAGE_INODE 3 /*!< Index node */ @@ -203,6 +181,9 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; #ifndef UNIV_INNOCHECKSUM +/* structure containing encryption specification */ +typedef struct fil_space_crypt_struct fil_space_crypt_t; + /** The number of fsyncs done to the log */ extern ulint fil_n_log_flushes; @@ -214,9 +195,6 @@ extern ulint fil_n_pending_tablespace_flushes; /** Number of files currently open */ extern ulint fil_n_file_opened; -/* structure containing encryption specification */ -typedef struct fil_space_crypt_struct fil_space_crypt_t; - struct fsp_open_info { ibool success; /*!< Has the tablespace been opened? */ const char* check_msg; /*!< fil_check_first_page() message */ @@ -997,13 +975,11 @@ fil_io( appropriately aligned */ void* message, /*!< in: message for aio handler if non-sync aio used, else ignored */ - ulint* write_size, /*!< in/out: Actual write size initialized + ulint* write_size) /*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: should we encrypt the page */ __attribute__((nonnull(8))); /**********************************************************************//** Waits for an aio operation to complete. This function is used to write the @@ -1256,6 +1232,7 @@ fil_user_tablespace_restore_page( /*******************************************************************//** Return space flags */ +UNIV_INLINE ulint fil_space_flags( /*===========*/ @@ -1281,12 +1258,6 @@ fil_space_t* fil_space_get_by_id( /*================*/ ulint id); /*!< in: space id */ -/*******************************************************************//** -Return space name */ -char* -fil_space_name( -/*===========*/ - fil_space_t* space); /*!< in: space */ /****************************************************************** Get id of first tablespace or ULINT_UNDEFINED if none */ @@ -1301,270 +1272,23 @@ ulint fil_get_next_space( ulint id); /*!< in: space id */ -/********************************************************************* -Init global resources needed for tablespace encryption/decryption */ -void -fil_space_crypt_init(); - -/********************************************************************* -Cleanup global resources needed for tablespace encryption/decryption */ -void -fil_space_crypt_cleanup(); - -/********************************************************************* -Create crypt data, i.e data that is used for a single tablespace */ -fil_space_crypt_t * -fil_space_create_crypt_data(); - -/********************************************************************* -Destroy crypt data */ +/*******************************************************************//** +Returns the block size of the file space +@return block size */ UNIV_INTERN -void -fil_space_destroy_crypt_data( -/*=========================*/ - fil_space_crypt_t **crypt_data); /*!< in/out: crypt data */ - -/********************************************************************* -Get crypt data for a space*/ -fil_space_crypt_t * -fil_space_get_crypt_data( -/*======================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Set crypt data for a space*/ -void -fil_space_set_crypt_data( -/*======================*/ - ulint space, /*!< in: tablespace id */ - fil_space_crypt_t* crypt_data); /*!< in: crypt data */ - -/********************************************************************* -Compare crypt data*/ -int -fil_space_crypt_compare( -/*======================*/ - const fil_space_crypt_t* crypt_data1, /*!< in: crypt data */ - const fil_space_crypt_t* crypt_data2); /*!< in: crypt data */ - -/********************************************************************* -Read crypt data from buffer page */ -fil_space_crypt_t * -fil_space_read_crypt_data( -/*======================*/ - ulint space, /*!< in: tablespace id */ - const byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ - -/********************************************************************* -Write crypt data to buffer page */ -void -fil_space_write_crypt_data( -/*=======================*/ - ulint space, /*!< in: tablespace id */ - byte* page, /*!< in: buffer page */ - ulint offset, /*!< in: offset where to store data */ - ulint maxsize, /*!< in: max space available to store crypt data in */ - mtr_t * mtr); /*!< in: mini-transaction */ - -/********************************************************************* -Clear crypt data from page 0 (used for import tablespace) */ -void -fil_space_clear_crypt_data( -/*======================*/ - byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ - -/********************************************************************* -Parse crypt data log record */ -byte* -fil_parse_write_crypt_data( -/*=======================*/ - byte* ptr, /*!< in: start of log record */ - byte* end_ptr, /*!< in: end of log record */ - buf_block_t*); /*!< in: buffer page to apply record to */ - -/********************************************************************* -Check if extra buffer shall be allocated for decrypting after read */ -UNIV_INTERN -bool -fil_space_check_encryption_read( -/*==============================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Check if page shall be encrypted before write */ -UNIV_INTERN -bool -fil_space_check_encryption_write( -/*==============================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Encrypt buffer page */ -void -fil_space_encrypt( -/*===============*/ - ulint space, /*!< in: tablespace id */ - ulint offset, /*!< in: page no */ - lsn_t lsn, /*!< in: page lsn */ - const byte* src_frame,/*!< in: page frame */ - ulint size, /*!< in: size of data to encrypt */ - byte* dst_frame, /*!< in: where to encrypt to */ - ulint page_encryption_key); /*!< in: page encryption key id if page - encrypted */ - -/********************************************************************* -Decrypt buffer page */ -void -fil_space_decrypt( -/*===============*/ - ulint space, /*!< in: tablespace id */ - const byte* src_frame,/*!< in: page frame */ - ulint page_size, /*!< in: size of data to encrypt */ - byte* dst_frame); /*!< in: where to decrypt to */ - - -/********************************************************************* -Decrypt buffer page -@return true if page was encrypted */ -bool -fil_space_decrypt( -/*===============*/ - fil_space_crypt_t* crypt_data, /*!< in: crypt data */ - const byte* src_frame,/*!< in: page frame */ - ulint page_size, /*!< in: page size */ - byte* dst_frame); /*!< in: where to decrypt to */ - -/********************************************************************* -fil_space_verify_crypt_checksum -NOTE: currently this function can only be run in single threaded mode -as it modifies srv_checksum_algorithm (temporarily) -@return true if page is encrypted AND OK, false otherwise */ -bool -fil_space_verify_crypt_checksum( -/*===============*/ - const byte* src_frame,/*!< in: page frame */ - ulint zip_size); /*!< in: size of data to encrypt */ - -/********************************************************************* -Init threads for key rotation */ -void -fil_crypt_threads_init(); - -/********************************************************************* -Set thread count (e.g start or stops threads) used for key rotation */ -void -fil_crypt_set_thread_cnt( +ulint +fil_space_get_block_size( /*=====================*/ - uint new_cnt); /*!< in: requested #threads */ - -/********************************************************************* -End threads for key rotation */ -void -fil_crypt_threads_end(); - -/********************************************************************* -Cleanup resources for threads for key rotation */ -void -fil_crypt_threads_cleanup(); - -/********************************************************************* -Set rotate key age */ -void -fil_crypt_set_rotate_key_age( -/*=====================*/ - uint rotate_age); /*!< in: requested rotate age */ - -/********************************************************************* -Set rotation threads iops */ -void -fil_crypt_set_rotation_iops( -/*=====================*/ - uint iops); /*!< in: requested iops */ - -/********************************************************************* -Mark a space as closing */ -UNIV_INTERN -void -fil_space_crypt_mark_space_closing( -/*===============*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Wait for crypt threads to stop accessing space */ -UNIV_INTERN -void -fil_space_crypt_close_tablespace( -/*===============*/ - ulint space); /*!< in: tablespace id */ - -/** Struct for retreiving info about encryption */ -struct fil_space_crypt_status_t { - ulint space; /*!< tablespace id */ - ulint scheme; /*!< encryption scheme */ - uint min_key_version; /*!< min key version */ - uint current_key_version;/*!< current key version */ - uint keyserver_requests;/*!< no of key requests to key server */ - bool rotating; /*!< is key rotation ongoing */ - bool flushing; /*!< is flush at end of rotation ongoing */ - ulint rotate_next_page_number; /*!< next page if key rotating */ - ulint rotate_max_page_number; /*!< max page if key rotating */ -}; - -/********************************************************************* -Get crypt status for a space -@return 0 if crypt data found */ -int -fil_space_crypt_get_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_crypt_status_t * status); /*!< out: status */ - -/** Struct for retreiving statistics about encryption key rotation */ -struct fil_crypt_stat_t { - ulint pages_read_from_cache; - ulint pages_read_from_disk; - ulint pages_modified; - ulint pages_flushed; - ulint estimated_iops; -}; - -/********************************************************************* -Get crypt rotation statistics */ -void -fil_crypt_total_stat( -/*==================*/ - fil_crypt_stat_t* stat); /*!< out: crypt stat */ - -/** Struct for retreiving info about scrubbing */ -struct fil_space_scrub_status_t { - ulint space; /*!< tablespace id */ - bool compressed; /*!< is space compressed */ - time_t last_scrub_completed; /*!< when was last scrub completed */ - bool scrubbing; /*!< is scrubbing ongoing */ - time_t current_scrub_started; /*!< when started current scrubbing */ - ulint current_scrub_active_threads; /*!< current scrub active threads */ - ulint current_scrub_page_number; /*!< current scrub page no */ - ulint current_scrub_max_page_number; /*!< current scrub max page no */ -}; - -/********************************************************************* -Get scrub status for a space -@return 0 if no scrub info found */ -int -fil_space_get_scrub_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_scrub_status_t * status); /*!< out: status */ + ulint id, /*!< in: space id */ + ulint offset, /*!< in: page offset */ + ulint len); /*!< in: page len */ #endif -/*******************************************************************//** -Return page type name */ -const char* -fil_get_page_type_name( -/*===================*/ - ulint page_type); /*!< in: FIL_PAGE_TYPE */ +#ifndef UNIV_INNOCHECKSUM +#ifndef UNIV_NONINL +#include "fil0fil.ic" +#endif +#endif #endif /* fil0fil_h */ diff --git a/storage/innobase/include/fil0fil.ic b/storage/innobase/include/fil0fil.ic new file mode 100644 index 00000000000..b1e65e6dddb --- /dev/null +++ b/storage/innobase/include/fil0fil.ic @@ -0,0 +1,108 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0fil.ic +The low-level file system support functions + +Created 31/03/2015 Jan Lindström +*******************************************************/ + +#ifndef fil0fil_ic +#define fil0fil_ic + +/*******************************************************************//** +Return space name */ +UNIV_INLINE +char* +fil_space_name( +/*===========*/ + fil_space_t* space) /*!< in: space */ +{ + return (space->name); +} + +/*******************************************************************//** +Return space flags */ +UNIV_INLINE +ulint +fil_space_flags( +/*===========*/ + fil_space_t* space) /*!< in: space */ +{ + return (space->flags); +} + +/*******************************************************************//** +Return page type name */ +UNIV_INLINE +const char* +fil_get_page_type_name( +/*===================*/ + ulint page_type) /*!< in: FIL_PAGE_TYPE */ +{ + switch(page_type) { + case FIL_PAGE_PAGE_COMPRESSED: + return (const char*)"PAGE_COMPRESSED"; + case FIL_PAGE_INDEX: + return (const char*)"INDEX"; + case FIL_PAGE_UNDO_LOG: + return (const char*)"UNDO LOG"; + case FIL_PAGE_INODE: + return (const char*)"INODE"; + case FIL_PAGE_IBUF_FREE_LIST: + return (const char*)"IBUF_FREE_LIST"; + case FIL_PAGE_TYPE_ALLOCATED: + return (const char*)"ALLOCATED"; + case FIL_PAGE_IBUF_BITMAP: + return (const char*)"IBUF_BITMAP"; + case FIL_PAGE_TYPE_SYS: + return (const char*)"SYS"; + case FIL_PAGE_TYPE_TRX_SYS: + return (const char*)"TRX_SYS"; + case FIL_PAGE_TYPE_FSP_HDR: + return (const char*)"FSP_HDR"; + case FIL_PAGE_TYPE_XDES: + return (const char*)"XDES"; + case FIL_PAGE_TYPE_BLOB: + return (const char*)"BLOB"; + case FIL_PAGE_TYPE_ZBLOB: + return (const char*)"ZBLOB"; + case FIL_PAGE_TYPE_ZBLOB2: + return (const char*)"ZBLOB2"; + case FIL_PAGE_TYPE_COMPRESSED: + return (const char*)"ORACLE PAGE COMPRESSED"; + default: + return (const char*)"PAGE TYPE CORRUPTED"; + } +} + +/****************************************************************//** +Get block size from fil node +@return block size*/ +UNIV_INLINE +ulint +fil_node_get_block_size( +/*====================*/ + fil_node_t* node) /*!< in: Node where to get block + size */ +{ + return (node->file_block_size); +} + +#endif /* fil0fil_ic */ diff --git a/storage/innobase/include/fil0pageencryption.h b/storage/innobase/include/fil0pageencryption.h deleted file mode 100644 index 405b91c8c06..00000000000 --- a/storage/innobase/include/fil0pageencryption.h +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - -Copyright (C) 2014 eperi GmbH. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -#ifndef fil0pageencryption_h -#define fil0pageencryption_h - -#define PAGE_ENCRYPTION_WRONG_KEY 1 -#define PAGE_ENCRYPTION_WRONG_PAGE_TYPE 2 -#define PAGE_ENCRYPTION_ERROR 3 -#define PAGE_ENCRYPTION_KEY_MISSING 4 -#define PAGE_ENCRYPTION_OK 0 -#define PAGE_ENCRYPTION_WILL_NOT_ENCRYPT 5 - -/* This key will be used if nothing else is given */ -#define DEFAULT_ENCRYPTION_KEY 1 - -#include "fsp0fsp.h" -#include "fsp0pageencryption.h" - -/******************************************************************//** -@file include/fil0pageencryption.h -Helper functions for encryption/decryption page data on to table space. - -Created 08/25/2014 -***********************************************************************/ - -/*******************************************************************//** -Find out whether the page is page encrypted -Returns the page encryption flag of the space, or false if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return true if page encrypted, false if not or space not found */ -ibool -fil_space_is_page_encrypted( -/*========================*/ - ulint id); /*!< in: space id */ - -/*******************************************************************//** -Find out whether the page is page encrypted -@return true if page is page encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_encrypted( -/*==================*/ - const byte *buf); /*!< in: page */ - -/*******************************************************************//** -Find out whether the page is page compressed and then encrypted -@return true if page is page compressed+encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_compressed_encrypted( -/*=============================*/ - const byte *buf); /*!< in: page */ - -/*******************************************************************//** -Find out whether the page can be decrypted -@return true if page can be decrypted, false if not. */ -UNIV_INLINE -ulint -fil_page_encryption_status( -/*=======================*/ - const byte *buf); /*!< in: page */ - -#endif // fil0pageencryption_h diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index ee1ab4c7f55..2bac42eb081 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -59,10 +59,6 @@ is found in a remote location, not the default data directory. */ #define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 #define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4 -/** Number of flag bits used to indicate the page compression and compression level */ -#define FSP_FLAGS_WIDTH_PAGE_ENCRYPTION 1 -#define FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY 8 - /** Number of flag bits used to indicate atomic writes for this tablespace */ #define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2 @@ -74,9 +70,7 @@ is found in a remote location, not the default data directory. */ + FSP_FLAGS_WIDTH_DATA_DIR \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY) + + FSP_FLAGS_WIDTH_ATOMIC_WRITES ) /** A mask of all the known/used bits in tablespace flags */ #define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) @@ -100,15 +94,9 @@ dictionary */ /** Zero relative shift position of the ATOMIC_WRITES field */ #define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL) -/** Zero relative shift position of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_POS_PAGE_ENCRYPTION (FSP_FLAGS_POS_ATOMIC_WRITES \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES) -/** Zero relative shift position of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY (FSP_FLAGS_POS_PAGE_ENCRYPTION \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION) /** Zero relative shift position of the PAGE_SSIZE field */ -#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY) +#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \ + + FSP_FLAGS_WIDTH_ATOMIC_WRITES) /** Zero relative shift position of the start of the UNUSED bits */ #define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \ + FSP_FLAGS_WIDTH_PAGE_SSIZE) @@ -144,14 +132,6 @@ dictionary */ #define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \ ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \ << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Bit mask of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_MASK_PAGE_ENCRYPTION \ - ((~(~0 << FSP_FLAGS_WIDTH_PAGE_ENCRYPTION)) \ - << FSP_FLAGS_POS_PAGE_ENCRYPTION) -/** Bit mask of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_MASK_PAGE_ENCRYPTION_KEY \ - ((~(~0 << FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY)) \ - << FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY) /** Bit mask of the ATOMIC_WRITES field */ #define FSP_FLAGS_MASK_ATOMIC_WRITES \ ((~(~0 << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \ @@ -192,14 +172,6 @@ dictionary */ #define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \ ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \ >> FSP_FLAGS_POS_ATOMIC_WRITES) -/** Return the value of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_GET_PAGE_ENCRYPTION(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_ENCRYPTION) \ - >> FSP_FLAGS_POS_PAGE_ENCRYPTION) -/** Return the value of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_ENCRYPTION_KEY) \ - >> FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY) /** Set a PAGE_SSIZE into the correct bits in a given tablespace flags. */ @@ -216,13 +188,6 @@ tablespace flags. */ #define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \ (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)) -/** Set a PAGE_ENCRYPTION into the correct bits in a given tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_ENCRYPTION(flags, encryption) \ - (flags | (encryption << FSP_FLAGS_POS_PAGE_ENCRYPTION)) -/** Set a PAGE_ENCRYPTION_KEY into the correct bits in a given tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_ENCRYPTION_KEY(flags, encryption_key) \ - (flags | (encryption_key << FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY)) - /** Set a ATOMIC_WRITES into the correct bits in a given tablespace flags. */ #define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \ diff --git a/storage/innobase/include/fsp0pageencryption.h b/storage/innobase/include/fsp0pageencryption.h deleted file mode 100644 index 52365c8e93c..00000000000 --- a/storage/innobase/include/fsp0pageencryption.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - - Copyright (C) 2014 eperi GmbH. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************/ - -/******************************************************************//** -@file include/fsp0pageencryption.h -Helper functions for extracting/storing page encryption information to file space. - -Created 08/28/2014 -***********************************************************************/ - -#ifndef FSP0PAGEENCRYPTION_H_ -#define FSP0PAGEENCRYPTION_H_ - - -#define FIL_PAGE_ENCRYPTION_AES_128 16 /*!< Encryption algorithm AES-128. */ -#define FIL_PAGE_ENCRYPTION_AES_196 24 /*!< Encryption algorithm AES-196. */ -#define FIL_PAGE_ENCRYPTION_AES_256 32 /*!< Encryption algorithm AES-256. */ - -#define FIL_PAGE_ENCRYPTED_SIZE 2 /*!< Number of bytes used to store - actual payload data size on encrypted pages. */ - -/********************************************************************//** -Determine if the tablespace is page encrypted from dict_table_t::flags. -@return TRUE if page encrypted, FALSE if not page encrypted */ -UNIV_INLINE -ibool -fsp_flags_is_page_encrypted( -/*=========================*/ - ulint flags); /*!< in: tablespace flags */ - - -/********************************************************************//** -Extract the page encryption key from tablespace flags. -A tablespace has only one physical page encryption key -whether that page is encrypted or not. -@return page encryption key of the file-per-table tablespace, -or zero if the table is not encrypted. */ -UNIV_INLINE -ulint -fsp_flags_get_page_encryption_key( -/*=================================*/ - ulint flags); /*!< in: tablespace flags */ - - -#ifndef UNIV_NONINL -#include "fsp0pageencryption.ic" -#endif - - -#endif /* FSP0PAGEENCRYPTION_H_ */ diff --git a/storage/innobase/include/fsp0pageencryption.ic b/storage/innobase/include/fsp0pageencryption.ic deleted file mode 100644 index b5c3f5ab666..00000000000 --- a/storage/innobase/include/fsp0pageencryption.ic +++ /dev/null @@ -1,167 +0,0 @@ -/***************************************************************************** - - Copyright (C) 2014 eperi GmbH. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** -@file include/fsp0pageencryption.ic -Implementation for helper functions for encrypting/decrypting pages -and atomic writes information to file space. - -Created 08/28/2014 -***********************************************************************/ - -#include "fsp0fsp.h" -#include "fil0pageencryption.h" - - -/********************************************************************//** -Determine if the tablespace is page encrypted from dict_table_t::flags. -@return TRUE if page encrypted, FALSE if not page encrypted */ -UNIV_INLINE -ibool -fsp_flags_is_page_encrypted( -/*=========================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_ENCRYPTION(flags)); -} - -/********************************************************************//** -Extract the page encryption key from tablespace flags. -A tablespace has only one physical page encryption key -whether that page is encrypted or not. -@return page encryption key of the file-per-table tablespace, -or zero if the table is not encrypted. */ -UNIV_INLINE -ulint -fsp_flags_get_page_encryption_key( -/*=================================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(flags)); -} - - -/*******************************************************************//** -Returns the page encryption flag of the space, or false if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return true if page encrypted, false if not or space not found */ -UNIV_INLINE -ibool -fil_space_is_page_encrypted( -/*=========================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_is_page_encrypted(flags)); - } - - return(flags); -} - -/*******************************************************************//** -Returns the page encryption key of the space, or 0 if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return page compression level, ULINT_UNDEFINED if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_encryption_key( -/*=================================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_get_page_encryption_key(flags)); - } - - return(flags); -} - -/*******************************************************************//** -Find out whether the page is page is encrypted -@return true if page is page encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_encrypted( -/*==================*/ - const byte *buf) /*!< in: page */ -{ - return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_ENCRYPTED); -} - -/*******************************************************************//** -Find out whether the page is page is first compressed and then encrypted -@return true if page is page compressed+encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_compressed_encrypted( -/*=============================*/ - const byte *buf) /*!< in: page */ -{ - return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); -} - -/*******************************************************************//** -Find out whether the page can be decrypted. -This is the case, if the page is already decrypted and is not the first page of the table space. -If the page is already decrypted it is not of the FIL_PAGE_PAGE_ENCRYPTED type. -if it is the first page of the table space, it is assumed that a page can be decrypted if the -key found in the flags (part of the 1st page) can be read from the key provider. -The case, if the key changed, is currently not caught. -The function for decrypting the page should already be executed before this. -@return PAGE_ENCRYPTION_KEY_MISSING if key provider is available, but key is not available - PAGE_ENCRYPTION_ERROR if other error occurred - 0 if decryption should be possible -*/ -UNIV_INLINE -ulint -fil_page_encryption_status( -/*=====================*/ - const byte *buf) /*!< in: page */ -{ - ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE); - - if (page_type == FIL_PAGE_TYPE_FSP_HDR) { - ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf); - if (fsp_flags_is_page_encrypted(flags)) { - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - /* accessing table would surely fail, because no key or no key provider available */ - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - return PAGE_ENCRYPTION_KEY_MISSING; - } - return PAGE_ENCRYPTION_ERROR; - } - } - } - - if(page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - if (!has_encryption_key(key)) { - return PAGE_ENCRYPTION_KEY_MISSING; - } - return PAGE_ENCRYPTION_ERROR; - } - return 0; -} diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index f00d754ac66..a2996ecacc8 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -715,34 +715,6 @@ fts_drop_index_tables( dict_index_t* index) /*!< in: Index to drop */ __attribute__((nonnull, warn_unused_result)); -/****************************************************************** -Wait for background threads to stop using FTS index -*/ -UNIV_INTERN -void -fts_wait_bg_to_stop_using_index( -/*======================*/ - trx_t* trx, /*!< in: transaction */ - dict_index_t* index, /*!< in: FTS Index */ - bool drop_table); /*!< in: in addition to stop - using index, also prevent - threads from start using it, - used by drop table */ - -/****************************************************************** -Wait for background threads to stop using any FTS index of the table -*/ -UNIV_INTERN -void -fts_wait_bg_to_stop_using_table( -/*======================*/ - trx_t* trx, /*!< in: transaction */ - dict_table_t* table, /*!< in: table to stop threads */ - bool drop_table); /*!< in: in addition to stop - using table, also prevent - threads from start using it, - used by drop table */ - /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h index 9c7c0229ba4..c3cfd973e8d 100644 --- a/storage/innobase/include/log0crypt.h +++ b/storage/innobase/include/log0crypt.h @@ -11,11 +11,13 @@ Created 11/25/2013 Minli Zhu #include "ut0byte.h" #include "ut0lst.h" #include "ut0rnd.h" -#include "my_aes.h" +#include "my_crypt.h" #define PURPOSE_BYTE_LEN MY_AES_BLOCK_SIZE - 1 #define PURPOSE_BYTE_OFFSET 0 -#define UNENCRYPTED_KEY_VER 0 +#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_NOT_ENCRYPTED + +typedef int Crypt_result; /* If true, enable redo log encryption. */ extern my_bool srv_encrypt_log; diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 79667097724..eb2a09c8d29 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -1022,8 +1022,8 @@ struct log_t{ #endif /* UNIV_LOG_ARCHIVE */ extern os_event_t log_scrub_event; -/* log scrubbing interval in ms */ -extern ulonglong innodb_scrub_log_interval; +/* log scrubbing speed, in bytes/sec */ +extern ulonglong innodb_scrub_log_speed; /*****************************************************************//** This is the main thread for log scrub. It waits for an event and diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 99490fa044e..fe6b755dc59 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -312,25 +312,21 @@ The wrapper functions have the prefix of "innodb_". */ pfs_os_file_close_func(file, __FILE__, __LINE__) # define os_aio(type, mode, name, file, buf, offset, \ - n, message1, message2, write_size, \ - page_compression, page_compression_level, \ - page_encryption, page_encryption_key, lsn, encrypt) \ + n, message1, message2, write_size) \ pfs_os_aio_func(type, mode, name, file, buf, offset, \ n, message1, message2, write_size, \ - page_compression, page_compression_level, \ - page_encryption, page_encryption_key, \ - lsn, encrypt, __FILE__, __LINE__) + __FILE__, __LINE__) -# define os_file_read(file, buf, offset, n, compressed) \ - pfs_os_file_read_func(file, buf, offset, n, compressed, __FILE__, __LINE__) +# define os_file_read(file, buf, offset, n) \ + pfs_os_file_read_func(file, buf, offset, n, __FILE__, __LINE__) -# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ +# define os_file_read_no_error_handling(file, buf, offset, n) \ pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \ - compressed, __FILE__, __LINE__) + __FILE__, __LINE__) -# define os_file_write(name, file, buf, offset, n) \ - pfs_os_file_write_func(name, file, buf, offset, \ +# define os_file_write(name, file, buf, offset, n) \ + pfs_os_file_write_func(name, file, buf, offset, \ n, __FILE__, __LINE__) # define os_file_flush(file) \ @@ -362,18 +358,15 @@ to original un-instrumented file I/O APIs */ # define os_file_close(file) os_file_close_func(file) # define os_aio(type, mode, name, file, buf, offset, n, message1, \ - message2, write_size, page_compression, page_compression_level, \ - page_encryption, page_encryption_key, lsn, encrypt) \ + message2, write_size) \ os_aio_func(type, mode, name, file, buf, offset, n, \ - message1, message2, write_size, \ - page_compression, page_compression_level, \ - page_encryption, page_encryption_key, lsn, encrypt) + message1, message2, write_size) -# define os_file_read(file, buf, offset, n, compressed) \ - os_file_read_func(file, buf, offset, n, compressed) +# define os_file_read(file, buf, offset, n) \ + os_file_read_func(file, buf, offset, n) -# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ - os_file_read_no_error_handling_func(file, buf, offset, n, compressed) +# define os_file_read_no_error_handling(file, buf, offset, n) \ + os_file_read_no_error_handling_func(file, buf, offset, n) # define os_file_write(name, file, buf, offset, n) \ os_file_write_func(name, file, buf, offset, n) @@ -724,8 +717,6 @@ pfs_os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -744,8 +735,6 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -781,16 +770,6 @@ pfs_os_aio_func( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption - key to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later, /*!< in: should we encrypt ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ /*******************************************************************//** @@ -947,9 +926,7 @@ os_file_read_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed); /*!< in: is this file space - compressed ? */ + ulint n); /*!< in: number of bytes to read */ /*******************************************************************//** Rewind file to its start, read at most size - 1 bytes from it to str, and NUL-terminate str. All errors are silently ignored. This function is @@ -974,9 +951,7 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed); /*!< in: is this file space - compressed ? */ + ulint n); /*!< in: number of bytes to read */ /*******************************************************************//** NOTE! Use the corresponding macro os_file_write(), not directly this @@ -1160,21 +1135,11 @@ os_aio_func( (can be used to identify a completed aio operation); ignored if mode is OS_AIO_SYNC */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size);/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption key - to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later); /*!< in: should we encrypt ? */ /************************************************************************//** Wakes up all async i/o threads so that they know to exit themselves in shutdown. */ diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic index 9839a841188..db525bcea19 100644 --- a/storage/innobase/include/os0file.ic +++ b/storage/innobase/include/os0file.ic @@ -220,17 +220,6 @@ pfs_os_aio_func( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< in: page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption - key to be used */ - lsn_t lsn, /*!< in: lsn of the newest - modification */ - bool encrypt_later, /*!< in: encrypt later ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -246,9 +235,7 @@ pfs_os_aio_func( src_file, src_line); result = os_aio_func(type, mode, name, file, buf, offset, - n, message1, message2, write_size, - page_compression, page_compression_level, - page_encryption, page_encryption_key, lsn, encrypt_later); + n, message1, message2, write_size); register_pfs_file_io_end(locker, n); @@ -269,8 +256,6 @@ pfs_os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -281,7 +266,7 @@ pfs_os_file_read_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_func(file, buf, offset, n, compressed); + result = os_file_read_func(file, buf, offset, n); register_pfs_file_io_end(locker, n); @@ -304,8 +289,6 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -316,7 +299,7 @@ pfs_os_file_read_no_error_handling_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_no_error_handling_func(file, buf, offset, n, compressed); + result = os_file_read_no_error_handling_func(file, buf, offset, n); register_pfs_file_io_end(locker, n); diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index d1d902ef57d..79a8a5bf848 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -328,9 +328,8 @@ enum monitor_id_t { MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR, /* New monitor variables for page encryption */ - MONITOR_OVLD_PAGES_PAGE_ENCRYPTED, - MONITOR_OVLD_PAGES_PAGE_DECRYPTED, - MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR, + MONITOR_OVLD_PAGES_ENCRYPTED, + MONITOR_OVLD_PAGES_DECRYPTED, /* Index related counters */ MONITOR_MODULE_INDEX, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 31db78ae5ee..34f8432d19f 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -133,12 +133,10 @@ struct srv_stats_t { ulint_ctr_64_t pages_page_decompressed; /* Number of page compression errors */ ulint_ctr_64_t pages_page_compression_error; - /* Number of pages encrypted with page encryption */ - ulint_ctr_64_t pages_page_encrypted; - /* Number of pages decrypted with page encryption */ - ulint_ctr_64_t pages_page_decrypted; - /* Number of page encryption errors */ - ulint_ctr_64_t pages_page_encryption_error; + /* Number of pages encrypted */ + ulint_ctr_64_t pages_encrypted; + /* Number of pages decrypted */ + ulint_ctr_64_t pages_decrypted; /** Number of data read in total (in bytes) */ ulint_ctr_1_t data_read; @@ -546,7 +544,7 @@ extern my_bool srv_print_all_deadlocks; extern my_bool srv_cmp_per_index_enabled; /* is encryption enabled */ -extern my_bool srv_encrypt_tables; +extern ulong srv_encrypt_tables; /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars; @@ -562,9 +560,6 @@ that semaphore times out in InnoDB */ #define DEFAULT_SRV_FATAL_SEMAPHORE_TIMEOUT 600 extern ulong srv_fatal_semaphore_wait_threshold; -/** Default encryption key used for page encryption */ -extern uint srv_default_page_encryption_key; - /** Enable semaphore request instrumentation */ extern my_bool srv_instrument_semaphores; @@ -1020,16 +1015,13 @@ struct export_var_t{ compression */ ib_int64_t innodb_pages_page_compression_error;/*!< Number of page compression errors */ - ib_int64_t innodb_pages_page_encrypted;/*!< Number of pages - encrypted by page encryption */ - ib_int64_t innodb_pages_page_decrypted;/*!< Number of pages - decrypted by page encryption */ - ib_int64_t innodb_pages_page_encryption_error;/*!< Number of page - encryption errors */ + ib_int64_t innodb_pages_encrypted; /*!< Number of pages + encrypted */ + ib_int64_t innodb_pages_decrypted; /*!< Number of pages + decrypted */ ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */ - ulint innodb_sec_rec_cluster_reads_avoided; - /*!< srv_sec_rec_cluster_reads_avoided */ + ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */ ulint innodb_encryption_rotation_pages_read_from_cache; ulint innodb_encryption_rotation_pages_read_from_disk; diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc index 6f487e36b56..c3c943a808f 100644 --- a/storage/innobase/log/log0crypt.cc +++ b/storage/innobase/log/log0crypt.cc @@ -26,12 +26,12 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "m_string.h" #include "log0crypt.h" #include -#include +#include + #include "log0log.h" #include "srv0start.h" // for srv_start_lsn #include "log0recv.h" // for recv_sys -#include "mysql/plugin_encryption_key_management.h" // for BAD_ENCRYPTION_KEY_VERSION #include "ha_prototypes.h" // IB_LOG_ /* If true, enable redo log encryption. */ @@ -47,6 +47,8 @@ byte redo_log_crypt_msg[MY_AES_BLOCK_SIZE] = {0}; * encryption/decryption. */ byte aes_ctr_nonce[MY_AES_BLOCK_SIZE] = {0}; +#define LOG_DEFAULT_ENCRYPTION_KEY 1 + /*********************************************************************//** Generate a 128-bit value used to generate crypt key for redo log. It is generated via the concatenation of 1 purpose byte (0x02) and 15-byte @@ -69,7 +71,7 @@ log_init_crypt_msg_and_nonce(void) /*==============================*/ { mach_write_to_1(redo_log_crypt_msg, redo_log_purpose_byte); - if (my_random_bytes(redo_log_crypt_msg + 1, PURPOSE_BYTE_LEN) != AES_OK) + if (my_random_bytes(redo_log_crypt_msg + 1, PURPOSE_BYTE_LEN) != MY_AES_OK) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: generate " @@ -78,7 +80,7 @@ log_init_crypt_msg_and_nonce(void) abort(); } - if (my_random_bytes(aes_ctr_nonce, MY_AES_BLOCK_SIZE) != AES_OK) + if (my_random_bytes(aes_ctr_nonce, MY_AES_BLOCK_SIZE) != MY_AES_OK) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: generate " @@ -116,7 +118,8 @@ log_init_crypt_key( } byte mysqld_key[MY_AES_BLOCK_SIZE] = {0}; - if (get_encryption_key(crypt_ver, mysqld_key, MY_AES_BLOCK_SIZE)) + uint keylen= sizeof(mysqld_key); + if (encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY, crypt_ver, mysqld_key, &keylen)) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: getting mysqld crypto key " @@ -125,14 +128,12 @@ log_init_crypt_key( } uint32 dst_len; - my_aes_encrypt_dynamic_type func= get_aes_encrypt_func(MY_AES_ALGORITHM_ECB); - int rc= (*func)(crypt_msg, MY_AES_BLOCK_SIZE, //src, srclen + int rc= my_aes_encrypt_ecb(crypt_msg, MY_AES_BLOCK_SIZE, //src, srclen key, &dst_len, //dst, &dstlen (unsigned char*)&mysqld_key, sizeof(mysqld_key), - NULL, 0, - 1); + NULL, 0, 1); - if (rc != AES_OK || dst_len != MY_AES_BLOCK_SIZE) + if (rc != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: getting redo log crypto key " @@ -169,23 +170,12 @@ log_blocks_crypt( const bool is_encrypt) /*!< in: encrypt or decrypt*/ { byte *log_block = (byte*)block; - Crypt_result rc = AES_OK; + Crypt_result rc = MY_AES_OK; uint32 src_len, dst_len; byte aes_ctr_counter[MY_AES_BLOCK_SIZE]; ulint log_block_no, log_block_start_lsn; - byte *key; - ulint lsn; - if (is_encrypt) - { - ut_a(log_sys && log_sys->redo_log_crypt_ver != UNENCRYPTED_KEY_VER); - key = (byte *)(log_sys->redo_log_crypt_key); - lsn = log_sys->lsn; + ulint lsn = is_encrypt ? log_sys->lsn : srv_start_lsn; - } else { - ut_a(recv_sys && recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER); - key = (byte *)(recv_sys->recv_log_crypt_key); - lsn = srv_start_lsn; - } ut_a(size % OS_FILE_LOG_BLOCK_SIZE == 0); src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE; for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) @@ -205,13 +195,28 @@ log_blocks_crypt( mach_write_to_4(aes_ctr_counter + 11, log_block_no); bzero(aes_ctr_counter + 15, 1); - int rc = (* my_aes_encrypt_dynamic)(log_block + LOG_BLOCK_HDR_SIZE, src_len, - dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, - (unsigned char*)key, 16, - aes_ctr_counter, MY_AES_BLOCK_SIZE, - 1); + int rc; + if (is_encrypt) { + ut_a(log_sys); + ut_a(log_sys->redo_log_crypt_ver != UNENCRYPTED_KEY_VER); + rc = encryption_encrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len, + dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, + (unsigned char*)(log_sys->redo_log_crypt_key), 16, + aes_ctr_counter, MY_AES_BLOCK_SIZE, 1, + LOG_DEFAULT_ENCRYPTION_KEY, + log_sys->redo_log_crypt_ver); + } else { + ut_a(recv_sys); + ut_a(recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER); + rc = encryption_decrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len, + dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, + (unsigned char*)(recv_sys->recv_log_crypt_key), 16, + aes_ctr_counter, MY_AES_BLOCK_SIZE, 1, + LOG_DEFAULT_ENCRYPTION_KEY, + recv_sys->recv_log_crypt_ver); + } - ut_a(rc == AES_OK); + ut_a(rc == MY_AES_OK); ut_a(dst_len == src_len); log_block += OS_FILE_LOG_BLOCK_SIZE; dst_block += OS_FILE_LOG_BLOCK_SIZE; @@ -260,12 +265,11 @@ log_crypt_set_ver_and_key( if (srv_encrypt_log) { unsigned int vkey; - vkey = get_latest_encryption_key_version(); + vkey = encryption_key_get_latest_version(LOG_DEFAULT_ENCRYPTION_KEY); encrypted = true; if (vkey == UNENCRYPTED_KEY_VER || - vkey == BAD_ENCRYPTION_KEY_VERSION || - vkey == (unsigned int)CRYPT_KEY_UNKNOWN) { + vkey == ENCRYPTION_KEY_VERSION_INVALID) { encrypted = false; ib_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 12c05e16b6b..80ae3529354 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1276,7 +1276,7 @@ log_group_file_header_flush( (ulint) (dest_offset / UNIV_PAGE_SIZE), (ulint) (dest_offset % UNIV_PAGE_SIZE), OS_FILE_LOG_BLOCK_SIZE, - buf, group, 0, 0, false); + buf, group, 0); srv_stats.os_log_pending_writes.dec(); } @@ -1307,7 +1307,7 @@ log_group_encrypt_before_write( const ulint size) /*!< in: size of log blocks */ { - Crypt_result result = AES_OK; + Crypt_result result = MY_AES_OK; ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0); byte* dst_frame = (byte*)malloc(size); @@ -1315,14 +1315,14 @@ log_group_encrypt_before_write( //encrypt log blocks content result = log_blocks_encrypt(block, size, dst_frame); - if (result == AES_OK) + if (result == MY_AES_OK) { ut_ad(block[0] == dst_frame[0]); memcpy(block, dst_frame, size); } free(dst_frame); - return (result == AES_OK); + return (result == MY_AES_OK); } /******************************************************//** @@ -1443,7 +1443,7 @@ loop: fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, group->space_id, 0, (ulint) (next_offset / UNIV_PAGE_SIZE), (ulint) (next_offset % UNIV_PAGE_SIZE), write_len, buf, - group, 0, 0, false); + group, 0); srv_stats.os_log_pending_writes.dec(); @@ -2011,7 +2011,7 @@ log_group_checkpoint( write_offset / UNIV_PAGE_SIZE, write_offset % UNIV_PAGE_SIZE, OS_FILE_LOG_BLOCK_SIZE, - buf, ((byte*) group + 1), 0, 0, false); + buf, ((byte*) group + 1), 0); ut_ad(((ulint) group & 0x1UL) == 0); } @@ -2093,7 +2093,7 @@ log_group_read_checkpoint_info( fil_io(OS_FILE_READ | OS_FILE_LOG, true, group->space_id, 0, field / UNIV_PAGE_SIZE, field % UNIV_PAGE_SIZE, - OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL, 0, 0, false); + OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL, 0); } /******************************************************//** @@ -2357,13 +2357,13 @@ log_group_decrypt_after_read( // decrypt log blocks content result = log_blocks_decrypt(frame, size, dst_frame); - if (result == AES_OK) + if (result == MY_AES_OK) { memcpy(frame, dst_frame, size); } free(dst_frame); - return (result == AES_OK); + return (result == MY_AES_OK); } /******************************************************//** @@ -2417,7 +2417,7 @@ loop: fil_io(OS_FILE_READ | OS_FILE_LOG, sync, group->space_id, 0, (ulint) (source_offset / UNIV_PAGE_SIZE), (ulint) (source_offset % UNIV_PAGE_SIZE), - len, buf, NULL, 0, 0, false); + len, buf, NULL, 0); if (recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER && !log_group_decrypt_after_read(group, buf, len)) @@ -3857,8 +3857,8 @@ log_scrub() next_lbn_to_pad = log_block_convert_lsn_to_no(log_sys->lsn); } -/* log scrubbing interval in ms. */ -UNIV_INTERN ulonglong innodb_scrub_log_interval; +/* log scrubbing speed, in bytes/sec */ +UNIV_INTERN ulonglong innodb_scrub_log_speed; /*****************************************************************//** This is the main thread for log scrub. It waits for an event and @@ -3878,7 +3878,10 @@ DECLARE_THREAD(log_scrub_thread)( while(srv_shutdown_state == SRV_SHUTDOWN_NONE) { - os_event_wait_time(log_scrub_event, innodb_scrub_log_interval * 1000); + /* log scrubbing interval in µs. */ + ulonglong interval = 1000*1000*512/innodb_scrub_log_speed; + + os_event_wait_time(log_scrub_event, interval); log_scrub(); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index d0f2cd360f9..3b8c4878e32 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -49,6 +49,7 @@ Created 9/20/1997 Heikki Tuuri #include "trx0undo.h" #include "trx0rec.h" #include "fil0fil.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP # include "buf0rea.h" # include "srv0srv.h" @@ -3101,7 +3102,7 @@ recv_recovery_from_checkpoint_start_func( fil_io(OS_FILE_READ | OS_FILE_LOG, true, max_cp_group->space_id, 0, 0, 0, LOG_FILE_HDR_SIZE, - log_hdr_buf, max_cp_group, 0, 0, false); + log_hdr_buf, max_cp_group, 0); if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, (byte*)"ibbackup", (sizeof "ibbackup") - 1)) { @@ -3132,7 +3133,7 @@ recv_recovery_from_checkpoint_start_func( fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, max_cp_group->space_id, 0, 0, 0, OS_FILE_LOG_BLOCK_SIZE, - log_hdr_buf, max_cp_group, 0, 0, false); + log_hdr_buf, max_cp_group, 0); } #ifdef UNIV_LOG_ARCHIVE diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index d49f5f9900d..e17cf161973 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -43,9 +43,9 @@ Created 10/21/1995 Heikki Tuuri #include "srv0srv.h" #include "srv0start.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "fsp0fsp.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #include "buf0buf.h" #include "srv0mon.h" #include "srv0srv.h" @@ -224,49 +224,14 @@ struct os_aio_slot_t{ completed */ ulint bitmap; - byte* page_compression_page; /*!< Memory allocated for - page compressed page and - freed after the write - has been completed */ - - byte* page_encryption_page; /*!< Memory allocated for - page encrypted page and - freed after the write - has been completed */ - - ibool page_compression; - ulint page_compression_level; - - ibool page_encryption; - ulint page_encryption_key; - ulint* write_size; /*!< Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - byte* page_buf; /*!< Actual page buffer for - page compressed pages, do not - free this */ - - byte* page_buf2; /*!< Actual page buffer for - page encrypted pages, do not - free this */ - byte* tmp_encryption_buf; /*!< a temporal buffer used by page encryption */ - - ibool page_compression_success; - /*!< TRUE if page compression was successfull, false if not */ - ibool page_encryption_success; - /*!< TRUE if page encryption was successfull, false if not */ - - lsn_t lsn; /* lsn of the newest modification */ - ulint file_block_size;/*!< file block size */ - bool encrypt_later; /*!< should the page be encrypted - before write */ - #ifdef WIN_ASYNC_IO HANDLE handle; /*!< handle object we need in the OVERLAPPED struct */ @@ -277,7 +242,6 @@ struct os_aio_slot_t{ int n_bytes; /* bytes written/read. */ int ret; /* AIO return code */ #endif /* WIN_ASYNC_IO */ - byte *lzo_mem; /* Temporal memory used by LZO */ }; /** The asynchronous i/o array structure */ @@ -403,39 +367,6 @@ os_file_trim( /*=========*/ os_aio_slot_t* slot); /*!< in: slot structure */ -/**********************************************************************//** -Allocate memory for temporal buffer used for page compression. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf( -/*===================*/ - os_aio_slot_t* slot); /*!< in: slot structure */ - -#ifdef HAVE_LZO -/**********************************************************************//** -Allocate memory for temporal memory used for page compression when -LZO compression method is used */ -UNIV_INTERN -void -os_slot_alloc_lzo_mem( -/*===================*/ - os_aio_slot_t* slot); /*!< in: slot structure */ -#endif - -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf2( - os_aio_slot_t* slot); /*!< in: slot structure */ -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. */ -UNIV_INTERN -void -os_slot_alloc_tmp_encryption_buf( - os_aio_slot_t* slot); /*!< in: slot structure */ /****************************************************************//** Does error handling when a file operation fails. @return TRUE if we should retry the operation */ @@ -2891,9 +2822,7 @@ os_file_read_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed) /*!< in: is this file space - compressed ? */ + ulint n) /*!< in: number of bytes to read */ { #ifdef __WIN__ BOOL ret; @@ -3024,9 +2953,7 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed) /*!< in: is this file space - compressed ? */ + ulint n) /*!< in: number of bytes to read */ { #ifdef __WIN__ BOOL ret; @@ -4184,9 +4111,8 @@ os_aio_array_free( /*==============*/ os_aio_array_t*& array) /*!< in, own: array to free */ { - ulint i; #ifdef WIN_ASYNC_IO - + ulint i; for (i = 0; i < array->n_slots; i++) { os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); CloseHandle(slot->handle); @@ -4207,31 +4133,6 @@ os_aio_array_free( } #endif /* LINUX_NATIVE_AIO */ - for (i = 0; i < array->n_slots; i++) { - os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); - - if (slot->page_compression_page) { - ut_free(slot->page_compression_page); - slot->page_compression_page = NULL; - } - - if (slot->lzo_mem) { - ut_free(slot->lzo_mem); - slot->lzo_mem = NULL; - } - - if (slot->page_encryption_page) { - ut_free(slot->page_encryption_page); - slot->page_encryption_page = NULL; - } - - if (slot->tmp_encryption_buf) { - ut_free(slot->tmp_encryption_buf); - slot->tmp_encryption_buf = NULL; - } - } - - ut_free(array->slots); ut_free(array); @@ -4566,22 +4467,11 @@ os_aio_array_reserve_slot( to write */ os_offset_t offset, /*!< in: file offset */ ulint len, /*!< in: length of the block to read or write */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size)/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption key - to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: should we encrypt before - writing the page */ { os_aio_slot_t* slot = NULL; #ifdef WIN_ASYNC_IO @@ -4669,95 +4559,13 @@ found: slot->len = len; slot->type = type; slot->offset = offset; - slot->lsn = lsn; slot->io_already_done = FALSE; - slot->page_compression_success = FALSE; - slot->page_encryption_success = FALSE; slot->write_size = write_size; - slot->page_compression_level = page_compression_level; - slot->page_compression = page_compression; - slot->page_encryption_key = page_encryption_key; - slot->page_encryption = page_encryption; - slot->encrypt_later = encrypt_later; if (message1) { slot->file_block_size = fil_node_get_block_size(message1); } - /* If the space is page compressed and this is write operation - then we compress the page */ - if (message1 && type == OS_FILE_WRITE && page_compression ) { - ulint real_len = len; - byte* tmp = NULL; - - /* Release the array mutex while compressing */ - os_mutex_exit(array->mutex); - - // We allocate memory for page compressed buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf(slot); - -#ifdef HAVE_LZO - if (innodb_compression_algorithm == 3) { - os_slot_alloc_lzo_mem(slot); - } -#endif - - /* Call page compression */ - tmp = fil_compress_page( - fil_node_get_space_id(slot->message1), - (byte *)buf, - slot->page_buf, - len, - page_compression_level, - fil_node_get_block_size(slot->message1), - &real_len, - slot->lzo_mem - ); - - /* If compression succeeded, set up the length and buffer */ - if (tmp != buf) { - len = real_len; - buf = slot->page_buf; - slot->len = real_len; - slot->page_compression_success = TRUE; - } else { - slot->page_compression_success = FALSE; - } - - /* Take array mutex back, not sure if this is really needed - below */ - os_mutex_enter(array->mutex); - - } - - /* If the space is page encryption and this is write operation - then we encrypt the page */ - if (message1 && type == OS_FILE_WRITE && (page_encryption == 1 || encrypt_later)) { - ut_a(page_encryption == 1 || srv_encrypt_tables == 1); - /* Release the array mutex while encrypting */ - os_mutex_exit(array->mutex); - - // We allocate memory for page encrypted buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf2(slot); - - fil_space_encrypt( - fil_node_get_space_id(slot->message1), - slot->offset, - slot->lsn, - (byte *)buf, - slot->len, - slot->page_buf2, - slot->page_encryption_key); - - slot->page_encryption_success = TRUE; - buf = slot->page_buf2; - - /* Take array mutex back */ - os_mutex_enter(array->mutex); - } - slot->buf = static_cast(buf); #ifdef WIN_ASYNC_IO @@ -5037,22 +4845,11 @@ os_aio_func( (can be used to identify a completed aio operation); ignored if mode is OS_AIO_SYNC */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size)/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption key - to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: should we encrypt page - before write */ { os_aio_array_t* array; os_aio_slot_t* slot; @@ -5104,8 +4901,7 @@ os_aio_func( and os_file_write_func() */ if (type == OS_FILE_READ) { - ret = os_file_read_func(file, buf, offset, n, - page_compression); + ret = os_file_read_func(file, buf, offset, n); } else { ut_ad(!srv_read_only_mode); @@ -5163,9 +4959,7 @@ try_again: } slot = os_aio_array_reserve_slot(type, array, message1, message2, file, - name, buf, offset, n, write_size, - page_compression, page_compression_level, - page_encryption, page_encryption_key, lsn, encrypt_later); + name, buf, offset, n, write_size); if (type == OS_FILE_READ) { if (srv_use_native_aio) { @@ -5192,18 +4986,9 @@ try_again: if (srv_use_native_aio) { os_n_file_writes++; #ifdef WIN_ASYNC_IO - if (page_encryption && slot->page_encryption_success) { - buffer = slot->page_buf2; - n = slot->len; - } else { - if (page_compression && slot->page_compression_success) { - buffer = slot->page_buf; - n = slot->len; - } else { - buffer = buf; - } - } + n = slot->len; + buffer = buf; ret = WriteFile(file, buffer, (DWORD) n, &len, &(slot->control)); @@ -5409,27 +5194,9 @@ os_aio_windows_handle( switch (slot->type) { case OS_FILE_WRITE: - if (slot->message1 - && slot->page_encryption - && slot->page_encryption_success) { - ret_val = os_file_write(slot->name, - slot->file, - slot->page_buf2, - slot->offset, - slot->len); - } else { - if (slot->message1 - && slot->page_compression - && slot->page_compression_success) { - ret = WriteFile(slot->file, slot->page_buf, - (DWORD) slot->len, &len, - &(slot->control)); - } else { - ret = WriteFile(slot->file, slot->buf, - (DWORD) slot->len, &len, - &(slot->control)); - } - } + ret = WriteFile(slot->file, slot->buf, + (DWORD) slot->len, &len, + &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, @@ -5460,47 +5227,9 @@ os_aio_windows_handle( ret_val = ret && len == slot->len; } - if (slot->type == OS_FILE_READ) { - if (fil_page_is_compressed_encrypted(slot->buf) || - fil_page_is_encrypted(slot->buf)) { - ut_ad(slot->message1 != NULL); - os_slot_alloc_page_buf2(slot); - os_slot_alloc_tmp_encryption_buf(slot); - - // Decrypt the data - fil_space_decrypt( - fil_node_get_space_id(slot->message1), - slot->buf, - slot->len, - slot->page_buf2); - // Copy decrypted buffer back to buf - memcpy(slot->buf, slot->page_buf2, slot->len); - } - if (fil_page_is_compressed(slot->buf)) { - /* We allocate memory for page compressed buffer if - and only if it is not yet allocated. */ - os_slot_alloc_page_buf(slot); -#ifdef HAVE_LZO - if (fil_page_is_lzo_compressed(slot->buf)) { - os_slot_alloc_lzo_mem(slot); - } -#endif - fil_decompress_page( - slot->page_buf, - slot->buf, - slot->len, - slot->write_size); - } - } else { - /* OS_FILE_WRITE */ - if (slot->page_compression_success && - (fil_page_is_compressed(slot->page_buf) || - fil_page_is_compressed_encrypted(slot->buf))) { - if (srv_use_trim && os_fallocate_failed == FALSE) { - // Deallocate unused blocks from file system - os_file_trim(slot); - } - } + if (slot->type == OS_FILE_WRITE && srv_use_trim && os_fallocate_failed == FALSE) { + // Deallocate unused blocks from file system + os_file_trim(slot); } os_aio_array_free_slot(array, slot); @@ -5592,50 +5321,9 @@ retry: /* We have not overstepped to next segment. */ ut_a(slot->pos < end_pos); - if (slot->type == OS_FILE_READ) { - /* If the page is page encrypted we encrypt */ - if (fil_page_is_compressed_encrypted(slot->buf) || - fil_page_is_encrypted(slot->buf)) { - os_slot_alloc_page_buf2(slot); - os_slot_alloc_tmp_encryption_buf(slot); - ut_ad(slot->message1 != NULL); - - // Decrypt the data - fil_space_decrypt( - fil_node_get_space_id(slot->message1), - slot->buf, - slot->len, - slot->page_buf2); - // Copy decrypted buffer back to buf - memcpy(slot->buf, slot->page_buf2, slot->len); - } - - /* If the table is page compressed and this - is read, we decompress before we announce - the read is complete. For writes, we free - the compressed page. */ - if (fil_page_is_compressed(slot->buf)) { - // We allocate memory for page compressed buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf(slot); -#ifdef HAVE_LZO - if (fil_page_is_lzo_compressed(slot->buf)) { - os_slot_alloc_lzo_mem(slot); - } -#endif - - fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size); - } - } else { - /* OS_FILE_WRITE */ - if (slot->page_compression_success && - (fil_page_is_compressed(slot->page_buf) || - fil_page_is_compressed_encrypted(slot->buf))) { - if (srv_use_trim && os_fallocate_failed == FALSE) { - // Deallocate unused blocks from file system - os_file_trim(slot); - } - } + if (slot->type == OS_FILE_WRITE && srv_use_trim && os_fallocate_failed == FALSE) { + // Deallocate unused blocks from file system + os_file_trim(slot); } /* Mark this request as completed. The error handling @@ -6080,8 +5768,7 @@ consecutive_loop: } else { ret = os_file_read( aio_slot->file, combined_buf, - aio_slot->offset, total_len, - aio_slot->page_compression); + aio_slot->offset, total_len); } srv_set_io_thread_op_info(global_segment, "file i/o done"); @@ -6653,92 +6340,6 @@ os_file_trim( } #endif /* !UNIV_HOTBACKUP */ -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf2( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - - if(slot->page_buf2 == NULL) { - byte* cbuf2; - byte* cbuf; - - cbuf2 = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); - cbuf = static_cast(ut_align(cbuf2, UNIV_PAGE_SIZE)); - slot->page_encryption_page = static_cast(cbuf2); - slot->page_buf2 = static_cast(cbuf); - memset(slot->page_encryption_page, 0, UNIV_PAGE_SIZE*2); - } -} - -/**********************************************************************//** -Allocate memory for temporal buffer used for page compression. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if (slot->page_buf == NULL) { - byte* cbuf2; - byte* cbuf; - ulint asize = UNIV_PAGE_SIZE; -#ifdef HAVE_SNAPPY - asize += snappy_max_compressed_length(asize) - UNIV_PAGE_SIZE; -#endif - - /* We allocate extra to avoid memory overwrite on compression */ - cbuf2 = static_cast(ut_malloc(asize*2)); - cbuf = static_cast(ut_align(cbuf2, UNIV_PAGE_SIZE)); - slot->page_compression_page = static_cast(cbuf2); - slot->page_buf = static_cast(cbuf); - ut_a(slot->page_buf != NULL); - memset(slot->page_compression_page, 0, asize*2); - } -} - -#ifdef HAVE_LZO -/**********************************************************************//** -Allocate memory for temporal memory used for page compression when -LZO compression method is used */ -UNIV_INTERN -void -os_slot_alloc_lzo_mem( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if(slot->lzo_mem == NULL) { - slot->lzo_mem = static_cast(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); - ut_a(slot->lzo_mem != NULL); - memset(slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); - } -} -#endif - -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. */ -UNIV_INTERN -void -os_slot_alloc_tmp_encryption_buf( -/*=============================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if (slot->tmp_encryption_buf == NULL) { - slot->tmp_encryption_buf = static_cast(ut_malloc(64)); - memset(slot->tmp_encryption_buf, 0, 64); - } -} - - /***********************************************************************//** Try to get number of bytes per sector from file system. @return file block size */ diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index caed087b439..c63dbffcba9 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2554,7 +2554,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size, FALSE); + srv_sort_buf_size); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" @@ -3385,7 +3385,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size, FALSE); + srv_sort_buf_size); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 97746aa088e..d2734ecd6b5 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -786,7 +786,7 @@ row_merge_read( #endif /* UNIV_DEBUG */ success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, - ofs, srv_sort_buf_size, FALSE); + ofs, srv_sort_buf_size); #ifdef POSIX_FADV_DONTNEED /* Each block is read exactly once. Free up the file cache. */ diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 3dd65c540c3..d9fef775d40 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -57,6 +57,7 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "btr0defragment.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "ibuf0ibuf.h" #include "fts0fts.h" #include "fts0types.h" diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 39481a90c00..0bcc876f591 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -985,20 +985,15 @@ static monitor_info_t innodb_counter_info[] = MONITOR_NONE, MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR}, - {"compress_pages_page_encrypted", "compression", - "Number of pages encrypted by page encryption", + {"compress_pages_encrypted", "compression", + "Number of pages encrypted", MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_ENCRYPTED}, + MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_ENCRYPTED}, - {"compress_pages_page_decrypted", "compression", - "Number of pages decrypted by page encryption", + {"compress_pages_decrypted", "compression", + "Number of pages decrypted", MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_DECRYPTED}, - - {"compress_pages_page_encryption_error", "compression", - "Number of page encryption errors ", - MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR}, + MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_DECRYPTED}, /* ========== Counters for Index ========== */ {"module_index", "index", "Index Manager", @@ -2014,14 +2009,11 @@ srv_mon_process_existing_counter( case MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR: value = srv_stats.pages_page_compression_error; break; - case MONITOR_OVLD_PAGES_PAGE_ENCRYPTED: - value = srv_stats.pages_page_encrypted; + case MONITOR_OVLD_PAGES_ENCRYPTED: + value = srv_stats.pages_encrypted; break; - case MONITOR_OVLD_PAGES_PAGE_DECRYPTED: - value = srv_stats.pages_page_decrypted; - break; - case MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR: - value = srv_stats.pages_page_encryption_error; + case MONITOR_OVLD_PAGES_DECRYPTED: + value = srv_stats.pages_decrypted; break; default: diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index ee88c1f9e33..17470855fc4 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -74,9 +74,9 @@ Created 10/8/1995 Heikki Tuuri #include "mysql/plugin.h" #include "mysql/service_thd_wait.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "fil0pagecompress.h" #include "btr0scrub.h" -#include "fil0pageencryption.h" #ifdef WITH_WSREP extern int wsrep_debug; @@ -523,9 +523,6 @@ thread ensures that we flush the log files at least once per second. */ static time_t srv_last_log_flush_time; -/** Default encryption key used for page encryption */ -UNIV_INTERN uint srv_default_page_encryption_key = DEFAULT_ENCRYPTION_KEY; - /** Enable semaphore request instrumentation */ UNIV_INTERN my_bool srv_instrument_semaphores = FALSE; @@ -1601,9 +1598,8 @@ srv_export_innodb_status(void) export_vars.innodb_page_compressed_trim_op_saved = srv_stats.page_compressed_trim_op_saved; export_vars.innodb_pages_page_decompressed = srv_stats.pages_page_decompressed; export_vars.innodb_pages_page_compression_error = srv_stats.pages_page_compression_error; - export_vars.innodb_pages_page_decrypted = srv_stats.pages_page_decrypted; - export_vars.innodb_pages_page_encrypted = srv_stats.pages_page_encrypted; - export_vars.innodb_pages_page_encryption_error = srv_stats.pages_page_encryption_error; + export_vars.innodb_pages_decrypted = srv_stats.pages_decrypted; + export_vars.innodb_pages_encrypted = srv_stats.pages_encrypted; export_vars.innodb_defragment_compression_failures = btr_defragment_compression_failures; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 3822a9abf2d..c349dd7402b 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -3,7 +3,7 @@ Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2015, MariaDB Corporation Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -53,6 +53,7 @@ Created 2/16/1996 Heikki Tuuri #include "os0file.h" #include "os0thread.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "fsp0fsp.h" #include "rem0rec.h" #include "mtr0mtr.h" @@ -1119,7 +1120,7 @@ check_first_page: *sum_of_new_sizes += srv_data_file_sizes[i]; - crypt_data = fil_space_create_crypt_data(); + crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY); } ret = os_file_close(files[i]); diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 09c816aee4e..b8e3350ca76 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -64,7 +64,7 @@ IF(NOT WITH_ARIA_STORAGE_ENGINE) ENDIF() TARGET_LINK_LIBRARIES(aria myisam - mysys mysys_ssl ${LIBCRYPT} ${LIBDL} ${SSL_LIBRARIES}) + mysys mysys_ssl) MYSQL_ADD_EXECUTABLE(aria_ftdump maria_ftdump.c COMPONENT Server) TARGET_LINK_LIBRARIES(aria_ftdump aria) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 4b95725a743..fba0beda802 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -3138,11 +3138,6 @@ int ha_maria::create(const char *name, register TABLE *table_arg, ha_create_info->page_checksum == HA_CHOICE_YES) create_flags|= HA_CREATE_PAGE_CHECKSUM; - mysql_mutex_lock(&LOCK_global_system_variables); - mysql_mutex_unlock(&LOCK_global_system_variables); - if (row_type == BLOCK_RECORD && maria_encrypt_tables) - create_flags|= HA_CREATE_ENCRYPTED; - (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY, (uchar*) thd->query(), thd->query_length()); diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h index 241bc7c2739..693de8a8a56 100644 --- a/storage/maria/ma_check_standalone.h +++ b/storage/maria/ma_check_standalone.h @@ -23,6 +23,16 @@ void _mi_report_crashed(void *file __attribute__((unused)), { } +static unsigned int no_key() +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} + +struct encryption_service_st encryption_handler= +{ + no_key, 0, 0, 0, 0, 0 +}; + /* only those that included myisamchk.h may need and can use the below */ #ifdef _myisamchk_h /* @@ -121,5 +131,6 @@ void _ma_check_print_error(HA_CHECK *param, const char *fmt,...) va_end(args); DBUG_VOID_RETURN; } + #endif diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index b7fcb6b7058..f160499a94e 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -73,8 +73,8 @@ int maria_create(const char *name, enum data_file_type datafile_type, my_bool forced_packed; myf sync_dir= 0; uchar *log_data= NULL; - my_bool encrypted= MY_TEST(flags & HA_CREATE_ENCRYPTED); - my_bool insert_order= MY_TEST(flags & HA_INSERT_ORDER); + my_bool encrypted= maria_encrypt_tables && datafile_type == BLOCK_RECORD; + my_bool insert_order= MY_TEST(flags & HA_PRESERVE_INSERT_ORDER); uint crypt_page_header_space= 0; DBUG_ENTER("maria_create"); DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u", diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index 89defe8cec9..5a187382c42 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -1,11 +1,28 @@ -/* Copyright 2013 Google Inc. All Rights Reserved. */ +/* + Copyright (c) 2013 Google Inc. + Copyright (c) 2014, 2015 MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include -#include "ma_crypt.h" #include "maria_def.h" #include "ma_blockrec.h" #include +#define HARD_CODED_ENCRYPTION_KEY_VERSION 1 +#define HARD_CODED_ENCRYPTION_KEY_ID 1 + #define CRYPT_SCHEME_1 1 #define CRYPT_SCHEME_1_ID_LEN 4 /* 4 bytes for counter-block */ #define CRYPT_SCHEME_1_IV_LEN 16 @@ -14,21 +31,11 @@ struct st_maria_crypt_data { uchar type; + uint keyid; uchar iv_length; uchar iv[1]; // var size }; -static -void -fatal(const char * fmt, ...) -{ - va_list args; - va_start(args,fmt); - vfprintf(stderr, fmt, args); - va_end(args); - abort(); -} - uint ma_crypt_get_data_page_header_space() { @@ -65,6 +72,7 @@ ma_crypt_create(MARIA_SHARE* share) MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0)); bzero(crypt_data, sz); crypt_data->type= CRYPT_SCHEME_1; + crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID; crypt_data->iv_length= iv_length; my_random_bytes(crypt_data->iv, iv_length); share->crypt_data= crypt_data; @@ -115,6 +123,7 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff) MARIA_CRYPT_DATA *crypt_data= (MARIA_CRYPT_DATA*)my_malloc(sz, MYF(0)); crypt_data->type= type; + crypt_data->keyid= HARD_CODED_ENCRYPTION_KEY_ID; crypt_data->iv_length= iv_length; memcpy(crypt_data->iv, buff + 2, iv_length); share->crypt_data= crypt_data; @@ -128,20 +137,21 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff) /* currently only supported type */ if (type != CRYPT_SCHEME_1) { - fatal("Unsupported crypt scheme! type: %d iv_length: %d\n", - type, iv_length); + my_printf_error(HA_ERR_UNSUPPORTED, + "Unsupported crypt scheme! type: %d iv_length: %d\n", + MYF(ME_FATALERROR|ME_NOREFRESH), + type, iv_length); + return 0; } share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE; return buff + 2 + iv_length; } -static void ma_encrypt(MARIA_CRYPT_DATA *crypt_data, - const uchar *src, uchar *dst, uint size, - uint pageno, LSN lsn, uint *key_version); -static void ma_decrypt(MARIA_CRYPT_DATA *crypt_data, - const uchar *src, uchar *dst, uint size, - uint pageno, LSN lsn, uint key_version); +static int ma_encrypt(MARIA_CRYPT_DATA *, const uchar *, uchar *, uint, + uint, LSN, uint *); +static int ma_decrypt(MARIA_CRYPT_DATA *, const uchar *, uchar *, uint, + uint, LSN, uint); static my_bool ma_crypt_pre_read_hook(PAGECACHE_IO_HOOK_ARGS *args) { @@ -183,9 +193,9 @@ static my_bool ma_crypt_data_post_read_hook(int res, /* 1 - copy head */ memcpy(dst, src, head); /* 2 - decrypt page */ - ma_decrypt(share->crypt_data, - src + head, dst + head, size - (head + tail), pageno, lsn, - key_version); + res= ma_decrypt(share->crypt_data, + src + head, dst + head, size - (head + tail), pageno, lsn, + key_version); /* 3 - copy tail */ memcpy(dst + size - tail, src + size - tail, tail); /* 4 clear key version to get correct crc */ @@ -249,10 +259,11 @@ static my_bool ma_crypt_data_pre_write_hook(PAGECACHE_IO_HOOK_ARGS *args) /* 1 - copy head */ memcpy(dst, src, head); - /* 2 - decrypt page */ - ma_encrypt(share->crypt_data, - src + head, dst + head, size - (head + tail), pageno, lsn, - &key_version); + /* 2 - encrypt page */ + if (ma_encrypt(share->crypt_data, + src + head, dst + head, size - (head + tail), pageno, lsn, + &key_version)) + return 1; /* 3 - copy tail */ memcpy(dst + size - tail, src + size - tail, tail); /* 4 - store key version */ @@ -285,7 +296,8 @@ void ma_crypt_set_data_pagecache_callbacks(PAGECACHE_FILE *file, __attribute__((unused))) { /* Only use encryption if we have defined it */ - if (likely(current_aes_dynamic_method != MY_AES_ALGORITHM_NONE)) + if (encryption_key_get_latest_version(HARD_CODED_ENCRYPTION_KEY_ID) != + ENCRYPTION_KEY_VERSION_INVALID) { file->pre_read_hook= ma_crypt_pre_read_hook; file->post_read_hook= ma_crypt_data_post_read_hook; @@ -316,8 +328,8 @@ static my_bool ma_crypt_index_post_read_hook(int res, /* 1 - copy head */ memcpy(dst, src, head); /* 2 - decrypt page */ - ma_decrypt(share->crypt_data, - src + head, dst + head, size, pageno, lsn, key_version); + res= ma_decrypt(share->crypt_data, + src + head, dst + head, size, pageno, lsn, key_version); /* 3 - copy tail */ memcpy(dst + block_size - tail, src + block_size - tail, tail); /* 4 clear key version to get correct crc */ @@ -368,9 +380,10 @@ static my_bool ma_crypt_index_pre_write_hook(PAGECACHE_IO_HOOK_ARGS *args) /* 1 - copy head */ memcpy(dst, src, head); - /* 2 - decrypt page */ - ma_encrypt(share->crypt_data, - src + head, dst + head, size, pageno, lsn, &key_version); + /* 2 - encrypt page */ + if (ma_encrypt(share->crypt_data, + src + head, dst + head, size, pageno, lsn, &key_version)) + return 1; /* 3 - copy tail */ memcpy(dst + block_size - tail, src + block_size - tail, tail); /* 4 - store key version */ @@ -396,7 +409,7 @@ void ma_crypt_set_index_pagecache_callbacks(PAGECACHE_FILE *file, #define COUNTER_LEN MY_AES_BLOCK_SIZE -static void ma_encrypt(MARIA_CRYPT_DATA *crypt_data, +static int ma_encrypt(MARIA_CRYPT_DATA *crypt_data, const uchar *src, uchar *dst, uint size, uint pageno, LSN lsn, uint *key_version) @@ -404,58 +417,60 @@ static void ma_encrypt(MARIA_CRYPT_DATA *crypt_data, int rc; uint32 dstlen; uchar counter[COUNTER_LEN]; - uchar *key= crypt_data->iv; + *key_version= HARD_CODED_ENCRYPTION_KEY_VERSION; // create counter block memcpy(counter + 0, crypt_data->iv + CRYPT_SCHEME_1_IV_LEN, 4); int4store(counter + 4, pageno); int8store(counter + 8, lsn); - rc = my_aes_encrypt_dynamic(src, size, - dst, &dstlen, - key, sizeof(crypt_data->iv), - counter, sizeof(counter), - 1); + rc = encryption_encrypt(src, size, dst, &dstlen, + crypt_data->iv, CRYPT_SCHEME_1_IV_LEN, + counter, sizeof(counter), 1, + crypt_data->keyid, *key_version); - DBUG_ASSERT(rc == AES_OK); + DBUG_ASSERT(rc == MY_AES_OK); DBUG_ASSERT(dstlen == size); - if (! (rc == AES_OK && dstlen == size)) + if (! (rc == MY_AES_OK && dstlen == size)) { - fatal("failed to encrypt! rc: %d, dstlen: %d size: %d\n", - rc, dstlen, (int)size); + my_printf_error(HA_ERR_GENERIC, + "failed to encrypt! rc: %d, dstlen: %u size: %u\n", + MYF(ME_FATALERROR|ME_NOREFRESH), + rc, dstlen, size); + return 1; } - *key_version= 1; + return 0; } -static void ma_decrypt(MARIA_CRYPT_DATA *crypt_data, - const uchar *src, uchar *dst, uint size, - uint pageno, LSN lsn, - uint key_version) +static int ma_decrypt(MARIA_CRYPT_DATA *crypt_data, + const uchar *src, uchar *dst, uint size, + uint pageno, LSN lsn, + uint key_version) { int rc; uint32 dstlen; uchar counter[COUNTER_LEN]; - uchar *key= crypt_data->iv; // create counter block memcpy(counter + 0, crypt_data->iv + CRYPT_SCHEME_1_IV_LEN, 4); int4store(counter + 4, pageno); int8store(counter + 8, lsn); - rc = my_aes_decrypt_dynamic(src, size, - dst, &dstlen, - key, sizeof(crypt_data->iv), - counter, sizeof(counter), - 1); + rc =encryption_decrypt(src, size, dst, &dstlen, + crypt_data->iv, CRYPT_SCHEME_1_IV_LEN, + counter, sizeof(counter), 1, crypt_data->keyid, + key_version); - DBUG_ASSERT(rc == AES_OK); + DBUG_ASSERT(rc == MY_AES_OK); DBUG_ASSERT(dstlen == size); - if (! (rc == AES_OK && dstlen == size)) + if (! (rc == MY_AES_OK && dstlen == size)) { - fatal("failed to decrypt! rc: %d, dstlen: %d size: %d\n", - rc, dstlen, (int)size); + my_printf_error(HA_ERR_GENERIC, + "failed to encrypt! rc: %d, dstlen: %u size: %u\n", + MYF(ME_FATALERROR|ME_NOREFRESH), + rc, dstlen, size); + return 1; } - - (void)key_version; + return 0; } diff --git a/storage/maria/ma_crypt.h b/storage/maria/ma_crypt.h index 76752e19449..309a8300eb8 100644 --- a/storage/maria/ma_crypt.h +++ b/storage/maria/ma_crypt.h @@ -1,7 +1,22 @@ -/* Copyright 2013 Google Inc. All Rights Reserved. */ +/* + Copyright (c) 2013 Google Inc. + Copyright (c) 2014, 2015 MariaDB Corporation -#ifndef _ma_crypt_h -#define _ma_crypt_h + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef STORAGE_MARIA_MA_CRYPT_INCLUDED +#define STORAGE_MARIA_MA_CRYPT_INCLUDED #include diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 271a0ee8d53..42861e92ed4 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -837,7 +837,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) if (MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED)) { - disk_pos= ma_crypt_read(share, disk_pos); + if (!(disk_pos= ma_crypt_read(share, disk_pos))) + goto err; } if ((share->data_file_type == BLOCK_RECORD || diff --git a/storage/tokudb/mysql-test/tokudb/r/auto_increment.result b/storage/tokudb/mysql-test/tokudb/r/auto_increment.result index 140c943081f..ce576c337d3 100644 --- a/storage/tokudb/mysql-test/tokudb/r/auto_increment.result +++ b/storage/tokudb/mysql-test/tokudb/r/auto_increment.result @@ -376,7 +376,7 @@ t1 CREATE TABLE `t1` ( `t1_id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`t1_id`), KEY `t1_name` (`t1_name`) -) ENGINE=TokuDB AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 DROP TABLE `t1`; create table t1(a int not null auto_increment primary key); create table t2(a int not null auto_increment primary key, t1a int); diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result index f9df80c8fd6..b32ea1498c1 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result @@ -7,19 +7,19 @@ Table Create Table t CREATE TABLE `t` ( `a` char(100) NOT NULL DEFAULT '', `b` binary(200) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a CHAR(101) NOT NULL DEFAULT 'a'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` char(101) NOT NULL DEFAULT 'a', `b` binary(200) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b BINARY(201) NOT NULL DEFAULT 'b'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` char(101) NOT NULL DEFAULT 'a', `b` binary(201) NOT NULL DEFAULT 'b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result index 2d450f4991a..558d153711c 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result @@ -7,31 +7,31 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` tinyint(4) DEFAULT '100' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a SMALLINT DEFAULT 200; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` smallint(6) DEFAULT '200' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a MEDIUMINT DEFAULT 300; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` mediumint(9) DEFAULT '300' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a INT DEFAULT 400; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT '400' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a BIGINT DEFAULT 500; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` bigint(20) DEFAULT '500' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; CREATE TABLE t (a TINYINT NOT NULL DEFAULT 1); ALTER TABLE t CHANGE COLUMN a a TINYINT NOT NULL DEFAULT 100; @@ -39,31 +39,31 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` tinyint(4) NOT NULL DEFAULT '100' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a SMALLINT NOT NULL DEFAULT 200; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` smallint(6) NOT NULL DEFAULT '200' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a MEDIUMINT NOT NULL DEFAULT 300; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` mediumint(9) NOT NULL DEFAULT '300' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a INT NOT NULL DEFAULT 400; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` int(11) NOT NULL DEFAULT '400' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a BIGINT NOT NULL DEFAULT 500; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` bigint(20) NOT NULL DEFAULT '500' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; CREATE TABLE t (a TINYINT UNSIGNED DEFAULT 1); ALTER TABLE t CHANGE COLUMN a a TINYINT UNSIGNED DEFAULT 100; @@ -71,31 +71,31 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` tinyint(3) unsigned DEFAULT '100' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a SMALLINT UNSIGNED DEFAULT 200; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` smallint(5) unsigned DEFAULT '200' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a MEDIUMINT UNSIGNED DEFAULT 300; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` mediumint(8) unsigned DEFAULT '300' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a INT UNSIGNED DEFAULT 400; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` int(10) unsigned DEFAULT '400' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a BIGINT UNSIGNED DEFAULT 500; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` bigint(20) unsigned DEFAULT '500' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; CREATE TABLE t (a TINYINT UNSIGNED NOT NULL DEFAULT 1); ALTER TABLE t CHANGE COLUMN a a TINYINT UNSIGNED NOT NULL DEFAULT 100; @@ -103,29 +103,29 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` tinyint(3) unsigned NOT NULL DEFAULT '100' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a SMALLINT UNSIGNED NOT NULL DEFAULT 200; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` smallint(5) unsigned NOT NULL DEFAULT '200' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a MEDIUMINT UNSIGNED NOT NULL DEFAULT 300; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` mediumint(8) unsigned NOT NULL DEFAULT '300' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a INT UNSIGNED NOT NULL DEFAULT 400; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` int(10) unsigned NOT NULL DEFAULT '400' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a BIGINT UNSIGNED NOT NULL DEFAULT 500; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` bigint(20) unsigned NOT NULL DEFAULT '500' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result index d18c38721e6..635afaf0895 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result @@ -5,7 +5,7 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varbinary(1) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARBINARY(2); ALTER TABLE t CHANGE COLUMN a a VARBINARY(2); ALTER TABLE t CHANGE COLUMN a a VARBINARY(3); diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result index 344c78c53be..874233af69c 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result @@ -6,21 +6,21 @@ Table Create Table t CREATE TABLE `t` ( `a` varbinary(100) NOT NULL DEFAULT '', `b` varbinary(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARBINARY(255) NOT NULL DEFAULT 'a'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varbinary(255) NOT NULL DEFAULT 'a', `b` varbinary(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARBINARY(256) NOT NULL DEFAULT 'b'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varbinary(256) NOT NULL DEFAULT 'b', `b` varbinary(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b VARBINARY(255) NOT NULL DEFAULT 'c'; ERROR 42000: Table 't' uses an extension that doesn't exist in this XYZ version ALTER TABLE t CHANGE COLUMN b b VARBINARY(1024) NOT NULL DEFAULT 'd'; @@ -29,7 +29,7 @@ Table Create Table t CREATE TABLE `t` ( `a` varbinary(256) NOT NULL DEFAULT 'b', `b` varbinary(1024) NOT NULL DEFAULT 'd' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b VARBINARY(256) NOT NULL DEFAULT 'e'; ERROR 42000: Table 't' uses an extension that doesn't exist in this XYZ version DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result index d1577ee0d84..3da19a3fd62 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result @@ -12,14 +12,14 @@ Table Create Table t CREATE TABLE `t` ( `a` varbinary(101) DEFAULT NULL, `b` varbinary(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARBINARY(200); SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varbinary(200) DEFAULT NULL, `b` varbinary(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SELECT * FROM t; a b hi there @@ -38,7 +38,7 @@ t CREATE TABLE `t` ( `i` int(11) DEFAULT NULL, `a` varbinary(101) DEFAULT NULL, `b` varbinary(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARBINARY(200); SHOW CREATE TABLE t; Table Create Table @@ -46,7 +46,7 @@ t CREATE TABLE `t` ( `i` int(11) DEFAULT NULL, `a` varbinary(200) DEFAULT NULL, `b` varbinary(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SELECT * FROM t; i a b 1 hi there diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result index 5018e2db278..2e7da5ed5ef 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result @@ -5,7 +5,7 @@ SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varchar(1) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 INSERT INTO t VALUES (null); ALTER TABLE t CHANGE COLUMN a a VARCHAR(2); ALTER TABLE t CHANGE COLUMN a a VARCHAR(2); diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result index b04e5d7bc36..c9ea9737e5f 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result @@ -6,21 +6,21 @@ Table Create Table t CREATE TABLE `t` ( `a` varchar(100) NOT NULL DEFAULT '', `b` varchar(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARCHAR(255) NOT NULL DEFAULT 'a'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varchar(255) NOT NULL DEFAULT 'a', `b` varchar(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARCHAR(256) NOT NULL DEFAULT 'b'; SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varchar(256) NOT NULL DEFAULT 'b', `b` varchar(256) NOT NULL DEFAULT '' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b VARCHAR(255) NOT NULL DEFAULT 'c'; ERROR 42000: Table 't' uses an extension that doesn't exist in this XYZ version ALTER TABLE t CHANGE COLUMN b b VARCHAR(1024) NOT NULL DEFAULT 'd'; @@ -29,7 +29,7 @@ Table Create Table t CREATE TABLE `t` ( `a` varchar(256) NOT NULL DEFAULT 'b', `b` varchar(1024) NOT NULL DEFAULT 'd' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b VARCHAR(256) NOT NULL DEFAULT 'e'; ERROR 42000: Table 't' uses an extension that doesn't exist in this XYZ version DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result index 30bdc54acbf..d40f4abdd4a 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result @@ -8,7 +8,7 @@ t CREATE TABLE `t` ( `a` varchar(32) DEFAULT NULL, `b` varchar(32) DEFAULT NULL, KEY `a` (`a`(2)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARCHAR(100); ERROR 42000: Table 't' uses an extension that doesn't exist in this XYZ version ALTER TABLE t CHANGE COLUMN a a VARCHAR(256); diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result index dfe9d12b047..6cbf0f9b5b7 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result @@ -8,7 +8,7 @@ t CREATE TABLE `t` ( `a` varchar(32) DEFAULT NULL, `b` varchar(32) DEFAULT NULL, KEY `a` (`a`(2)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN b b VARCHAR(100); ALTER TABLE t CHANGE COLUMN b b VARCHAR(256); DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result index 2d91d590dd4..2d56f6b7319 100644 --- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result +++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result @@ -12,14 +12,14 @@ Table Create Table t CREATE TABLE `t` ( `a` varchar(101) DEFAULT NULL, `b` varchar(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARCHAR(200); SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `a` varchar(200) DEFAULT NULL, `b` varchar(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SELECT * FROM t; a b hi there @@ -38,7 +38,7 @@ t CREATE TABLE `t` ( `i` int(11) DEFAULT NULL, `a` varchar(101) DEFAULT NULL, `b` varchar(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE t CHANGE COLUMN a a VARCHAR(200); SHOW CREATE TABLE t; Table Create Table @@ -46,7 +46,7 @@ t CREATE TABLE `t` ( `i` int(11) DEFAULT NULL, `a` varchar(200) DEFAULT NULL, `b` varchar(100) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SELECT * FROM t; i a b 1 hi there diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result index 4e23ce34a0c..1e0935543dc 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result @@ -1009,14 +1009,14 @@ s CREATE TABLE `s` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL NULL NULL NULL NULL 1000 @@ -1030,7 +1030,7 @@ s CREATE TABLE `s` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1038,7 +1038,7 @@ t CREATE TABLE `t` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b b 5 NULL 1000 Using where; Using index diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result index b124834f7c8..9337718ce35 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result @@ -1009,14 +1009,14 @@ s CREATE TABLE `s` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL NULL NULL NULL NULL 1000 @@ -1030,7 +1030,7 @@ s CREATE TABLE `s` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1038,7 +1038,7 @@ t CREATE TABLE `t` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where @@ -1057,7 +1057,7 @@ s CREATE TABLE `s` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1066,7 +1066,7 @@ t CREATE TABLE `t` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2 b_2 5 NULL 1000 Using where; Using index @@ -1080,7 +1080,7 @@ s CREATE TABLE `s` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1088,7 +1088,7 @@ t CREATE TABLE `t` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b_2 b_2 5 NULL 1000 Using where; Using index @@ -1107,7 +1107,7 @@ s CREATE TABLE `s` ( `c` int(11) DEFAULT NULL, KEY `b_2` (`b`) `clustering`=yes, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1116,7 +1116,7 @@ t CREATE TABLE `t` ( `c` int(11) DEFAULT NULL, KEY `b_2` (`b`) `clustering`=yes, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b_2,b b_2 5 NULL 1000 Using where; Using index diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result index cfb4ec696ce..710509b2acf 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result @@ -1009,14 +1009,14 @@ s CREATE TABLE `s` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL NULL NULL NULL NULL 1000 @@ -1030,7 +1030,7 @@ s CREATE TABLE `s` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1038,7 +1038,7 @@ t CREATE TABLE `t` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where @@ -1053,7 +1053,7 @@ s CREATE TABLE `s` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`,`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1062,7 +1062,7 @@ t CREATE TABLE `t` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`,`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2 b_2 10 NULL 1000 Using where; Using index @@ -1082,7 +1082,7 @@ s CREATE TABLE `s` ( KEY `b` (`b`), KEY `b_2` (`b`,`a`), KEY `b_3` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1092,7 +1092,7 @@ t CREATE TABLE `t` ( KEY `b` (`b`), KEY `b_2` (`b`,`a`), KEY `b_3` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2,b_3 b_2 10 NULL 1000 Using where; Using index @@ -1107,7 +1107,7 @@ s CREATE TABLE `s` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_3` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1116,7 +1116,7 @@ t CREATE TABLE `t` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_3` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_3 b_3 5 NULL 1000 Using where; Using index diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result index a36df1f251e..660d63c54c8 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result @@ -1012,21 +1012,21 @@ s CREATE TABLE `s` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table u; Table Create Table u CREATE TABLE `u` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t,u where s.b = t.b and s.c = t.c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL NULL NULL NULL NULL 1000 @@ -1042,7 +1042,7 @@ s CREATE TABLE `s` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1050,7 +1050,7 @@ t CREATE TABLE `t` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table u; Table Create Table u CREATE TABLE `u` ( @@ -1058,7 +1058,7 @@ u CREATE TABLE `u` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `c` (`c`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t,u where s.b = t.b and s.c = u.c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where @@ -1081,7 +1081,7 @@ s CREATE TABLE `s` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table t; Table Create Table t CREATE TABLE `t` ( @@ -1090,7 +1090,7 @@ t CREATE TABLE `t` ( `c` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `b_2` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table u; Table Create Table u CREATE TABLE `u` ( @@ -1099,7 +1099,7 @@ u CREATE TABLE `u` ( `c` int(11) DEFAULT NULL, KEY `c` (`c`), KEY `c_2` (`c`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select straight_join * from s,t,u where s.b = t.b and s.c = u.c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b,b_2 NULL NULL NULL 1000 Using where diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result b/storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result index 5ffa89eaf6c..914c3edc6ac 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result @@ -11,7 +11,7 @@ t1 CREATE TABLE `t1` ( `d` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 create index foo on t1(c,d) clustering=yes; show create table t1; Table Create Table @@ -23,7 +23,7 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`a`), KEY `b` (`b`) `clustering`=yes, KEY `foo` (`c`,`d`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 drop primary key; alter table t1 add primary key (a,b,c,d); alter table t1 add key bar(d,c,b,a) clustering=yes; @@ -38,7 +38,7 @@ t1 CREATE TABLE `t1` ( KEY `b` (`b`) `clustering`=yes, KEY `foo` (`c`,`d`) `clustering`=yes, KEY `bar` (`d`,`c`,`b`,`a`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 value (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4),(32,54,12,56); explain select * from t1; id select_type table type possible_keys key key_len ref rows Extra diff --git a/storage/tokudb/mysql-test/tokudb/r/ctype_collate.result b/storage/tokudb/mysql-test/tokudb/r/ctype_collate.result index e6de51b896d..6254005d2bb 100644 --- a/storage/tokudb/mysql-test/tokudb/r/ctype_collate.result +++ b/storage/tokudb/mysql-test/tokudb/r/ctype_collate.result @@ -486,7 +486,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `latin1_f` char(32) NOT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SHOW FIELDS FROM t1; Field Type Null Key Default Extra latin1_f char(32) NO NULL @@ -496,7 +496,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `latin1_f` char(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SHOW FIELDS FROM t1; Field Type Null Key Default Extra latin1_f char(32) YES NULL @@ -505,7 +505,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `latin1_f` char(32) COLLATE latin1_bin DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin SHOW FIELDS FROM t1; Field Type Null Key Default Extra latin1_f char(32) YES NULL diff --git a/storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result b/storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result index 0c450b38fda..3efeb757b61 100644 --- a/storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result +++ b/storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result @@ -94,7 +94,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `name` varchar(10) DEFAULT NULL, `level` smallint(5) unsigned DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=cp1250 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=cp1250 insert into t1 values ('string',1); select concat(name,space(level)), concat(name, repeat(' ',level)) from t1; concat(name,space(level)) concat(name, repeat(' ',level)) @@ -196,7 +196,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `name` varchar(10) COLLATE cp1250_czech_cs DEFAULT NULL, `level` smallint(5) unsigned DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs insert into t1 values ('string',1); select concat(name,space(level)), concat(name, repeat(' ',level)) from t1; concat(name,space(level)) concat(name, repeat(' ',level)) diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-10.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-10.result index b0eedf1e33e..319048cfd8b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-10.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-10.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-11.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-11.result index c7efe887e33..a89ba26a461 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-11.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-11.result @@ -6,7 +6,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1); begin; insert into foo values (2); diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-12.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-12.result index e061dd7252a..b307f487f03 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-12.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-12.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-13.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-13.result index 2073e3e26ce..2f87ddb26cc 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-13.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-13.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; select * from foo; a diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-14.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-14.result index 8fb95595c85..eecb674346f 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-14.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-14.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; select * from foo; a diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-15.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-15.result index 65732a84585..0b7d96dd7b5 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-15.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-15.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; select * from foo; a diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-16.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-16.result index 0379dc05d5e..7ee801d88b2 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-16.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-16.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; select * from foo; a diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-17.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-17.result index c0191bedb47..fe3322b9fb7 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-17.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-17.result @@ -8,7 +8,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session tokudb_load_save_space=0; set session transaction isolation level repeatable read; begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-18.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-18.result index c36a872fd30..1edda2650e2 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-18.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-18.result @@ -8,7 +8,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session tokudb_load_save_space=1; set session transaction isolation level repeatable read; begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-21.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-21.result index 88e6efd2b02..bee7c8b4549 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-21.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-21.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-22.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-22.result index 7790a3ff5ff..5d986701785 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-22.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-22.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-23.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-23.result index 1d2bcc175c7..9ea3c631d17 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-23.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-23.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-25.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-25.result index 37e19f0cff5..427d1ca5c3f 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-25.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-25.result @@ -10,14 +10,14 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table bar; Table Create Table bar CREATE TABLE `bar` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; # should be empty diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-3.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-3.result index 878bed00102..684dd147b07 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-3.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-3.result @@ -10,7 +10,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,1); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-33.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-33.result index 7a520ffb0e1..38acca99831 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-33.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-33.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-34.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-34.result index d725bd33c95..e1795bbc832 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-34.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-34.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-35.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-35.result index 4daac248bd8..86fb9670fce 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-35.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-35.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-36.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-36.result index ba4a455e529..d982ff3249d 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-36.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-36.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-37.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-37.result index 5209adeeac6..3e1ad76dd3d 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-37.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-37.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-38.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-38.result index 936a50b1709..5ee3c72e91e 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-38.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-38.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 create table foo_isam (a int, b int, c int) engine=MyISAM; insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500),(6,60,600),(7,70,700),(8,80,800),(9,90,900); begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-39.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-39.result index cd9baa23c09..905d5c2292a 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-39.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-39.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1),(2),(3); set session transaction isolation level repeatable read; begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-4.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-4.result index 499eca4053d..ce8aa725f5b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-4.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-4.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 #should read (1,1) select * from foo; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-40.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-40.result index da77da35ce3..1330fe41c50 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-40.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-40.result @@ -7,7 +7,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1),(2),(3); set session transaction isolation level repeatable read; begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-5.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-5.result index 3d58de843f0..47204dcc7e1 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-5.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-5.result @@ -9,7 +9,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,1); set session transaction isolation level repeatable read; begin; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-6.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-6.result index e388c2dc5fd..a0c8185b1ab 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-6.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-6.result @@ -10,7 +10,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (100,100); begin; insert into foo values (1,100); diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-7.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-7.result index 61f115b9f64..ba78f786c31 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-7.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-7.result @@ -9,7 +9,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,100); select * from foo; a b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-8.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-8.result index 0f1584692da..4e310d2d001 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-8.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-8.result @@ -11,7 +11,7 @@ foo CREATE TABLE `foo` ( `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500); create table foo_isam (a int, b int, c int); # should use key b diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-9.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-9.result index b1de77d61b2..b3b45d731f2 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-9.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-9.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` varchar(100) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 set session transaction isolation level repeatable read; begin; select * from foo; diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result index aa199dd04a9..c6bea70265b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result +++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result @@ -6,7 +6,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values (1),(2),(3); begin; insert into foo values (4); diff --git a/storage/tokudb/mysql-test/tokudb/r/type_binary.result b/storage/tokudb/mysql-test/tokudb/r/type_binary.result index c2f1ded6d92..d3a4582404e 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_binary.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_binary.result @@ -25,7 +25,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `s1` varbinary(20) DEFAULT NULL, `s2` varbinary(20) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (0x41,0x4100),(0x41,0x4120),(0x4100,0x4120); select hex(s1), hex(s2) from t1; hex(s1) hex(s2) diff --git a/storage/tokudb/mysql-test/tokudb/r/type_bit.result b/storage/tokudb/mysql-test/tokudb/r/type_bit.result index b9813451d94..1d5432e2dd6 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_bit.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_bit.result @@ -43,7 +43,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bit(1) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a bit(64)); insert into t1 values @@ -498,7 +498,7 @@ show create table t2; Table Create Table t2 CREATE TABLE `t2` ( `a` bit(7) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1, t2; create table t1 (id1 int(11), b1 bit(1)); create table t2 (id2 int(11), b2 bit(1)); @@ -701,6 +701,6 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` bit(8) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; End of 5.1 tests diff --git a/storage/tokudb/mysql-test/tokudb/r/type_blob.result b/storage/tokudb/mysql-test/tokudb/r/type_blob.result index ed9b554e5cb..21d9f57770e 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_blob.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_blob.result @@ -26,12 +26,12 @@ Table Create Table t3 CREATE TABLE `t3` ( `a` mediumtext, `b` mediumblob -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create TABLE t4; Table Create Table t4 CREATE TABLE `t4` ( `c` mediumtext CHARACTER SET utf8 NOT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1,t2,t3,t4; CREATE TABLE t1 (a char(257) default "hello"); ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead @@ -365,7 +365,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` text, KEY `a` (`a`(2100)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1 ( t1_id bigint(21) NOT NULL auto_increment, @@ -672,7 +672,7 @@ t1 CREATE TABLE `t1` ( `e` int(11) DEFAULT NULL, PRIMARY KEY (`a`,`b`,`c`(255),`d`), KEY `a` (`a`,`b`,`d`,`e`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; CREATE table t1 (a blob); insert into t1 values ('b'),('a\0'),('a'),('a '),('aa'),(NULL); @@ -751,7 +751,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` text -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (default); select * from t1; a diff --git a/storage/tokudb/mysql-test/tokudb/r/type_datetime.result b/storage/tokudb/mysql-test/tokudb/r/type_datetime.result index 82f5ebe9600..77364b90f9d 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_datetime.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_datetime.result @@ -205,7 +205,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `da` date DEFAULT '1962-03-03', `dt` datetime DEFAULT '1962-03-03 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (); insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38'); Warnings: @@ -573,7 +573,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `da` date DEFAULT '1962-03-03', `dt` datetime DEFAULT '1962-03-03 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (); insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38'); Warnings: diff --git a/storage/tokudb/mysql-test/tokudb/r/type_decimal.result b/storage/tokudb/mysql-test/tokudb/r/type_decimal.result index a432927eda2..5d271bc73fa 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_decimal.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_decimal.result @@ -712,14 +712,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `d` decimal(5,0) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (d decimal); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `d` decimal(10,0) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (d decimal(66,0)); ERROR 42000: Too big precision 66 specified for 'd'. Maximum is 65. @@ -880,7 +880,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` decimal(10,0) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select round(a,b) as c from t1 order by c; c 1000 diff --git a/storage/tokudb/mysql-test/tokudb/r/type_enum.result b/storage/tokudb/mysql-test/tokudb/r/type_enum.result index cd96b7520b2..85ca32f1697 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_enum.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_enum.result @@ -1628,14 +1628,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` enum('','a','b') NOT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a enum (' ','a','b ') not null default 'b '); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` enum('','a','b') NOT NULL DEFAULT 'b' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a enum ('0','1')); insert into t1 set a='foobar'; @@ -1660,7 +1660,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` enum('ä','1','2') NOT NULL DEFAULT 'ä' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; set names latin1; CREATE TABLE t1 ( @@ -1672,7 +1672,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT '1', `b` enum('value','öäü_value','ÊÃÕ') NOT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra a int(11) YES 1 @@ -1701,7 +1701,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` enum('ä','ö','ü') CHARACTER SET utf8 DEFAULT 'ü' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values ('ä'), ('ö'), ('ü'); select a from t1 order by a; a @@ -1719,7 +1719,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` enum('ä','ö','ü') DEFAULT 'ü' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select a from t1 order by a; a ä @@ -1753,28 +1753,28 @@ Table Create Table t1 CREATE TABLE `t1` ( `f1` int(11) DEFAULT NULL, `f2` enum('ÿÿ') DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1(russian enum('E','F','EÿF','FÿE') NOT NULL DEFAULT'E'); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `russian` enum('E','F','EÿF','FÿE') NOT NULL DEFAULT 'E' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1(denormal enum('E','F','E,F','F,E') NOT NULL DEFAULT'E'); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `denormal` enum('E','F','E,F','F,E') NOT NULL DEFAULT 'E' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1(russian_deviant enum('E','F','EÿF','F,E') NOT NULL DEFAULT'E'); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `russian_deviant` enum('E','F','EÿF','F,E') NOT NULL DEFAULT 'E' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1 ( id INT AUTO_INCREMENT PRIMARY KEY, diff --git a/storage/tokudb/mysql-test/tokudb/r/type_float.result b/storage/tokudb/mysql-test/tokudb/r/type_float.result index cdb3db55f75..e9abecc1dee 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_float.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_float.result @@ -96,7 +96,7 @@ t2 CREATE TABLE `t2` ( `col2` double(22,5) DEFAULT NULL, `col3` double DEFAULT NULL, `col4` double DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1,t2; create table t1 (a float); insert into t1 values (1); @@ -239,7 +239,7 @@ show create table t3; Table Create Table t3 CREATE TABLE `t3` ( `d` double DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1, t2, t3; create table t1 select 105213674794682365.00 + 0.0 x; show warnings; diff --git a/storage/tokudb/mysql-test/tokudb/r/type_nchar.result b/storage/tokudb/mysql-test/tokudb/r/type_nchar.result index 0e261807c5c..0dc39a49a7e 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_nchar.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_nchar.result @@ -5,47 +5,47 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c national char(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c national varchar(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` varchar(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c nvarchar(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` varchar(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c nchar varchar(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` varchar(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c national character varying(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` varchar(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (c nchar varying(10)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` varchar(10) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result index 3f76f54609f..6ab94a1b10b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result @@ -60,7 +60,7 @@ t1 CREATE TABLE `t1` ( `if(0, NULL, 1.2)` decimal(2,1) DEFAULT NULL, `if(1, 0.22e1, 1.1)` double NOT NULL DEFAULT '0', `if(1E0, 1.1, 1.2)` decimal(2,1) NOT NULL DEFAULT '0.0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 select nullif(1.1, 1.1), nullif(1.1, 1.2), nullif(1.1, 0.11e1), nullif(1.0, 1), nullif(1, 1.0), nullif(1, 1.1); select * from t1; @@ -75,7 +75,7 @@ t1 CREATE TABLE `t1` ( `nullif(1.0, 1)` decimal(2,1) DEFAULT NULL, `nullif(1, 1.0)` int(1) DEFAULT NULL, `nullif(1, 1.1)` int(1) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a decimal(4,2)); insert into t1 value (10000), (1.1e10), ("11111"), (100000.1); @@ -179,7 +179,7 @@ t1 CREATE TABLE `t1` ( `truncate(-5678.123451,-3)` decimal(4,0) NOT NULL DEFAULT '0', `abs(-1.1)` decimal(3,1) NOT NULL DEFAULT '0.0', `-(-1.1)` decimal(2,1) NOT NULL DEFAULT '0.0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; set session sql_mode='traditional'; select 1e10/0e0; @@ -773,7 +773,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `0.5` decimal(2,1) NOT NULL DEFAULT '0.0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; select round(1.5),round(2.5); round(1.5) round(2.5) @@ -936,14 +936,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `sl` decimal(5,5) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (sl decimal(65, 30)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `sl` decimal(65,30) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 ( f1 decimal unsigned not null default 17.49, @@ -976,7 +976,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `f0` decimal(30,30) unsigned zerofill NOT NULL DEFAULT '0.000000000000000000000000000000', `f1` decimal(10,0) unsigned zerofill NOT NULL DEFAULT '0000000000' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; drop procedure if exists wg2; create procedure wg2() @@ -1026,7 +1026,7 @@ t1 CREATE TABLE `t1` ( `my_double` double DEFAULT NULL, `my_varchar` varchar(50) DEFAULT NULL, `my_decimal` decimal(65,30) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 INSERT INTO t1 SET my_float = 1.175494345e-32, my_double = 1.175494345e-32, my_varchar = '1.175494345e-32'; @@ -1540,7 +1540,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `5.05 / 0.014` decimal(10,6) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from t1; 5.05 / 0.014 360.714286 diff --git a/storage/tokudb/mysql-test/tokudb/r/type_set.result b/storage/tokudb/mysql-test/tokudb/r/type_set.result index f155cb53809..9d8574ce5ab 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_set.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_set.result @@ -5,14 +5,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` set('','a','b') NOT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a set (' ','a','b ') not null default 'b '); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` set('','a','b') NOT NULL DEFAULT 'b' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1 ( user varchar(64) NOT NULL default '', path varchar(255) NOT NULL default '', privilege set('select','RESERVED30','RESERVED29','RESERVED28','RESERVED27','RESERVED26', 'RESERVED25','RESERVED24','data.delete','RESERVED22','RESERVED21', 'RESERVED20','data.insert.none','data.insert.approve', 'data.insert.delete','data.insert.move','data.insert.propose', 'data.insert.reject','RESERVED13','RESERVED12','RESERVED11','RESERVED10', 'RESERVED09','data.update','RESERVED07','RESERVED06','RESERVED05', 'RESERVED04','metadata.delete','metadata.put','RESERVED01','RESERVED00') NOT NULL default '', KEY user (user) ) ENGINE=MyISAM CHARSET=utf8; DROP TABLE t1; @@ -22,7 +22,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `s` set('a','A') CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values ('a'),('a,A'),('A,a'),('A'); select s from t1 order by s; s @@ -84,5 +84,5 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `f1` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1') DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb/r/type_timestamp.result b/storage/tokudb/mysql-test/tokudb/r/type_timestamp.result index 6d0f6946ed9..9154c84d5a7 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_timestamp.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_timestamp.result @@ -195,7 +195,7 @@ t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT '2003-01-01 00:00:00', `t2` datetime DEFAULT NULL, `t3` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO 2003-01-01 00:00:00 @@ -219,7 +219,7 @@ t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `t2` datetime DEFAULT NULL, `t3` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO CURRENT_TIMESTAMP @@ -245,7 +245,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT '2003-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP, `t2` datetime DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO 2003-01-01 00:00:00 on update CURRENT_TIMESTAMP @@ -270,7 +270,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `t2` datetime DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP @@ -296,7 +296,7 @@ t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `t2` datetime DEFAULT NULL, `t3` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP @@ -322,7 +322,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `t1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `t2` datetime DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra t1 timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP @@ -377,7 +377,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` timestamp NULL DEFAULT NULL, `b` timestamp NULL DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (NULL, NULL); SET TIMESTAMP=1000000017; insert into t1 values (); @@ -392,7 +392,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `b` timestamp NULL DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (NULL, NULL); SET TIMESTAMP=1000000018; insert into t1 values (); @@ -407,7 +407,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` timestamp NULL DEFAULT NULL, `b` timestamp NULL DEFAULT '2003-01-01 00:00:00' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 values (NULL, NULL); insert into t1 values (DEFAULT, DEFAULT); select * from t1; diff --git a/storage/tokudb/mysql-test/tokudb/r/type_varchar.result b/storage/tokudb/mysql-test/tokudb/r/type_varchar.result index d12fbbf99bd..ad95b9a9908 100644 --- a/storage/tokudb/mysql-test/tokudb/r/type_varchar.result +++ b/storage/tokudb/mysql-test/tokudb/r/type_varchar.result @@ -9,7 +9,7 @@ t1 CREATE TABLE `t1` ( `c` char(3) DEFAULT NULL, `e` enum('abc','def','ghi') DEFAULT NULL, `t` text -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table vchar; Table Create Table vchar CREATE TABLE `vchar` ( @@ -400,21 +400,21 @@ Table Create Table t1 CREATE TABLE `t1` ( `f1` varchar(65500) DEFAULT NULL, KEY `index1` (`f1`(10)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 modify f1 varchar(255); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `f1` varchar(255) DEFAULT NULL, KEY `index1` (`f1`(10)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 modify f1 tinytext; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `f1` tinytext, KEY `index1` (`f1`(10)) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; DROP TABLE IF EXISTS t1; CREATE TABLE t1(f1 VARCHAR(100) DEFAULT 'test'); diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result index d4aac756ffa..38338f7f823 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result @@ -9,7 +9,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (a) PARTITIONS 2 */ ALTER TABLE foo ADD KEY(b); @@ -20,7 +20,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`), KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (a) PARTITIONS 2 */ DROP TABLE foo; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result index 0058d4c5664..2c1390ad2a4 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result @@ -7,33 +7,33 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo ALTER COLUMN a SET DEFAULT 100; SHOW CREATE TABLE foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '100', `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo ALTER COLUMN a DROP DEFAULT; SHOW CREATE TABLE foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo ALTER COLUMN b SET DEFAULT 42; SHOW CREATE TABLE foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT '42' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo ALTER COLUMN b DROP DEFAULT; SHOW CREATE TABLE foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL, `b` int(11) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE foo; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result index e70818ed629..7f58c9ebc97 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result @@ -15,7 +15,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL AUTO_INCREMENT, `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 insert into foo (b) values (11),(21),(32); select * from foo; a b @@ -31,7 +31,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL AUTO_INCREMENT, `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 alter table foo auto_increment=10; insert into foo (b) values (11),(21),(32); select * from foo; @@ -51,7 +51,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL AUTO_INCREMENT, `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB AUTO_INCREMENT=1006 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB AUTO_INCREMENT=1006 DEFAULT CHARSET=latin1 alter table foo auto_increment=100000, add column c int; ERROR 42000: Table 'foo' uses an extension that doesn't exist in this XYZ version alter table foo auto_increment=100000, drop column b; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result index 85c7914edc3..41c5a6c72d4 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result @@ -6,14 +6,14 @@ Table Create Table foo CREATE TABLE `foo` ( `id` int(11) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 CREATE TABLE bar LIKE foo; SHOW CREATE TABLE bar; Table Create Table bar CREATE TABLE `bar` ( `id` int(11) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo ADD COLUMN a INT; SHOW CREATE TABLE foo; Table Create Table @@ -21,7 +21,7 @@ foo CREATE TABLE `foo` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 FLUSH TABLES; SHOW CREATE TABLE foo; Table Create Table @@ -29,5 +29,5 @@ foo CREATE TABLE `foo` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE foo, bar; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result index 9f6637826ab..426834da11b 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result @@ -5,7 +5,7 @@ SHOW CREATE TABLE s; Table Create Table s CREATE TABLE `s` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 SET tokudb_disable_slow_alter=1; ALTER TABLE s RENAME TO t, ADD COLUMN b INT; SHOW CREATE TABLE t; @@ -13,5 +13,5 @@ Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE t; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result index 26685013aa4..075ccad6065 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result @@ -8,7 +8,7 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (a) PARTITIONS 2 */ ALTER TABLE foo ADD COLUMN c INT; @@ -19,7 +19,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (a) PARTITIONS 2 */ DROP TABLE foo; diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result index 272d0edd61c..f4fc1b67bb6 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result @@ -33,7 +33,7 @@ foo CREATE TABLE `foo` ( `b` varchar(10) DEFAULT NULL, `c` blob, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from foo; a b c 1 bb cccc diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result index 8c490c0ad35..834ddfbd2d3 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result @@ -18,7 +18,7 @@ foo CREATE TABLE `foo` ( PRIMARY KEY (`aa`), KEY `b` (`b`), KEY `d` (`d`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from foo; aa b c d e 1 10 cc dddd eeeee @@ -40,7 +40,7 @@ foo CREATE TABLE `foo` ( PRIMARY KEY (`aa`), KEY `b` (`bb`), KEY `d` (`d`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select bb from foo FORCE INDEX (b) where bb > 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE foo index b b 9 NULL 1 Using where; Using index @@ -59,7 +59,7 @@ foo CREATE TABLE `foo` ( PRIMARY KEY (`aa`), KEY `b` (`bb`), KEY `d` (`dd`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 explain select * from foo where dd > "d"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE foo index d d 13 NULL 1 Using where; Using index diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result index 4538fa6881a..7ec5ee47865 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result @@ -63,7 +63,7 @@ foo CREATE TABLE `foo` ( UNIQUE KEY `c` (`c`), KEY `d` (`d`), KEY `b` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table foo change column aa aa int NOT NULL; ERROR 42000: Table 'foo' uses an extension that doesn't exist in this XYZ version alter table foo change column aa aa varchar(20); diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result index dd32bd5b86f..7e552fbbfa1 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result @@ -61,7 +61,7 @@ foo CREATE TABLE `foo` ( UNIQUE KEY `c` (`c`), KEY `d` (`d`), KEY `b` (`b`) `clustering`=yes -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table foo_isam; Table Create Table foo_isam CREATE TABLE `foo_isam` ( diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result index 6057137da5b..b366f097081 100644 --- a/storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result +++ b/storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result @@ -5,13 +5,13 @@ CREATE TABLE foo (c1 int not null primary key) engine=TokuDB; SELECT CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES WHERE (table_name LIKE 'foo'); CREATE_OPTIONS -`compression`='tokudb_zlib' + SHOW CREATE TABLE foo; Table Create Table foo CREATE TABLE `foo` ( `c1` int(11) NOT NULL, PRIMARY KEY (`c1`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 ALTER TABLE foo compression=tokudb_lzma, add column c2 int not null; SELECT CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES WHERE (table_name LIKE 'foo'); diff --git a/storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result index 88dad457334..005ac572afd 100644 Binary files a/storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result and b/storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result differ diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/2952.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2952.result index 277e2d9f407..d0319ab9f74 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/2952.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/2952.result @@ -12,7 +12,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; insert into foo values (1,10,100),(2,20,200),(3,30,300); set session transaction isolation level read uncommitted; @@ -35,7 +35,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; insert into foo values (1,10,100),(2,20,200),(3,30,300); insert into foo values (100,100,100); @@ -56,7 +56,7 @@ foo CREATE TABLE `foo` ( `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 begin; insert into foo values (1,10,100),(2,20,200),(3,30,300); insert into foo values (100,100,100); diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/5089.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5089.result index a4229ffa9dd..995a854f5da 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/5089.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/5089.result @@ -6,7 +6,7 @@ t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL, `c2` int(11) NOT NULL, PRIMARY KEY (`c1`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into t1 (c1,c2) values (1,1),(2,2); alter table t1 compression=tokudb_lzma; show create table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result b/storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result index 055cf471eb7..ae80daae14b 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result @@ -8,7 +8,7 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values(1); select * from foo; a @@ -20,7 +20,7 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from foo; a 1 @@ -45,7 +45,7 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from foo; a 1 @@ -67,7 +67,7 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert into foo values(1); select * from foo; a @@ -84,7 +84,7 @@ show create table fooff; Table Create Table fooff CREATE TABLE `fooff` ( `a` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table fooff; begin; select * from bar; @@ -100,7 +100,7 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `abra` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 select * from foo; abra drop table foo; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result index c7757919d69..53cb52ddcba 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result @@ -7,23 +7,23 @@ Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table bar; Table Create Table bar CREATE TABLE `bar` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table foo; Table Create Table foo CREATE TABLE `foo` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table bar; Table Create Table bar CREATE TABLE `bar` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE foo,bar; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result index e57d76fba21..b202da70fcf 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result @@ -9,12 +9,12 @@ show create table foo; Table Create Table foo CREATE TABLE `foo` ( `b` bigint(20) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table bar; Table Create Table bar CREATE TABLE `bar` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE foo,bar; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result index 7c329454692..2b098d68705 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result @@ -10,11 +10,11 @@ foo CREATE TABLE `foo` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 show create table bar; Table Create Table bar CREATE TABLE `bar` ( `a` bigint(20) DEFAULT NULL, KEY `a` (`a`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 DROP TABLE foo,bar; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/229cols.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/229cols.result index 540839485cb..c6f214e4f24 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/r/229cols.result +++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/229cols.result @@ -461,7 +461,7 @@ t1 CREATE TABLE `t1` ( `col227` varchar(40) DEFAULT NULL, `col228` varchar(40) DEFAULT NULL, `col229` varchar(40) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 add i230 integer; show create table t1; Table Create Table @@ -696,7 +696,7 @@ t1 CREATE TABLE `t1` ( `col228` varchar(40) DEFAULT NULL, `col229` varchar(40) DEFAULT NULL, `i230` int(11) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; create table t1( col1 varchar(40), @@ -1163,5 +1163,5 @@ t1 CREATE TABLE `t1` ( `col228` varchar(40) DEFAULT NULL, `col229` varchar(40) DEFAULT NULL, `col230` varchar(40) DEFAULT NULL -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/alter.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/alter.result index cc779a36ca7..600e34dfffd 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/r/alter.result +++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/alter.result @@ -9,7 +9,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL, `j` int(11) DEFAULT '0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 modify i int default '1'; select * from t1; i j @@ -19,7 +19,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) DEFAULT '1', `j` int(11) DEFAULT '0' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 alter table t1 modify j int default '2', rename t2; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -31,5 +31,5 @@ Table Create Table t2 CREATE TABLE `t2` ( `i` int(11) DEFAULT '1', `j` int(11) DEFAULT '2' -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 drop table t2; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/clustering.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/clustering.result index f8ac248e5cf..86f6fd4cdc2 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/r/clustering.result +++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/clustering.result @@ -7,7 +7,7 @@ t1 CREATE TABLE `t1` ( `c` text, KEY `a` (`a`) `clustering`=yes, KEY `b` (`b`) -) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' +) ENGINE=TokuDB DEFAULT CHARSET=latin1 insert t1 values (1, 1, 1); insert t1 select a+1, a+1, a+1 from t1; insert t1 select a+2, a+2, a+2 from t1; diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 0ef97fd3e21..dc2b81872ae 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -40,6 +40,7 @@ Created 11/5/1995 Heikki Tuuri #include "mem0mem.h" #include "btr0btr.h" #include "fil0fil.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP #include "buf0buddy.h" #include "lock0lock.h" @@ -57,8 +58,6 @@ Created 11/5/1995 Heikki Tuuri #include "trx0trx.h" #include "srv0start.h" #include "ut0byte.h" - -#include "fil0pageencryption.h" #include "fil0pagecompress.h" @@ -96,6 +95,14 @@ _increment_page_get_statistics(buf_block_t* block, trx_t* trx) return; } +#ifdef HAVE_LZO +#include "lzo/lzo1x.h" +#endif + +/* Number of temporary slots used for encryption/compression +memory allocation before/after I/O operations */ +#define BUF_MAX_TMP_SLOTS 200 + /* IMPLEMENTATION OF THE BUFFER POOL ================================= @@ -574,7 +581,7 @@ buf_page_is_corrupted( ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ { - ulint page_encrypted = fil_page_is_compressed_encrypted(read_buf) || fil_page_is_encrypted(read_buf); + ulint page_encrypted = fil_page_is_encrypted(read_buf); ulint checksum_field1; ulint checksum_field2; ibool crc32_inited = FALSE; @@ -1078,15 +1085,11 @@ buf_block_init( block->page.state = BUF_BLOCK_NOT_USED; block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; - block->page.crypt_buf = NULL; - block->page.crypt_buf_free = NULL; - block->page.comp_buf = NULL; - block->page.comp_buf_free = NULL; block->page.key_version = 0; - block->page.encrypt_later = false; - - + block->page.real_size = 0; + block->page.write_size = 0; block->modify_clock = 0; + block->page.slot = NULL; #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG block->page.file_page_was_freed = FALSE; @@ -1439,6 +1442,11 @@ buf_pool_init_instance( /* All fields are initialized by mem_zalloc(). */ + /* Initialize the temporal memory array and slots */ + buf_pool->tmp_arr = (buf_tmp_array_t *)mem_zalloc(sizeof(buf_tmp_array_t)); + buf_pool->tmp_arr->n_slots = BUF_MAX_TMP_SLOTS; + buf_pool->tmp_arr->slots = (buf_tmp_buffer_t*)mem_zalloc(sizeof(buf_tmp_buffer_t) * BUF_MAX_TMP_SLOTS); + buf_pool->try_LRU_scan = TRUE; return(DB_SUCCESS); @@ -1490,6 +1498,9 @@ buf_pool_free_instance( ha_clear(buf_pool->page_hash); hash_table_free(buf_pool->page_hash); hash_table_free(buf_pool->zip_hash); + + mem_free(buf_pool->tmp_arr->slots); + mem_free(buf_pool->tmp_arr); } /********************************************************************//** @@ -3575,12 +3586,8 @@ buf_page_init_low( bpage->newest_modification = 0; bpage->oldest_modification = 0; bpage->write_size = 0; - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - bpage->comp_buf = NULL; - bpage->comp_buf_free = NULL; bpage->key_version = 0; - bpage->encrypt_later = false; + bpage->real_size = 0; HASH_INVALIDATE(bpage, hash); bpage->is_corrupt = FALSE; @@ -3888,6 +3895,8 @@ err_exit: page_zip_set_size(&bpage->zip, zip_size); bpage->zip.data = (page_zip_t*) data; + bpage->slot = NULL; + mutex_enter(&buf_pool->zip_mutex); UNIV_MEM_DESC(bpage->zip.data, page_zip_get_size(&bpage->zip)); @@ -4499,7 +4508,11 @@ corrupt: } } else { /* io_type == BUF_IO_WRITE */ - buf_page_encrypt_after_write(bpage); + if (bpage->slot) { + /* Mark slot free */ + bpage->slot->reserved = false; + bpage->slot = NULL; + } } if (io_type == BUF_IO_WRITE @@ -5779,6 +5792,60 @@ buf_pool_mutex_exit( mutex_exit(&buf_pool->LRU_list_mutex); } +/********************************************************************//** +Reserve unused slot from temporary memory array and allocate necessary +temporary memory if not yet allocated. +@return reserved slot */ +buf_tmp_buffer_t* +buf_pool_reserve_tmp_slot( +/*======================*/ + buf_pool_t* buf_pool, /*!< in: buffer pool where to + reserve */ + bool compressed) /*!< in: is file space compressed */ +{ + buf_tmp_buffer_t *free_slot=NULL; + + /* Array is protected by buf_pool mutex */ + buf_pool_mutex_enter(buf_pool); + + for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { + buf_tmp_buffer_t *slot = &buf_pool->tmp_arr->slots[i]; + + if(slot->reserved == false) { + free_slot = slot; + break; + } + } + + /* We assume that free slot is found */ + ut_a(free_slot != NULL); + free_slot->reserved = true; + /* Now that we have reserved this slot we can release + buf_pool mutex */ + buf_pool_mutex_exit(buf_pool); + + /* Allocate temporary memory for encryption/decryption */ + if (free_slot->crypt_buf_free == NULL) { + free_slot->crypt_buf_free = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); + free_slot->crypt_buf = static_cast(ut_align(free_slot->crypt_buf_free, UNIV_PAGE_SIZE)); + memset(free_slot->crypt_buf_free, 0, UNIV_PAGE_SIZE *2); + } + + /* For page compressed tables allocate temporary memory for + compression/decompression */ + if (compressed && free_slot->comp_buf_free == NULL) { + free_slot->comp_buf_free = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); + free_slot->comp_buf = static_cast(ut_align(free_slot->comp_buf_free, UNIV_PAGE_SIZE)); + memset(free_slot->comp_buf_free, 0, UNIV_PAGE_SIZE *2); +#ifdef HAVE_LZO + free_slot->lzo_mem = static_cast(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); + memset(free_slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); +#endif + } + + return (free_slot); +} + /********************************************************************//** Encrypts a buffer page right before it's flushed to disk */ @@ -5786,11 +5853,18 @@ byte* buf_page_encrypt_before_write( /*==========================*/ buf_page_t* bpage, /*!< in/out: buffer page to be flushed */ - const byte* src_frame) /*!< in: src frame */ + const byte* src_frame, /*!< in: src frame */ + ulint space_id) /*!< in: space id */ { - bpage->encrypt_later = false; + fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id); + bpage->real_size = UNIV_PAGE_SIZE; - if (srv_encrypt_tables == FALSE) { + if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + /* Encryption is disabled */ + return const_cast(src_frame); + } + + if (!srv_encrypt_tables && (crypt_data == NULL || crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { /* Encryption is disabled */ return const_cast(src_frame); } @@ -5815,103 +5889,63 @@ buf_page_encrypt_before_write( ulint zip_size = buf_page_get_zip_size(bpage); ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + bool page_compressed = fil_space_is_page_compressed(bpage->space); - /** - * TODO(jonaso): figure out more clever malloc strategy - * - * This implementation does a malloc/free per iop for encrypted - * tablespaces. Alternative strategies that have been considered are - * - * 1) use buf_block_alloc (i.e alloc from buffer pool) - * this does not work as buf_block_alloc will then be called - * when needing to flush a page, which might be triggered - * due to shortage of memory in buffer pool - * 2) allocate a buffer per fil_node_t - * this would break abstraction layers and has therfore not been - * considered a lot. - */ + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); + bpage->slot = slot; - if (bpage->crypt_buf_free == NULL) { - bpage->crypt_buf_free = (byte*)malloc(page_size*2); - // TODO: Is 4k aligment enough ? - bpage->crypt_buf = (byte *)ut_align(bpage->crypt_buf_free, page_size); - } + byte *dst_frame = slot->crypt_buf; - byte *dst_frame = bpage->crypt_buf; - - if (!fil_space_is_page_compressed(bpage->space)) { - // encrypt page content - fil_space_encrypt(bpage->space, bpage->offset, - bpage->newest_modification, - src_frame, zip_size, dst_frame, 0); + if (!page_compressed) { + /* Encrypt page content */ + fil_space_encrypt(bpage->space, + bpage->offset, + bpage->newest_modification, + src_frame, + zip_size, + dst_frame); unsigned key_version = mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); ut_ad(key_version == 0 || key_version >= bpage->key_version); bpage->key_version = key_version; + bpage->real_size = page_size; } else { - /** Compression and encryption is done later at os0file.cc */ - bpage->encrypt_later = true; - dst_frame = (byte *)src_frame; + /* First we compress the page content */ + ulint out_len = 0; + ulint block_size = fil_space_get_block_size(bpage->space, bpage->offset, page_size); + + byte *tmp = fil_compress_page(bpage->space, + (byte *)src_frame, + slot->comp_buf, + page_size, + fil_space_get_page_compression_level(bpage->space), + block_size, + &out_len, +#ifdef HAVE_LZO + slot->lzo_mem +#else + NULL +#endif + ); + + bpage->real_size = out_len; + + /* And then we encrypt the page content */ + fil_space_encrypt(bpage->space, + bpage->offset, + bpage->newest_modification, + tmp, + zip_size, + dst_frame); } // return dst_frame which will be written return dst_frame; } -/********************************************************************//** -Release memory after encrypted page has been written to disk -*/ -ibool -buf_page_encrypt_after_write( -/*=========================*/ - buf_page_t* bpage) /*!< in/out: buffer page flushed */ -{ - if (bpage->crypt_buf_free != NULL) { - free(bpage->crypt_buf_free); - bpage->crypt_buf_free = NULL; - bpage->crypt_buf = NULL; - } - - if (bpage->comp_buf_free != NULL) { - free(bpage->comp_buf_free); - bpage->comp_buf_free = NULL; - bpage->comp_buf = NULL; - } - - return (TRUE); -} - -/********************************************************************//** -Allocates memory to read in an encrypted page -*/ -byte* -buf_page_decrypt_before_read( -/*=========================*/ - buf_page_t* bpage, /*!< in/out: buffer page to be read */ - ulint zip_size) /*!< in: compressed page size, or 0 */ -{ - ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; - - /* - Here we only need to allocate space for not header pages - in case of file space encryption. Table encryption is handled - later. - */ - if (!srv_encrypt_tables || bpage->offset == 0 || - fil_space_check_encryption_read(bpage->space) == false) - return zip_size ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - - if (bpage->crypt_buf_free == NULL) - { - // allocate buffer to read data into - bpage->crypt_buf_free = (byte*)malloc(size*2); - // TODO: Is 4K aligment enough ? - bpage->crypt_buf = (byte*)ut_align(bpage->crypt_buf_free, size); - } - return bpage->crypt_buf; -} - /********************************************************************//** Decrypt page after it has been read from disk */ @@ -5921,100 +5955,59 @@ buf_page_decrypt_after_read( buf_page_t* bpage) /*!< in/out: buffer page read from disk */ { ut_ad(bpage->key_version == 0); + + if (bpage->offset == 0) { + /* File header pages are not encrypted */ + return (TRUE); + } + ulint zip_size = buf_page_get_zip_size(bpage); ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; byte* dst_frame = (zip_size) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - - if (bpage->offset == 0) { - /* File header pages are not encrypted */ - ut_a(bpage->crypt_buf == NULL); - return (TRUE); - } - - const byte* src_frame = bpage->crypt_buf != NULL ? - bpage->crypt_buf : dst_frame; - unsigned key_version = - mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - bool page_compressed_encrypted = fil_page_is_compressed_encrypted(dst_frame); + mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + bool page_compressed = fil_page_is_compressed(dst_frame); + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); if (key_version == 0) { /* the page we read is unencrypted */ - if (fil_page_is_compressed(dst_frame)) { - if (bpage->comp_buf_free == NULL) { - bpage->comp_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - bpage->comp_buf = (byte*)ut_align(bpage->comp_buf_free, UNIV_PAGE_SIZE); - } + if (page_compressed) { + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); - fil_decompress_page(bpage->comp_buf, dst_frame, size, NULL); - } else { - if (dst_frame != src_frame) { - /* but we had allocated a crypt_buf */ - // TODO: Can this be avoided ? - memcpy(dst_frame, src_frame, size); - } - } + fil_decompress_page(slot->comp_buf, + dst_frame, + size, + &bpage->write_size); + + /* Mark this slot as free */ + slot->reserved = false; + } } else { - /* the page we read is encrypted */ - if (dst_frame == src_frame) { - /* but we had NOT allocated a crypt buf - * malloc a buffer, copy page to it - * and then decrypt from that into real page*/ - bpage->crypt_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - src_frame = bpage->crypt_buf = (byte*)ut_align(bpage->crypt_buf_free, UNIV_PAGE_SIZE); - memcpy(bpage->crypt_buf, dst_frame, size); - } - /* decrypt from src_frame to dst_frame */ - fil_space_decrypt(bpage->space, - src_frame, size, dst_frame); + /* Find free slot from temporary memory array */ + buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed); + memcpy(slot->crypt_buf, dst_frame, size); - /* decompress from dst_frame to comp_buf and then copy to - buffer pool */ - if (page_compressed_encrypted) { - if (bpage->comp_buf_free == NULL) { - bpage->comp_buf_free = (byte *)malloc(UNIV_PAGE_SIZE*2); - // TODO: is 4k aligment enough ? - bpage->comp_buf = (byte*)ut_align(bpage->comp_buf_free, UNIV_PAGE_SIZE); - } + /* decrypt from crypt_buf to dst_frame */ + fil_space_decrypt(bpage->space, + slot->crypt_buf, + size, + dst_frame); - fil_decompress_page(bpage->comp_buf, dst_frame, size, NULL); - } + if (page_compressed) { + fil_decompress_page(slot->comp_buf, + dst_frame, + size, + &bpage->write_size); + } + + /* Mark this slot as free */ + slot->reserved = false; } bpage->key_version = key_version; - if (bpage->crypt_buf_free != NULL) { - // free temp page - free(bpage->crypt_buf_free); - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - } - - if (bpage->comp_buf_free != NULL) { - // free temp page - free(bpage->comp_buf_free); - bpage->comp_buf = NULL; - bpage->comp_buf_free = NULL; - } - return (TRUE); } - -/********************************************************************//** -Release memory allocated for decryption -*/ -void -buf_page_decrypt_cleanup( -/*=====================*/ - buf_page_t* bpage) /*!< in/out: buffer page */ -{ - if (bpage->crypt_buf != NULL) { - free(bpage->crypt_buf_free); - bpage->crypt_buf = NULL; - bpage->crypt_buf_free = NULL; - } -} diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 871f723549b..1cfb6703fcb 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -36,6 +36,7 @@ Created 2011/12/19 #include "srv0srv.h" #include "page0zip.h" #include "trx0sys.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP @@ -385,7 +386,7 @@ buf_dblwr_init_or_load_pages( /* Read the trx sys header to check if we are using the doublewrite buffer */ off_t trx_sys_page = TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE; - os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE, FALSE); + os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE); doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; @@ -430,9 +431,9 @@ buf_dblwr_init_or_load_pages( block_bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; - os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes, FALSE); + os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes); os_file_read(file, buf + block_bytes, block2 * UNIV_PAGE_SIZE, - block_bytes, FALSE); + block_bytes); /* Check if any of these pages is half-written in data files, in the intended position */ @@ -530,9 +531,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, read_buf, NULL, - 0, - 0, - false); + 0); if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { /* page is encrypted and checksum is OK */ @@ -593,9 +592,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, page, NULL, - 0, - 0, - false); + 0); ib_logf(IB_LOG_LEVEL_INFO, "Recovered the page from" @@ -619,9 +616,7 @@ buf_dblwr_process() zip_size ? zip_size : UNIV_PAGE_SIZE, page, NULL, - 0, - 0, - false); + 0); } } } @@ -630,10 +625,6 @@ buf_dblwr_process() fil_flush_file_spaces(FIL_TABLESPACE); { - fprintf(stderr, - "Clear dblwr buffer after completing " - "processing of it...\n"); - size_t bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; byte *unaligned_buf = static_cast( ut_malloc(bytes + UNIV_PAGE_SIZE - 1)); @@ -643,9 +634,9 @@ buf_dblwr_process() memset(buf, 0, bytes); fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, - buf_dblwr->block1, 0, bytes, buf, NULL, NULL, 0, false); + buf_dblwr->block1, 0, bytes, buf, NULL, NULL); fil_io(OS_FILE_WRITE, true, TRX_SYS_SPACE, 0, - buf_dblwr->block2, 0, bytes, buf, NULL, NULL, 0, false); + buf_dblwr->block2, 0, bytes, buf, NULL, NULL); ut_free(unaligned_buf); } @@ -859,9 +850,7 @@ buf_dblwr_write_block_to_datafile( buf_page_get_zip_size(bpage), frame, (void*) bpage, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); return; } @@ -877,12 +866,10 @@ buf_dblwr_write_block_to_datafile( 0, buf_block_get_page_no(block), 0, - UNIV_PAGE_SIZE, + bpage->real_size, frame, (void*) block, - (ulint *)&bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + (ulint *)&bpage->write_size); } /********************************************************************//** @@ -984,9 +971,7 @@ try_again: (void*) write_buf, NULL, - 0, - 0, - false); + 0); if (buf_dblwr->first_free <= TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { /* No unwritten pages in the second block. */ @@ -1009,9 +994,7 @@ try_again: len, (void*) write_buf, NULL, - 0, - 0, - false); + 0); flush: /* increment the doublewrite flushed pages counter */ @@ -1250,9 +1233,7 @@ retry: UNIV_PAGE_SIZE, (void*) (buf_dblwr->write_buf + UNIV_PAGE_SIZE * i), NULL, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); } else { /* It is a regular page. Write it directly to the doublewrite buffer */ @@ -1261,12 +1242,11 @@ retry: TRX_SYS_SPACE, 0, offset, - 0, UNIV_PAGE_SIZE, + 0, + bpage->real_size, frame, NULL, - 0, - bpage->newest_modification, - bpage->encrypt_later); + 0); } /* Now flush the doublewrite buffer data to disk */ diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc index 4331db08cf5..6443043310b 100644 --- a/storage/xtradb/buf/buf0flu.cc +++ b/storage/xtradb/buf/buf0flu.cc @@ -951,7 +951,7 @@ buf_flush_write_block_low( break; } - frame = buf_page_encrypt_before_write(bpage, frame); + frame = buf_page_encrypt_before_write(bpage, frame, space_id); if (!srv_use_doublewrite_buf || !buf_dblwr) { fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, @@ -960,12 +960,10 @@ buf_flush_write_block_low( zip_size, buf_page_get_page_no(bpage), 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, + zip_size ? zip_size : bpage->real_size, frame, bpage, - &bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + &bpage->write_size); } else { /* InnoDB uses doublewrite buffer and doublewrite buffer is initialized. User can define do we use atomic writes @@ -981,12 +979,10 @@ buf_flush_write_block_low( zip_size, buf_page_get_page_no(bpage), 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, + zip_size ? zip_size : bpage->real_size, frame, bpage, - &bpage->write_size, - bpage->newest_modification, - bpage->encrypt_later); + &bpage->write_size); } else if (flush_type == BUF_FLUSH_SINGLE_PAGE) { buf_dblwr_write_single_page(bpage, sync); } else { diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc index 88741f987ca..6c74c30739e 100644 --- a/storage/xtradb/buf/buf0rea.cc +++ b/storage/xtradb/buf/buf0rea.cc @@ -222,7 +222,7 @@ not_to_recover: ut_ad(buf_page_in_file(bpage)); ut_ad(!mutex_own(&buf_pool_from_bpage(bpage)->LRU_list_mutex)); - byte* frame = buf_page_decrypt_before_read(bpage, zip_size); + byte* frame = zip_size ? bpage->zip.data : ((buf_block_t*) bpage)->frame; if (sync) { thd_wait_begin(NULL, THD_WAIT_DISKIO); @@ -232,14 +232,14 @@ not_to_recover: *err = _fil_io(OS_FILE_READ | wake_later | ignore_nonexistent_pages, sync, space, zip_size, offset, 0, zip_size, - frame, bpage, 0, trx, 0, false); + frame, bpage, 0, trx); } else { ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); *err = _fil_io(OS_FILE_READ | wake_later | ignore_nonexistent_pages, sync, space, 0, offset, 0, UNIV_PAGE_SIZE, - frame, bpage, &bpage->write_size, trx, 0, false); + frame, bpage, &bpage->write_size, trx); } if (sync) { @@ -247,7 +247,6 @@ not_to_recover: } if (*err != DB_SUCCESS) { - buf_page_decrypt_cleanup(bpage); if (ignore_nonexistent_pages || *err == DB_TABLESPACE_DELETED) { buf_read_page_handle_error(bpage); return(0); diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index 9f8315a8016..69f194578ae 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -24,6 +24,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com *******************************************************/ #include "fil0fil.h" +#include "fil0crypt.h" #include "srv0srv.h" #include "srv0start.h" #include "mach0data.h" @@ -35,15 +36,10 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "btr0scrub.h" #include "fsp0fsp.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #include "ha_prototypes.h" // IB_LOG_ #include -#include -#include - - /** Mutex for keys */ UNIV_INTERN ib_mutex_t fil_crypt_key_mutex; @@ -52,7 +48,7 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; #endif /** Is encryption enabled/disabled */ -UNIV_INTERN my_bool srv_encrypt_tables = FALSE; +UNIV_INTERN ulong srv_encrypt_tables = 0; /** No of key rotation threads requested */ UNIV_INTERN uint srv_n_fil_crypt_threads = 0; @@ -119,67 +115,12 @@ static const unsigned char CRYPT_MAGIC[MAGIC_SZ] = { static const unsigned char EMPTY_PATTERN[MAGIC_SZ] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -/** - * CRYPT_SCHEME_UNENCRYPTED - * - * Used as intermediate state when convering a space from unencrypted - * to encrypted - */ -#define CRYPT_SCHEME_UNENCRYPTED 0 - -/** - * CRYPT_SCHEME_1 - * - * L = AES_ECB(KEY, IV) - * CRYPT(PAGE) = AES_CRT(KEY=L, IV=C, PAGE) - */ -#define CRYPT_SCHEME_1 1 -#define CRYPT_SCHEME_1_IV_LEN 16 -// cached L given key_version -struct key_struct -{ - uint key_version; - byte key[CRYPT_SCHEME_1_IV_LEN]; -}; - -struct fil_space_rotate_state_t -{ - time_t start_time; // time when rotation started - ulint active_threads; // active threads in space - ulint next_offset; // next "free" offset - ulint max_offset; // max offset needing to be rotated - uint min_key_version_found; // min key version found but not rotated - lsn_t end_lsn; // max lsn created when rotating this space - bool starting; // initial write of IV - bool flushing; // space is being flushed at end of rotate - struct { - bool is_active; // is scrubbing active in this space - time_t last_scrub_completed; // when was last scrub completed - } scrubbing; -}; - -struct fil_space_crypt_struct -{ - ulint type; // CRYPT_SCHEME - uint keyserver_requests; // no of key requests to key server - uint key_count; // No of initalized key-structs - key_struct keys[3]; // cached L = AES_ECB(KEY, IV) - uint min_key_version; // min key version for this space - ulint page0_offset; // byte offset on page 0 for crypt data - - ib_mutex_t mutex; // mutex protecting following variables - bool closing; // is tablespace being closed - fil_space_rotate_state_t rotate_state; - - uint iv_length; // length of IV - byte iv[1]; // IV-data -}; - /********************************************************************* Init space crypt */ UNIV_INTERN void fil_space_crypt_init() +/*==================*/ { mutex_create(fil_crypt_key_mutex_key, &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK); @@ -196,6 +137,7 @@ Cleanup space crypt */ UNIV_INTERN void fil_space_crypt_cleanup() +/*=====================*/ { os_event_free(fil_crypt_throttle_sleep_event); } @@ -204,94 +146,75 @@ fil_space_crypt_cleanup() Get key bytes for a space/key-version */ static void -fil_crypt_get_key(byte *dst, uint* key_length, - fil_space_crypt_t* crypt_data, uint version, bool page_encrypted) +fil_crypt_get_key( +/*==============*/ + byte* dst, /*mutex); - if (!page_encrypted) { - // Check if we already have key - for (uint i = 0; i < crypt_data->key_count; i++) { - if (crypt_data->keys[i].key_version == version) { - memcpy(dst, crypt_data->keys[i].key, - sizeof(crypt_data->keys[i].key)); - mutex_exit(&crypt_data->mutex); - return; - } + // Check if we already have key + for (uint i = 0; i < crypt_data->key_count; i++) { + if (crypt_data->keys[i].key_version == version) { + memcpy(dst, crypt_data->keys[i].key, + crypt_data->keys[i].key_length); + *key_length = crypt_data->keys[i].key_length; + mutex_exit(&crypt_data->mutex); + return; } - // Not found! - crypt_data->keyserver_requests++; + } - // Rotate keys to make room for a new - for (uint i = 1; i < array_elements(crypt_data->keys); i++) { - crypt_data->keys[i] = crypt_data->keys[i - 1]; - } - } + // Not found! + crypt_data->keyserver_requests++; - if (has_encryption_key(version)) { - int rc; - *key_length = get_encryption_key_size(version); + // Rotate keys to make room for a new + for (uint i = 1; i < array_elements(crypt_data->keys); i++) { + crypt_data->keys[i] = crypt_data->keys[i - 1]; + } - rc = get_encryption_key(version, (unsigned char*)keybuf, *key_length); - - if (rc != CRYPT_KEY_OK) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Key %d can not be found. Reason=%d", version, rc); - ut_error; - } - } else { + *key_length = sizeof(keybuf); + uint rc = encryption_key_get(crypt_data->key_id, version, keybuf, key_length); + if (rc) { ib_logf(IB_LOG_LEVEL_FATAL, - "Key %d not found", version); + "Key id %u version %u can not be found. Reason=%u", + crypt_data->key_id, version, rc); ut_error; } + /* Now compute L by encrypting IV using this key. Note + that we use random IV from crypt data. */ + const unsigned char* src = crypt_data->iv; + const int srclen = crypt_data->iv_length; + unsigned char* buf = crypt_data->keys[0].key; + uint32 buflen = CRYPT_SCHEME_1_IV_LEN; - // do ctr key initialization - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) - { - /* Now compute L by encrypting IV using this key. Note - that we use random IV from crypt data. */ - const unsigned char* src = crypt_data->iv; - const int srclen = crypt_data->iv_length; - unsigned char* buf = page_encrypted ? keybuf : crypt_data->keys[0].key; - uint32 buflen = page_encrypted ? *key_length : sizeof(crypt_data->keys[0].key); + /* We use AES_ECB to encrypt IV */ + rc = my_aes_encrypt_ecb(src, srclen, buf, &buflen, + keybuf, *key_length, NULL, 0, 1); - // call ecb explicit - my_aes_encrypt_dynamic_type func = get_aes_encrypt_func(MY_AES_ALGORITHM_ECB); - int rc = (*func)(src, srclen, - buf, &buflen, - (unsigned char*)keybuf, *key_length, - NULL, 0, - 1); - - if (rc != AES_OK) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Unable to encrypt key-block " - " src: %p srclen: %d buf: %p buflen: %d." - " return-code: %d. Can't continue!\n", - src, srclen, buf, buflen, rc); - ut_error; - } - - if (!page_encrypted) { - crypt_data->keys[0].key_version = version; - crypt_data->key_count++; - - if (crypt_data->key_count > array_elements(crypt_data->keys)) { - crypt_data->key_count = array_elements(crypt_data->keys); - } - } - - // set the key size to the aes block size because this encrypted data is the key - *key_length = MY_AES_BLOCK_SIZE; - memcpy(dst, buf, buflen); - } else { - // otherwise keybuf contains the right key - memcpy(dst, keybuf, *key_length); + if (rc != MY_AES_OK) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Unable to encrypt key-block " + " src: %p srclen: %d buf: %p buflen: %d." + " return-code: %d. Can't continue!\n", + src, srclen, buf, buflen, rc); + ut_error; } + crypt_data->keys[0].key_version = version; + crypt_data->key_count++; + *key_length = buflen; + crypt_data->keys[0].key_length = buflen; + + if (crypt_data->key_count > array_elements(crypt_data->keys)) { + crypt_data->key_count = array_elements(crypt_data->keys); + } + + memcpy(dst, buf, buflen); mutex_exit(&crypt_data->mutex); } @@ -299,46 +222,55 @@ fil_crypt_get_key(byte *dst, uint* key_length, Get key bytes for a space/latest(key-version) */ static inline void -fil_crypt_get_latest_key(byte *dst, uint* key_length, - fil_space_crypt_t* crypt_data, uint *version) +fil_crypt_get_latest_key( +/*=====================*/ + byte* dst, /*!< out: Key */ + uint* key_length, /*!< out: Key length */ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + uint* version) /*!< in: Key version */ { - if (srv_encrypt_tables) { - // used for key rotation - get the next key id from the key provider - int rc = get_latest_encryption_key_version(); + // used for key rotation - get the next key id from the key provider + uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id); - // if no new key was created use the last one - if (rc >= 0) { - *version = rc; - } + if (rc == ENCRYPTION_KEY_VERSION_INVALID) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Unknown key id %u. Can't continue!\n", + crypt_data->key_id); + ut_error; } - return fil_crypt_get_key(dst, key_length, crypt_data, *version, srv_encrypt_tables == FALSE); + return fil_crypt_get_key(dst, key_length, crypt_data, *version); } /****************************************************************** -Create a fil_space_crypt_t object */ +Create a fil_space_crypt_t object +@return crypt object */ UNIV_INTERN fil_space_crypt_t* -fil_space_create_crypt_data() +fil_space_create_crypt_data(uint key_id) +/*=========================*/ { const uint iv_length = CRYPT_SCHEME_1_IV_LEN; const uint sz = sizeof(fil_space_crypt_t) + iv_length; fil_space_crypt_t* crypt_data = static_cast(malloc(sz)); + memset(crypt_data, 0, sz); - if (srv_encrypt_tables == FALSE) { + if (!srv_encrypt_tables) { crypt_data->type = CRYPT_SCHEME_UNENCRYPTED; crypt_data->min_key_version = 0; } else { crypt_data->type = CRYPT_SCHEME_1; - crypt_data->min_key_version = get_latest_encryption_key_version(); + crypt_data->key_id = key_id; + crypt_data->min_key_version = encryption_key_get_latest_version(key_id); } mutex_create(fil_crypt_data_mutex_key, &crypt_data->mutex, SYNC_NO_ORDER_CHECK); crypt_data->iv_length = iv_length; my_random_bytes(crypt_data->iv, iv_length); + crypt_data->encryption = FIL_SPACE_ENCRYPTION_DEFAULT; return crypt_data; } @@ -346,11 +278,14 @@ fil_space_create_crypt_data() Compare two crypt objects */ UNIV_INTERN int -fil_space_crypt_compare(const fil_space_crypt_t* crypt_data1, - const fil_space_crypt_t* crypt_data2) +fil_space_crypt_compare( +/*====================*/ + const fil_space_crypt_t* crypt_data1,/*!< in: Crypt data */ + const fil_space_crypt_t* crypt_data2)/*!< in: Crypt data */ { ut_a(crypt_data1->type == CRYPT_SCHEME_UNENCRYPTED || crypt_data1->type == CRYPT_SCHEME_1); + ut_a(crypt_data2->type == CRYPT_SCHEME_UNENCRYPTED || crypt_data2->type == CRYPT_SCHEME_1); @@ -365,10 +300,15 @@ fil_space_crypt_compare(const fil_space_crypt_t* crypt_data1, } /****************************************************************** -Read crypt data from a page (0) */ +Read crypt data from a page (0) +@return crypt data from page 0. */ UNIV_INTERN fil_space_crypt_t* -fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) +fil_space_read_crypt_data( +/*======================*/ + ulint space, /*!< in: file space id*/ + const byte* page, /*!< in: page 0 */ + ulint offset) /*!< in: offset */ { if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) { /* crypt is not stored */ @@ -395,6 +335,7 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) if (! (type == CRYPT_SCHEME_UNENCRYPTED || type == CRYPT_SCHEME_1)) { + ib_logf(IB_LOG_LEVEL_ERROR, "Found non sensible crypt scheme: %lu for space %lu " " offset: %lu bytes: " @@ -429,6 +370,12 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) uint min_key_version = mach_read_from_4 (page + offset + MAGIC_SZ + 2 + iv_length); + uint key_id = mach_read_from_4 + (page + offset + MAGIC_SZ + 2 + iv_length + 4); + + fil_encryption_t encryption = (fil_encryption_t)mach_read_from_1( + page + offset + MAGIC_SZ + 2 + iv_length + 8); + const uint sz = sizeof(fil_space_crypt_t) + iv_length; fil_space_crypt_t* crypt_data = static_cast( malloc(sz)); @@ -436,7 +383,9 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) crypt_data->type = type; crypt_data->min_key_version = min_key_version; + crypt_data->key_id = key_id; crypt_data->page0_offset = offset; + crypt_data->encryption = encryption; mutex_create(fil_crypt_data_mutex_key, &crypt_data->mutex, SYNC_NO_ORDER_CHECK); crypt_data->iv_length = iv_length; @@ -449,13 +398,11 @@ fil_space_read_crypt_data(ulint space, const byte* page, ulint offset) Free a crypt data object */ UNIV_INTERN void -fil_space_destroy_crypt_data(fil_space_crypt_t **crypt_data) +fil_space_destroy_crypt_data( +/*=========================*/ + fil_space_crypt_t **crypt_data) /*!< out: crypt data */ { if (crypt_data != NULL && (*crypt_data) != NULL) { - /* lock (and unlock) mutex to make sure no one has it locked - * currently */ - mutex_enter(& (*crypt_data)->mutex); - mutex_exit(& (*crypt_data)->mutex); mutex_free(& (*crypt_data)->mutex); free(*crypt_data); (*crypt_data) = NULL; @@ -466,18 +413,24 @@ fil_space_destroy_crypt_data(fil_space_crypt_t **crypt_data) Write crypt data to a page (0) */ static void -fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, - ulint type, - byte* page, ulint offset, - ulint maxsize, mtr_t* mtr) +fil_space_write_crypt_data_low( +/*===========================*/ + fil_space_crypt_t* crypt_data, /* 0 && offset < UNIV_PAGE_SIZE); ulint space_id = mach_read_from_4( page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); const uint len = crypt_data->iv_length; const uint min_key_version = crypt_data->min_key_version; + const uint key_id = crypt_data->key_id; + const fil_encryption_t encryption = crypt_data->encryption; crypt_data->page0_offset = offset; - ut_a(2 + len + 4 + MAGIC_SZ < maxsize); + ut_a(2 + len + 4 + 1 + 4 + MAGIC_SZ < maxsize); /* redo log this as bytewise updates to page 0 @@ -491,11 +444,13 @@ fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, mtr); mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len, min_key_version, MLOG_4BYTES, mtr); + mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len, key_id, + MLOG_4BYTES, mtr); + mlog_write_ulint(page + offset + MAGIC_SZ + 2 + len + 8, encryption, + MLOG_1BYTE, mtr); - DBUG_EXECUTE_IF("ib_file_crypt_redo_crash_1", - ut_error;); + byte* log_ptr = mlog_open(mtr, 11 + 17 + len); - byte* log_ptr = mlog_open(mtr, 11 + 12 + len); if (log_ptr != NULL) { log_ptr = mlog_write_initial_log_record_fast( page, @@ -511,29 +466,34 @@ fil_space_write_crypt_data_low(fil_space_crypt_t *crypt_data, log_ptr += 1; mach_write_to_4(log_ptr, min_key_version); log_ptr += 4; + mach_write_to_4(log_ptr, key_id); + log_ptr += 4; + mach_write_to_1(log_ptr, encryption); + log_ptr += 1; mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, crypt_data->iv, len); } - - DBUG_EXECUTE_IF("ib_file_crypt_redo_crash_2", - ut_error;); } /****************************************************************** Write crypt data to a page (0) */ UNIV_INTERN void -fil_space_write_crypt_data(ulint space, byte* page, ulint offset, - ulint maxsize, mtr_t* mtr) +fil_space_write_crypt_data( +/*=======================*/ + ulint space, /*page0_offset = offset; crypt_data->min_key_version = min_key_version; + crypt_data->encryption = encryption; memcpy(crypt_data->iv, ptr, len); ptr += len; @@ -595,7 +569,10 @@ fil_parse_write_crypt_data(byte* ptr, byte* end_ptr, Clear crypt data from a page (0) */ UNIV_INTERN void -fil_space_clear_crypt_data(byte* page, ulint offset) +fil_space_clear_crypt_data( +/*=======================*/ + byte* page, /*!< in/out: Page 0 */ + ulint offset) /*!< in: Offset */ { //TODO(jonaso): pass crypt-data and read len from there ulint len = CRYPT_SCHEME_1_IV_LEN; @@ -604,19 +581,22 @@ fil_space_clear_crypt_data(byte* page, ulint offset) 1 + // type 1 + // len len + // iv - 4; // min key version + 4 + // min key version + 4 + // key id + 1; // fil_encryption_t memset(page + offset, 0, size); } /********************************************************************* -Check if page shall be encrypted before write */ +Check if page shall be encrypted before write +@return true if page should be encrypted, false if not */ UNIV_INTERN bool fil_space_check_encryption_write( /*==============================*/ ulint space) /*!< in: tablespace id */ { - if (srv_encrypt_tables == FALSE) + if (!srv_encrypt_tables) return false; fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -636,23 +616,29 @@ fil_space_check_encryption_write( Encrypt a page */ UNIV_INTERN void -fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, - const byte* src_frame, ulint zip_size, byte* dst_frame, ulint encryption_key) +fil_space_encrypt( +/*==============*/ + ulint space, /*!< in: Space id */ + ulint offset, /*!< in: Page offset */ + lsn_t lsn, /*!< in: lsn */ + const byte* src_frame, /*!< in: Source page to be encrypted */ + ulint zip_size, /*!< in: compressed size if + row_format compressed */ + byte* dst_frame) /*!< in: outbut buffer */ { - fil_space_crypt_t* crypt_data=NULL; + fil_space_crypt_t* crypt_data = NULL; ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE; - - // get key (L) - uint key_version = encryption_key; - byte key[MY_AES_MAX_KEY_LENGTH]; - uint key_length=MY_AES_MAX_KEY_LENGTH; + uint key_version; + unsigned char key[MY_AES_MAX_KEY_LENGTH]; + uint key_length = MY_AES_MAX_KEY_LENGTH; + unsigned char iv[MY_AES_BLOCK_SIZE]; ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); if (orig_page_type==FIL_PAGE_TYPE_FSP_HDR - || orig_page_type==FIL_PAGE_TYPE_XDES - || orig_page_type== FIL_PAGE_PAGE_ENCRYPTED - || orig_page_type== FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { + || orig_page_type==FIL_PAGE_TYPE_XDES) { + /* File space header or extent descriptor do not need to be + encrypted. */ //TODO: is this really needed ? memcpy(dst_frame, src_frame, page_size); return; @@ -669,63 +655,42 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, fil_crypt_get_latest_key(key, &key_length, crypt_data, &key_version); - /* Load the iv or counter (depending to the encryption algorithm used) */ - unsigned char iv[MY_AES_BLOCK_SIZE]; - - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) { - // create counter block (C) - mach_write_to_4(iv + 0, space); - ulint space_offset = mach_read_from_4( - src_frame + FIL_PAGE_OFFSET); - mach_write_to_4(iv + 4, space_offset); - mach_write_to_8(iv + 8, lsn); - } else { - // Get random IV from crypt_data - mutex_enter(&crypt_data->mutex); - memcpy(iv, crypt_data->iv, crypt_data->iv_length); - mutex_exit(&crypt_data->mutex); - } + /* create iv/counter */ + mach_write_to_4(iv + 0, space); + mach_write_to_4(iv + 4, offset); + mach_write_to_8(iv + 8, lsn); ibool page_compressed = (mach_read_from_2(src_frame+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED); - ibool page_encrypted = fil_space_is_page_encrypted(space); - ulint compression_alg = mach_read_from_8(src_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - // copy page header + /* FIL page header is not encrypted */ memcpy(dst_frame, src_frame, FIL_PAGE_DATA); - if (page_encrypted && !page_compressed) { - // key id - mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - key_version); - // original page type - mach_write_to_2(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2, - orig_page_type); - // new page type - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_ENCRYPTED); - } else { - // store key version - mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - key_version); - } + /* Store key version */ + mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, key_version); - // encrypt page data + /* Calculate the start offset in a page */ ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END; ulint srclen = page_size - unencrypted_bytes; const byte* src = src_frame + FIL_PAGE_DATA; byte* dst = dst_frame + FIL_PAGE_DATA; - uint32 dstlen; + uint32 dstlen = 0; + /* For page compressed tables we encrypt only the actual compressed + payload. Note that first two bytes of page data is actual payload + size and that should not be encrypted. */ if (page_compressed) { - srclen = page_size - FIL_PAGE_DATA; + ulint payload = mach_read_from_2(src_frame + FIL_PAGE_DATA); + mach_write_to_2(dst_frame + FIL_PAGE_DATA, payload); + srclen = payload; + src+=2; + dst+=2; } - int rc = (* my_aes_encrypt_dynamic)(src, srclen, - dst, &dstlen, - (unsigned char*)key, key_length, - (unsigned char*)iv, sizeof(iv), - 1); + int rc = encryption_encrypt(src, srclen, dst, &dstlen, + key, key_length, iv, sizeof(iv), 1, + crypt_data->key_id, key_version); - if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) { + if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { ib_logf(IB_LOG_LEVEL_FATAL, "Unable to encrypt data-block " " src: %p srclen: %ld buf: %p buflen: %d." @@ -735,8 +700,12 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, ut_error; } + /* For compressed tables we do not store the FIL header because + the whole page is not stored to the disk. In compressed tables only + the FIL header + compressed (and now encrypted) payload alligned + to sector boundary is written. */ if (!page_compressed) { - // copy page trailer + /* FIL page trailer is also not encrypted */ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END, src_frame + page_size - FIL_PAGE_DATA_END, FIL_PAGE_DATA_END); @@ -772,28 +741,18 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn, // store the post-encryption checksum after the key-version mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum); - } else { - /* Page compressed and encrypted tables have different - FIL_HEADER */ - ulint page_len = log10((double)page_size)/log10((double)2); - /* Set up the correct page type */ - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); - /* Set up the compression algorithm */ - mach_write_to_2(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4, orig_page_type); - /* Set up the compressed size */ - mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6, page_len); - /* Set up the compression method */ - mach_write_to_1(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7, compression_alg); } + srv_stats.pages_encrypted.inc(); } /********************************************************************* -Check if extra buffer shall be allocated for decrypting after read */ +Check if extra buffer shall be allocated for decrypting after read +@return true if fil space has encryption data. */ UNIV_INTERN bool fil_space_check_encryption_read( -/*==============================*/ +/*=============================*/ ulint space) /*!< in: tablespace id */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -806,107 +765,78 @@ fil_space_check_encryption_read( return false; } + if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + return false; + } + return true; } /****************************************************************** -Decrypt a page */ +Decrypt a page +@return true if page was encrypted */ UNIV_INTERN bool -fil_space_decrypt(fil_space_crypt_t* crypt_data, - const byte* src_frame, ulint page_size, byte* dst_frame) +fil_space_decrypt( +/*==============*/ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + const byte* src_frame, /*!< in: input buffer */ + ulint page_size, /*!< in: page size */ + byte* dst_frame) /*!< out: output buffer */ { ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); - // key version - uint key_version; - bool page_encrypted = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED - || page_type == FIL_PAGE_PAGE_ENCRYPTED); + uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED); - bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED - || page_type == FIL_PAGE_PAGE_COMPRESSED); - - ulint orig_page_type=0; - - if (page_type == FIL_PAGE_PAGE_ENCRYPTED) { - key_version = mach_read_from_2( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - orig_page_type = mach_read_from_2( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 2); - } else { - key_version = mach_read_from_4( - src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - } - - if (key_version == 0 && !page_encrypted) { + if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) { //TODO: is this really needed ? memcpy(dst_frame, src_frame, page_size); return false; /* page not decrypted */ } - // read space & offset & lsn + /* read space & offset & lsn */ ulint space = mach_read_from_4( src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); ulint offset = mach_read_from_4( src_frame + FIL_PAGE_OFFSET); ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN); - // copy page header + /* Copy FIL page header, it is not encrypted */ memcpy(dst_frame, src_frame, FIL_PAGE_DATA); - if (page_type == FIL_PAGE_PAGE_ENCRYPTED) { - // orig page type - mach_write_to_2(dst_frame+FIL_PAGE_TYPE, orig_page_type); - } - - // get key + /* Get key */ byte key[MY_AES_MAX_KEY_LENGTH]; uint key_length; - fil_crypt_get_key(key, &key_length, crypt_data, key_version, page_encrypted); - - // get the iv unsigned char iv[MY_AES_BLOCK_SIZE]; + fil_crypt_get_key(key, &key_length, crypt_data, key_version); - if (current_aes_dynamic_method == MY_AES_ALGORITHM_CTR) { - // create counter block - - mach_write_to_4(iv + 0, space); - mach_write_to_4(iv + 4, offset); - mach_write_to_8(iv + 8, lsn); - } else { - // Get random IV from crypt_data - mutex_enter(&crypt_data->mutex); - memcpy(iv, crypt_data->iv, crypt_data->iv_length); - mutex_exit(&crypt_data->mutex); - } + /* create iv/counter */ + mach_write_to_4(iv + 0, space); + mach_write_to_4(iv + 4, offset); + mach_write_to_8(iv + 8, lsn); + /* Calculate the offset where decryption starts */ const byte* src = src_frame + FIL_PAGE_DATA; byte* dst = dst_frame + FIL_PAGE_DATA; - uint32 dstlen; + uint32 dstlen = 0; ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END); - ulint compressed_len; - ulint compression_method; + /* For page compressed tables we decrypt only the actual compressed + payload. Note that first two bytes of page data is actual payload + size and that should not be decrypted. */ if (page_compressed) { - orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4); - compressed_len = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+6); - compression_method = mach_read_from_1(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+7); + ulint compressed_len = mach_read_from_2(src_frame + FIL_PAGE_DATA); + src+=2; + dst+=2; + mach_write_to_2(dst_frame + FIL_PAGE_DATA, compressed_len); + srclen = compressed_len; } - if (page_encrypted && !page_compressed) { - orig_page_type = mach_read_from_2(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+2); - } + int rc = encryption_decrypt(src, srclen, dst, &dstlen, key, key_length, + iv, sizeof(iv), 1, + crypt_data->key_id, key_version); - if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - srclen = pow((double)2, (double)((int)compressed_len)) - FIL_PAGE_DATA; - } - - int rc = (* my_aes_decrypt_dynamic)(src, srclen, - dst, &dstlen, - (unsigned char*)key, key_length, - (unsigned char*)iv, sizeof(iv), - 1); - - if (! ((rc == AES_OK) && ((ulint) dstlen == srclen))) { + if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { ib_logf(IB_LOG_LEVEL_FATAL, "Unable to decrypt data-block " " src: %p srclen: %ld buf: %p buflen: %d." @@ -916,24 +846,22 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data, ut_error; } - if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - // copy page trailer + /* For compressed tables we do not store the FIL header because + the whole page is not stored to the disk. In compressed tables only + the FIL header + compressed (and now encrypted) payload alligned + to sector boundary is written. */ + if (!page_compressed) { + /* Copy FIL trailer */ memcpy(dst_frame + page_size - FIL_PAGE_DATA_END, src_frame + page_size - FIL_PAGE_DATA_END, FIL_PAGE_DATA_END); // clear key-version & crypt-checksum from dst - memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8); - } else { - /* For page compressed tables we set up the FIL_HEADER again */ - /* setting original page type */ - mach_write_to_2(dst_frame + FIL_PAGE_TYPE, orig_page_type); - /* page_compression uses BUF_NO_CHECKSUM_MAGIC as checksum */ - mach_write_to_4(dst_frame + FIL_PAGE_SPACE_OR_CHKSUM, BUF_NO_CHECKSUM_MAGIC); - /* Set up the flush lsn to be compression algorithm */ - mach_write_to_8(dst_frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, compression_method); + memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8); } + srv_stats.pages_decrypted.inc(); + return true; /* page was decrypted */ } @@ -941,8 +869,12 @@ fil_space_decrypt(fil_space_crypt_t* crypt_data, Decrypt a page */ UNIV_INTERN void -fil_space_decrypt(ulint space, - const byte* src_frame, ulint page_size, byte* dst_frame) +fil_space_decrypt( +/*==============*/ + ulint space, /*!< in: Fil space id */ + const byte* src_frame, /*!< in: input buffer */ + ulint page_size, /*!< in: page size */ + byte* dst_frame) /*!< out: output buffer */ { fil_space_decrypt(fil_space_get_crypt_data(space), src_frame, page_size, dst_frame); @@ -953,8 +885,13 @@ Verify checksum for a page (iff it's encrypted) NOTE: currently this function can only be run in single threaded mode as it modifies srv_checksum_algorithm (temporarily) @return true if page is encrypted AND OK, false otherwise */ +UNIV_INTERN bool -fil_space_verify_crypt_checksum(const byte* src_frame, ulint zip_size) +fil_space_verify_crypt_checksum( +/*============================*/ + const byte* src_frame, /*!< in: page the verify */ + ulint zip_size) /*!< in: compressed size if + row_format compressed */ { // key version uint key_version = mach_read_from_4( @@ -1041,12 +978,15 @@ struct key_state_t { Copy global key state */ static void fil_crypt_get_key_state( - key_state_t *new_state) +/*====================*/ + key_state_t *new_state) /*!< out: key state */ { - if (srv_encrypt_tables == TRUE) { - new_state->key_version = get_latest_encryption_key_version(); + if (srv_encrypt_tables) { + new_state->key_version = + encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; - ut_a(new_state->key_version > 0); + ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID); + ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED); } else { new_state->key_version = 0; new_state->rotate_key_age = 0; @@ -1054,9 +994,13 @@ fil_crypt_get_key_state( } /*********************************************************************** -Check if a key needs rotation given a key_state */ +Check if a key needs rotation given a key_state +@return true if key needs rotation, false if not */ static bool -fil_crypt_needs_rotation(uint key_version, const key_state_t *key_state) +fil_crypt_needs_rotation( +/*=====================*/ + uint key_version, /*!< in: Key version */ + const key_state_t* key_state) /*!< in: Key state */ { // TODO(jonaso): Add support for rotating encrypted => unencrypted @@ -1081,9 +1025,13 @@ fil_crypt_needs_rotation(uint key_version, const key_state_t *key_state) } /*********************************************************************** -Check if a space is closing (i.e just before drop) */ -UNIV_INTERN bool -fil_crypt_is_closing(ulint space) +Check if a space is closing (i.e just before drop) +@return true if space is closing, false if not. */ +UNIV_INTERN +bool +fil_crypt_is_closing( +/*=================*/ + ulint space) /*!< in: FIL space id */ { bool closing; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -1097,8 +1045,13 @@ fil_crypt_is_closing(ulint space) Start encrypting a space @return true if a pending op (fil_inc_pending_ops/fil_decr_pending_ops) is held */ -static bool -fil_crypt_start_encrypting_space(ulint space, bool *recheck) { +static +bool +fil_crypt_start_encrypting_space( +/*=============================*/ + ulint space, /*!< in: FIL space id */ + bool* recheck)/*!< out: true if recheck needed */ +{ /* we have a pending op when entering function */ bool pending_op = true; @@ -1106,7 +1059,7 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); - ibool page_encrypted = fil_space_is_page_encrypted(space); + ibool page_encrypted = (crypt_data != NULL); /*If spage is not encrypted and encryption is not enabled, then do not continue encrypting the space. */ @@ -1131,7 +1084,7 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { * crypt data in page 0 */ /* 1 - create crypt data */ - crypt_data = fil_space_create_crypt_data(); + crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY); if (crypt_data == NULL) { mutex_exit(&fil_crypt_threads_mutex); return pending_op; @@ -1257,10 +1210,14 @@ fil_crypt_start_encrypting_space(ulint space, bool *recheck) { } /*********************************************************************** -Check if space needs rotation given a key_state */ -static bool -fil_crypt_space_needs_rotation(uint space, const key_state_t *key_state, - bool *recheck) +Check if space needs rotation given a key_state +@return true if space needs key rotation */ +static +bool +fil_crypt_space_needs_rotation( + uint space, /*!< in: FIL space id */ + const key_state_t* key_state, /*!< in: Key state */ + bool* recheck) /*!< out: needs recheck ? */ { if (fil_space_get_type(space) != FIL_TABLESPACE) { return false; @@ -1296,6 +1253,11 @@ fil_crypt_space_needs_rotation(uint space, const key_state_t *key_state, mutex_enter(&crypt_data->mutex); do { + if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) { + /* This space is unencrypted by user request */ + break; + } + /* prevent threads from starting to rotate space */ if (crypt_data->rotate_state.starting) { /* recheck this space later */ @@ -1374,7 +1336,9 @@ struct rotate_thread_t { /*********************************************************************** Update global statistics with thread statistics */ static void -fil_crypt_update_total_stat(rotate_thread_t *state) +fil_crypt_update_total_stat( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { mutex_enter(&crypt_stat_mutex); crypt_stat.pages_read_from_cache += @@ -1397,9 +1361,13 @@ fil_crypt_update_total_stat(rotate_thread_t *state) /*********************************************************************** Allocate iops to thread from global setting, -used before starting to rotate a space */ -static bool -fil_crypt_alloc_iops(rotate_thread_t *state) +used before starting to rotate a space. +@return true if allocation succeeded, false if failed */ +static +bool +fil_crypt_alloc_iops( +/*=================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { ut_ad(state->allocated_iops == 0); @@ -1429,8 +1397,11 @@ fil_crypt_alloc_iops(rotate_thread_t *state) /*********************************************************************** Reallocate iops to thread, used when inside a space */ -static void -fil_crypt_realloc_iops(rotate_thread_t *state) +static +void +fil_crypt_realloc_iops( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { ut_a(state->allocated_iops > 0); @@ -1519,8 +1490,11 @@ fil_crypt_realloc_iops(rotate_thread_t *state) /*********************************************************************** Return allocated iops to global */ -static void -fil_crypt_return_iops(rotate_thread_t *state) +static +void +fil_crypt_return_iops( +/*========================*/ + rotate_thread_t *state) /*!< in: Key rotation status */ { if (state->allocated_iops > 0) { uint iops = state->allocated_iops; @@ -1544,11 +1518,14 @@ fil_crypt_return_iops(rotate_thread_t *state) /*********************************************************************** Search for a space needing rotation */ +UNIV_INTERN bool fil_crypt_find_space_to_rotate( - const key_state_t *key_state, - rotate_thread_t *state, - bool *recheck) +/*===========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state, /*!< in: Key rotation state */ + bool* recheck) /*!< out: true if recheck + needed */ { /* we need iops to start rotating */ while (!state->should_shutdown() && !fil_crypt_alloc_iops(state)) { @@ -1591,8 +1568,9 @@ Start rotating a space */ static void fil_crypt_start_rotate_space( - const key_state_t *key_state, - rotate_thread_t *state) +/*=========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -1629,12 +1607,14 @@ fil_crypt_start_rotate_space( } /*********************************************************************** -Search for batch of pages needing rotation */ +Search for batch of pages needing rotation +@return true if page needing key rotation found, false if not found */ static bool fil_crypt_find_page_to_rotate( - const key_state_t *key_state, - rotate_thread_t *state) +/*==========================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint batch = srv_alloc_time * state->allocated_iops; ulint space = state->space; @@ -1665,9 +1645,15 @@ fil_crypt_find_page_to_rotate( } /*********************************************************************** -Check if a page is uninitialized (doesn't need to be rotated) */ -static bool -fil_crypt_is_page_uninitialized(const byte* frame, uint zip_size) +Check if a page is uninitialized (doesn't need to be rotated) +@return true if page is uninitialized, false if not.*/ +static +bool +fil_crypt_is_page_uninitialized( +/*============================*/ + const byte *frame, /*!< in: Page */ + uint zip_size) /*!< in: compressed size if + row_format compressed */ { if (zip_size) { ulint stored_checksum = mach_read_from_4( @@ -1696,15 +1682,20 @@ fil_crypt_is_page_uninitialized(const byte* frame, uint zip_size) sleeptime_ms, __FILE__, __LINE__) /*********************************************************************** -Get a page and compute sleep time */ +Get a page and compute sleep time +@return page */ static buf_block_t* -fil_crypt_get_page_throttle_func(rotate_thread_t *state, - ulint space, uint zip_size, ulint offset, - mtr_t *mtr, - ulint *sleeptime_ms, - const char *file, - ulint line) +fil_crypt_get_page_throttle_func( + rotate_thread_t* state, /*!< in/out: Key rotation state */ + ulint space, /*!< in: FIL space id */ + uint zip_size, /*!< in: compressed size if + row_format compressed */ + ulint offset, /*!< in: page offsett */ + mtr_t* mtr, /*!< in/out: minitransaction */ + ulint* sleeptime_ms, /*!< out: sleep time */ + const char* file, /*!< in: file name */ + ulint line) /*!< in: file line */ { buf_block_t* block = buf_page_try_get_func(space, offset, RW_X_LATCH, true, @@ -1753,17 +1744,22 @@ Get block and allocation status note: innodb locks fil_space_latch and then block when allocating page but locks block and then fil_space_latch when freeing page. +@return block */ static buf_block_t* btr_scrub_get_block_and_allocation_status( - rotate_thread_t *state, - ulint space, - ulint zip_size, - ulint offset, - mtr_t *mtr, +/*======================================*/ + rotate_thread_t* state, /*!< in/out: Key rotation state */ + ulint space, /*!< in: FIL space id */ + uint zip_size, /*!< in: compressed size if + row_format compressed */ + ulint offset, /*!< in: page offsett */ + mtr_t* mtr, /*!< in/out: minitransaction + */ btr_scrub_page_allocation_status_t *allocation_status, - ulint *sleeptime_ms) + /*!< in/out: allocation status */ + ulint* sleeptime_ms) /*!< out: sleep time */ { mtr_t local_mtr; buf_block_t *block = NULL; @@ -1807,8 +1803,9 @@ Rotate one page */ static void fil_crypt_rotate_page( - const key_state_t *key_state, - rotate_thread_t *state) +/*===================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; ulint offset = state->offset; @@ -1960,8 +1957,9 @@ Rotate a batch of pages */ static void fil_crypt_rotate_pages( - const key_state_t *key_state, - rotate_thread_t *state) +/*===================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; ulint end = state->offset + state->batch; @@ -1989,7 +1987,10 @@ fil_crypt_rotate_pages( Flush rotated pages and then update page 0 */ static void -fil_crypt_flush_space(rotate_thread_t *state, ulint space) +fil_crypt_flush_space( +/*==================*/ + rotate_thread_t* state, /*!< in: Key rotation state */ + ulint space) /*!< in: FIL space id */ { fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -2033,9 +2034,10 @@ fil_crypt_flush_space(rotate_thread_t *state, ulint space) RW_X_LATCH, NULL, BUF_GET, __FILE__, __LINE__, &mtr); byte* frame = buf_block_get_frame(block); - ulint maxsize = 0; + ulint maxsize; crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); + fil_space_write_crypt_data(space, frame, crypt_data->page0_offset, ULINT_MAX, &mtr); @@ -2048,8 +2050,9 @@ Complete rotating a space */ static void fil_crypt_complete_rotate_space( - const key_state_t *key_state, - rotate_thread_t *state) +/*============================*/ + const key_state_t* key_state, /*!< in: Key state */ + rotate_thread_t* state) /*!< in: Key rotation state */ { ulint space = state->space; fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); @@ -2123,7 +2126,7 @@ A thread which monitors global key state and rotates tablespaces accordingly extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(fil_crypt_thread)( -/*===============================*/ +/*=============================*/ void* arg __attribute__((unused))) /*!< in: a dummy parameter required * by os_thread_create */ { @@ -2240,13 +2243,19 @@ DECLARE_THREAD(fil_crypt_thread)( Adjust thread count for key rotation */ UNIV_INTERN void -fil_crypt_set_thread_cnt(uint new_cnt) +fil_crypt_set_thread_cnt( +/*=====================*/ + uint new_cnt) /*!< in: New key rotation thread count */ { if (new_cnt > srv_n_fil_crypt_threads) { uint add = new_cnt - srv_n_fil_crypt_threads; srv_n_fil_crypt_threads = new_cnt; for (uint i = 0; i < add; i++) { - os_thread_create(fil_crypt_thread, NULL, NULL); + os_thread_id_t rotation_thread_id; + os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); + ib_logf(IB_LOG_LEVEL_INFO, + "Creating #%d thread id %lu total threads %du\n", + i, os_thread_pf(rotation_thread_id), new_cnt); } } else if (new_cnt < srv_n_fil_crypt_threads) { srv_n_fil_crypt_threads = new_cnt; @@ -2263,7 +2272,9 @@ fil_crypt_set_thread_cnt(uint new_cnt) Adjust max key age */ UNIV_INTERN void -fil_crypt_set_rotate_key_age(uint val) +fil_crypt_set_rotate_key_age( +/*=========================*/ + uint val) /*!< in: New max key age */ { srv_fil_crypt_rotate_key_age = val; os_event_set(fil_crypt_threads_event); @@ -2273,7 +2284,9 @@ fil_crypt_set_rotate_key_age(uint val) Adjust rotation iops */ UNIV_INTERN void -fil_crypt_set_rotation_iops(uint val) +fil_crypt_set_rotation_iops( +/*========================*/ + uint val) /*!< in: New iops setting */ { srv_n_fil_crypt_iops = val; os_event_set(fil_crypt_threads_event); @@ -2284,6 +2297,7 @@ Init threads for key rotation */ UNIV_INTERN void fil_crypt_threads_init() +/*====================*/ { fil_crypt_event = os_event_create(); fil_crypt_threads_event = os_event_create(); @@ -2300,6 +2314,7 @@ End threads for key rotation */ UNIV_INTERN void fil_crypt_threads_end() +/*===================*/ { /* stop threads */ fil_crypt_set_thread_cnt(0); @@ -2309,7 +2324,9 @@ fil_crypt_threads_end() Clean up key rotation threads resources */ UNIV_INTERN void -fil_crypt_threads_cleanup() { +fil_crypt_threads_cleanup() +/*=======================*/ +{ os_event_free(fil_crypt_event); os_event_free(fil_crypt_threads_event); } @@ -2319,7 +2336,8 @@ Mark a space as closing */ UNIV_INTERN void fil_space_crypt_mark_space_closing( - ulint space) +/*===============================*/ + ulint space) /*!< in: Space id */ { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -2340,7 +2358,8 @@ Wait for crypt threads to stop accessing space */ UNIV_INTERN void fil_space_crypt_close_tablespace( - ulint space) +/*=============================*/ + ulint space) /*!< in: Space id */ { mutex_enter(&fil_crypt_threads_mutex); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -2352,11 +2371,14 @@ fil_space_crypt_close_tablespace( uint start = time(0); uint last = start; + mutex_enter(&crypt_data->mutex); mutex_exit(&fil_crypt_threads_mutex); crypt_data->closing = true; + uint cnt = crypt_data->rotate_state.active_threads; bool flushing = crypt_data->rotate_state.flushing; + while (cnt > 0 || flushing) { mutex_exit(&crypt_data->mutex); /* release dict mutex so that scrub threads can release their @@ -2386,11 +2408,12 @@ fil_space_crypt_close_tablespace( /********************************************************************* Get crypt status for a space (used by information_schema) return 0 if crypt data present */ +UNIV_INTERN int fil_space_crypt_get_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_crypt_status_t* status) /*!< out: status */ +/*=======================*/ + ulint id, /*!< in: space id */ + struct fil_space_crypt_status_t* status) /*!< out: status */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(id); @@ -2400,6 +2423,7 @@ fil_space_crypt_get_status( mutex_enter(&crypt_data->mutex); status->keyserver_requests = crypt_data->keyserver_requests; status->min_key_version = crypt_data->min_key_version; + if (crypt_data->rotate_state.active_threads > 0 || crypt_data->rotate_state.flushing) { status->rotating = true; @@ -2413,22 +2437,27 @@ fil_space_crypt_get_status( status->rotating = false; } mutex_exit(&crypt_data->mutex); + + if (srv_encrypt_tables) { + status->current_key_version = + encryption_key_get_latest_version(crypt_data->key_id); + } else { + status->current_key_version = 0; + } } else { memset(status, 0, sizeof(*status)); } - if (srv_encrypt_tables == TRUE) { - status->current_key_version = get_latest_encryption_key_version(); - } else { - status->current_key_version = 0; - } return crypt_data == NULL ? 1 : 0; } /********************************************************************* Return crypt statistics */ +UNIV_INTERN void -fil_crypt_total_stat(fil_crypt_stat_t *stat) +fil_crypt_total_stat( +/*=================*/ + fil_crypt_stat_t *stat) /*!< out: Crypt statistics */ { mutex_enter(&crypt_stat_mutex); *stat = crypt_stat; @@ -2438,11 +2467,12 @@ fil_crypt_total_stat(fil_crypt_stat_t *stat) /********************************************************************* Get scrub status for a space (used by information_schema) return 0 if data found */ +UNIV_INTERN int fil_space_get_scrub_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_scrub_status_t* status) /*!< out: status */ +/*=======================*/ + ulint id, /*!< in: space id */ + struct fil_space_scrub_status_t* status) /*!< out: status */ { fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(id); memset(status, 0, sizeof(*status)); diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 14878f59f7d..5cb4c071eb0 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -27,8 +27,7 @@ Created 10/25/1995 Heikki Tuuri #include "fil0fil.h" #include "fil0pagecompress.h" #include "fsp0pagecompress.h" -#include "fil0pageencryption.h" -#include "fsp0pageencryption.h" +#include "fil0crypt.h" #include #include @@ -287,7 +286,7 @@ fil_read( actual page size does not decrease. */ { return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset, - byte_offset, len, buf, message, write_size, 0, false)); + byte_offset, len, buf, message, write_size)); } /********************************************************************//** @@ -314,18 +313,16 @@ fil_write( this must be appropriately aligned */ void* message, /*!< in: message for aio handler if non-sync aio used, else ignored */ - ulint* write_size, /*!< in/out: Actual write size initialized + ulint* write_size) /*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: encrypt later ? */ { ut_ad(!srv_read_only_mode); return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset, - byte_offset, len, buf, message, write_size, lsn, encrypt_later)); + byte_offset, len, buf, message, write_size)); } /*******************************************************************//** @@ -651,22 +648,7 @@ fil_node_open_file( set */ page = static_cast(ut_align(buf2, UNIV_PAGE_SIZE)); - success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE, - space->flags); - - if (fil_page_encryption_status(page)) { - /* if page is (still) encrypted, write an error and return. - * Otherwise the server would crash if decrypting is not possible. - * This may be the case, if the key file could not be - * opened on server startup. - */ - ib_logf(IB_LOG_LEVEL_ERROR, - "InnoDB: can not decrypt page, because " - "keys could not be read.\n" - ); - return false; - - } + success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); space_id = fsp_header_get_space_id(page); flags = fsp_header_get_flags(page); @@ -1191,21 +1173,6 @@ fil_space_create( ut_a(fil_system); - if (fsp_flags_is_page_encrypted(flags)) { - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - /* by returning here it should be avoided that - * the server crashes, if someone tries to access an - * encrypted table and the encryption key is not available. - * The the table is treaded as non-existent. - */ - ib_logf(IB_LOG_LEVEL_WARN, - "Tablespace '%s' can not be opened, because " - " encryption key can not be found (space id: %lu, key %lu)\n" - , name, (ulong) id, fsp_flags_get_page_encryption_key(flags)); - return (FALSE); - } - } - /* Look for a matching tablespace and if found free it. */ do { mutex_enter(&fil_system->mutex); @@ -1879,7 +1846,7 @@ fil_write_lsn_and_arch_no_to_file( lsn); err = fil_write(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0, 0, false); + UNIV_PAGE_SIZE, buf, NULL, 0); } mem_free(buf1); @@ -1958,7 +1925,6 @@ fil_check_first_page( { ulint space_id; ulint flags; - ulint page_is_encrypted; if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { return(NULL); @@ -1966,23 +1932,14 @@ fil_check_first_page( space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page); flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - /* Note: the 1st page is usually not encrypted. If the Key Provider - or the encryption key is not available, the - check for reading the first page should intentionally fail - with "can not decrypt" message. */ - page_is_encrypted = fil_page_encryption_status(page); - if (page_is_encrypted == PAGE_ENCRYPTION_KEY_MISSING && page_is_encrypted) { - page_is_encrypted = 1; - } else { - page_is_encrypted = 0; - if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { - fprintf(stderr, - "InnoDB: Error: Current page size %lu != " - " page size on page %lu\n", - UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags)); - return("innodb-page-size mismatch"); - } + if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { + fprintf(stderr, + "InnoDB: Error: Current page size %lu != " + " page size on page %lu\n", + UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags)); + + return("innodb-page-size mismatch"); } if (!space_id && !flags) { @@ -1998,17 +1955,9 @@ fil_check_first_page( } } - if (!page_is_encrypted && buf_page_is_corrupted( + if (buf_page_is_corrupted( false, page, fsp_flags_get_zip_size(flags))) { return("checksum mismatch"); - } else { - if (page_is_encrypted) { - /* this error message is interpreted by the calling method, which is - * executed if the server starts in recovery mode. - */ - return(MSG_CANNOT_DECRYPT); - - } } if (page_get_space_id(page) == space_id @@ -2046,6 +1995,7 @@ fil_read_first_page( byte* page; lsn_t flushed_lsn; const char* check_msg = NULL; + fil_space_crypt_t* cdata; buf = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); @@ -2053,10 +2003,7 @@ fil_read_first_page( page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); - os_file_read(data_file, page, 0, UNIV_PAGE_SIZE, - orig_space_id != ULINT_UNDEFINED ? - fil_space_is_page_compressed(orig_space_id) : - FALSE); + os_file_read(data_file, page, 0, UNIV_PAGE_SIZE); /* The FSP_HEADER on page 0 is only valid for the first file in a tablespace. So if this is not the first datafile, leave @@ -2067,13 +2014,6 @@ fil_read_first_page( *space_id = fsp_header_get_space_id(page); } - /* Page is page compressed page, need to decompress, before - continue. */ - if (fil_page_is_compressed(page)) { - ulint write_size=0; - fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, &write_size); - } - if (!one_read_already) { check_msg = fil_check_first_page(page); } @@ -2081,12 +2021,30 @@ fil_read_first_page( flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + + ulint space = fsp_header_get_space_id(page); + ulint offset = fsp_header_get_crypt_offset( + fsp_flags_get_zip_size(*flags), NULL); + cdata = fil_space_read_crypt_data(space, page, offset); + + /* If file space is encrypted we need to have at least some + encryption service available where to get keys */ + if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) || + (srv_encrypt_tables && + cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { + uint rc = encryption_key_get_latest_version(cdata->key_id); + + if (rc == ENCRYPTION_KEY_VERSION_INVALID) { + ib_logf(IB_LOG_LEVEL_FATAL, + "Tablespace id %ld encrypted but encryption service" + " not available. Can't continue opening tablespace.\n", + space); + ut_error; + } + } + if (crypt_data) { - ulint space = fsp_header_get_space_id(page); - ulint offset = - fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(*flags), NULL); - *crypt_data = fil_space_read_crypt_data(space, page, offset); + *crypt_data = cdata; } ut_free(buf); @@ -3551,7 +3509,7 @@ fil_create_new_single_table_tablespace( } success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE, - fil_space_create_crypt_data()); + fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY)); if (!success || !fil_node_create(path, size, space_id, FALSE)) { err = DB_ERROR; @@ -4106,8 +4064,7 @@ fil_user_tablespace_find_space_id( for (ulint j = 0; j < page_count; ++j) { - st = os_file_read(fsp->file, page, (j* page_size), page_size, - fsp_flags_is_page_compressed(fsp->flags)); + st = os_file_read(fsp->file, page, (j* page_size), page_size); if (!st) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4242,7 +4199,6 @@ fil_validate_single_table_tablespace( check_first_page: fsp->success = TRUE; - fsp->encryption_error = 0; if (const char* check_msg = fil_read_first_page( fsp->file, FALSE, &fsp->flags, &fsp->id, &fsp->lsn, &fsp->lsn, ULINT_UNDEFINED, &fsp->crypt_data)) { @@ -4250,14 +4206,6 @@ check_first_page: "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); fsp->success = FALSE; - if (strncmp(check_msg, MSG_CANNOT_DECRYPT, strlen(check_msg))==0) { - /* by returning here, it should be avoided, that the server crashes, - * if started in recovery mode and can not decrypt tables, if - * the key file can not be read. - */ - fsp->encryption_error = 1; - return; - } } if (!fsp->success) { @@ -4412,13 +4360,6 @@ fil_load_single_table_tablespace( if (!def.success && !remote.success) { - if (def.encryption_error || remote.encryption_error) { - fprintf(stderr, - "InnoDB: Error: could not open single-table" - " tablespace file %s. Encryption error!\n", def.filepath); - return; - } - /* The following call prints an error message */ os_file_get_last_error(true); fprintf(stderr, @@ -5258,7 +5199,7 @@ retry: success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC, node->name, node->handle, buf, offset, page_size * n_pages, - node, NULL, space_id, NULL, 0, 0, 0, 0, 0, 0, false); + node, NULL, space_id, NULL, 0); #endif /* UNIV_HOTBACKUP */ DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", @@ -5605,6 +5546,74 @@ fil_report_invalid_page_access( (ulong) byte_offset, (ulong) len, (ulong) type); } +/********************************************************************//** +Find correct node from file space +@return node */ +static +fil_node_t* +fil_space_get_node( + fil_space_t* space, /*!< in: file spage */ + ulint space_id, /*!< in: space id */ + ulint* block_offset, /*!< in/out: offset in number of blocks */ + ulint byte_offset, /*!< in: remainder of offset in bytes; in + aio this must be divisible by the OS block + size */ + ulint len) /*!< in: how many bytes to read or write; this + must not cross a file boundary; in aio this + must be a block size multiple */ +{ + fil_node_t* node; + ut_ad(mutex_own(&fil_system->mutex)); + + node = UT_LIST_GET_FIRST(space->chain); + + for (;;) { + if (node == NULL) { + return(NULL); + } else if (fil_is_user_tablespace_id(space->id) + && node->size == 0) { + + /* We do not know the size of a single-table tablespace + before we open the file */ + break; + } else if (node->size > *block_offset) { + /* Found! */ + break; + } else { + *block_offset -= node->size; + node = UT_LIST_GET_NEXT(chain, node); + } + } + + return (node); +} +/********************************************************************//** +Return block size of node in file space +@return file block size */ +UNIV_INTERN +ulint +fil_space_get_block_size( +/*=====================*/ + ulint space_id, + ulint block_offset, + ulint len) +{ + ulint block_size = 512; + fil_space_t* space = fil_space_get_space(space_id); + + if (space) { + mutex_enter(&fil_system->mutex); + fil_node_t* node = fil_space_get_node(space, space_id, &block_offset, 0, len); + mutex_exit(&fil_system->mutex); + + if (node) { + block_size = node->file_block_size; + } + } + + return block_size; +} + /********************************************************************//** Reads or writes data. This operation is asynchronous (aio). @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do @@ -5643,9 +5652,7 @@ _fil_io( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - trx_t* trx, - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: encrypt later ? */ + trx_t* trx) { ulint mode; fil_space_t* space; @@ -5654,11 +5661,7 @@ _fil_io( ulint is_log; ulint wake_later; os_offset_t offset; - ibool ignore_nonexistent_pages; - ibool page_compressed = FALSE; - ulint page_compression_level = 0; - ibool page_encrypted; - ulint page_encryption_key; + bool ignore_nonexistent_pages; is_log = type & OS_FILE_LOG; type = type & ~OS_FILE_LOG; @@ -5726,13 +5729,6 @@ _fil_io( space = fil_space_get_by_id(space_id); - page_compressed = fsp_flags_is_page_compressed(space->flags); - page_compression_level = fsp_flags_get_page_compression_level(space->flags); - - page_encrypted = fsp_flags_is_page_encrypted(space->flags); - page_encryption_key = fsp_flags_get_page_encryption_key(space->flags); - - /* If we are deleting a tablespace we don't allow any read operations on that. However, we do allow write operations. */ if (space == 0 || (type == OS_FILE_READ && space->stop_new_ops)) { @@ -5750,34 +5746,18 @@ _fil_io( ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE); - node = UT_LIST_GET_FIRST(space->chain); + node = fil_space_get_node(space, space_id, &block_offset, byte_offset, len); - for (;;) { - if (node == NULL) { - if (ignore_nonexistent_pages) { - mutex_exit(&fil_system->mutex); - return(DB_ERROR); - } - - fil_report_invalid_page_access( + if (!node) { + if (ignore_nonexistent_pages) { + mutex_exit(&fil_system->mutex); + return(DB_ERROR); + } + fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - ut_error; - - } else if (fil_is_user_tablespace_id(space->id) - && node->size == 0) { - - /* We do not know the size of a single-table tablespace - before we open the file */ - break; - } else if (node->size > block_offset) { - /* Found! */ - break; - } else { - block_offset -= node->size; - node = UT_LIST_GET_NEXT(chain, node); - } + ut_error; } /* Open file if closed */ @@ -5889,13 +5869,7 @@ _fil_io( message, space_id, trx, - page_compressed, - page_compression_level, - write_size, - page_encrypted, - page_encryption_key, - lsn, - encrypt_later); + write_size); #else /* In mysqlbackup do normal i/o, not aio */ @@ -6454,9 +6428,7 @@ fil_iterate( readptr = iter.crypt_io_buffer; } - if (!os_file_read(iter.file, readptr, offset, - (ulint) n_bytes, - fil_space_is_page_compressed(space_id))) { + if (!os_file_read(iter.file, readptr, offset, (ulint) n_bytes)) { ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed"); @@ -6607,8 +6579,7 @@ fil_tablespace_iterate( /* Read the first page and determine the page and zip size. */ - if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE, - dict_tf_get_page_compression(table->flags))) { + if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) { err = DB_IO_ERROR; @@ -6668,7 +6639,7 @@ fil_tablespace_iterate( if (iter.crypt_data != NULL) { /* clear crypt data from page 0 and write it back */ - os_file_read(file, page, 0, UNIV_PAGE_SIZE, 0); + os_file_read(file, page, 0, UNIV_PAGE_SIZE); fil_space_clear_crypt_data(page, crypt_data_offset); lsn_t lsn = mach_read_from_8(page + FIL_PAGE_LSN); if (callback.get_zip_size() == 0) { @@ -6915,79 +6886,6 @@ fil_system_exit(void) mutex_exit(&fil_system->mutex); } -/*******************************************************************//** -Return space name */ -char* -fil_space_name( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->name); -} - -/*******************************************************************//** -Return space flags */ -ulint -fil_space_flags( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->flags); -} - -/*******************************************************************//** -Return page type name */ -const char* -fil_get_page_type_name( -/*===================*/ - ulint page_type) /*!< in: FIL_PAGE_TYPE */ -{ - switch(page_type) { - case FIL_PAGE_PAGE_COMPRESSED: - return (const char*)"PAGE_COMPRESSED"; - case FIL_PAGE_INDEX: - return (const char*)"INDEX"; - case FIL_PAGE_UNDO_LOG: - return (const char*)"UNDO LOG"; - case FIL_PAGE_INODE: - return (const char*)"INODE"; - case FIL_PAGE_IBUF_FREE_LIST: - return (const char*)"IBUF_FREE_LIST"; - case FIL_PAGE_TYPE_ALLOCATED: - return (const char*)"ALLOCATED"; - case FIL_PAGE_IBUF_BITMAP: - return (const char*)"IBUF_BITMAP"; - case FIL_PAGE_TYPE_SYS: - return (const char*)"SYS"; - case FIL_PAGE_TYPE_TRX_SYS: - return (const char*)"TRX_SYS"; - case FIL_PAGE_TYPE_FSP_HDR: - return (const char*)"FSP_HDR"; - case FIL_PAGE_TYPE_XDES: - return (const char*)"XDES"; - case FIL_PAGE_TYPE_BLOB: - return (const char*)"BLOB"; - case FIL_PAGE_TYPE_ZBLOB: - return (const char*)"ZBLOB"; - case FIL_PAGE_TYPE_ZBLOB2: - return (const char*)"ZBLOB2"; - case FIL_PAGE_TYPE_COMPRESSED: - return (const char*)"ORACLE PAGE COMPRESSED"; - default: - return (const char*)"PAGE TYPE CORRUPTED"; - } -} -/****************************************************************//** -Get block size from fil node -@return block size*/ -ulint -fil_node_get_block_size( -/*====================*/ - fil_node_t* node) /*!< in: Node where to get block - size */ -{ - return (node->file_block_size); -} /****************************************************************** Get id of first tablespace or ULINT_UNDEFINED if none */ diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc index 3c2edd832c4..d394ca5215c 100644 --- a/storage/xtradb/fil/fil0pagecompress.cc +++ b/storage/xtradb/fil/fil0pagecompress.cc @@ -83,173 +83,6 @@ static ulint srv_data_read, srv_data_written; /* Used for debugging */ //#define UNIV_PAGECOMPRESS_DEBUG 1 -/****************************************************************//** -For page compressed pages decompress the page after actual read -operation. */ -static -void -fil_decompress_page_2( -/*==================*/ - byte* page_buf, /*!< out: destination buffer for - uncompressed data */ - byte* buf, /*!< in: source compressed data */ - ulong len, /*!< in: length of output buffer.*/ - ulint* write_size) /*!< in/out: Actual payload size of - the compressed data. */ -{ - ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - - if (page_type != FIL_PAGE_TYPE_COMPRESSED) { - /* It is not a compressed page */ - return; - } - - byte* ptr = buf + FIL_PAGE_DATA; - ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION); - int err = 0; - - ut_a(version == 1); - - /* Read the original page type, before we compressed the data. */ - page_type = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_TYPE_V1); - - ulint original_len = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_SIZE_V1); - - if (original_len < UNIV_PAGE_SIZE_MIN - (FIL_PAGE_DATA + 8) - || original_len > UNIV_PAGE_SIZE_MAX - FIL_PAGE_DATA - || len < original_len + FIL_PAGE_DATA) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: We try to uncompress corrupted page. " - "Original len %lu len %lu.", - original_len, len); - - fflush(stderr); - ut_error; - - } - - ulint algorithm = mach_read_from_1(buf + FIL_PAGE_ALGORITHM_V1); - - switch(algorithm) { - case PAGE_ZLIB_ALGORITHM: { - - err = uncompress(page_buf, &len, ptr, original_len); - - /* If uncompress fails it means that page is corrupted */ - if (err != Z_OK) { - - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed " - "but uncompress failed with error %d " - " size %lu len %lu.", - err, original_len, len); - - fflush(stderr); - - ut_error; - } - - break; - } -#ifdef HAVE_LZ4 - case PAGE_LZ4_ALGORITHM: { - - err = LZ4_decompress_fast( - (const char*) ptr, (char*) (page_buf), original_len); - - if (err < 0) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %d bytes" - " size %lu len %lu.", - err, original_len, len); - fflush(stderr); - - ut_error; - } - break; - } -#endif /* HAVE_LZ4 */ - -#ifdef HAVE_LZMA - case PAGE_LZMA_ALGORITHM: { - - lzma_ret ret; - size_t src_pos = 0; - size_t dst_pos = 0; - uint64_t memlimit = UINT64_MAX; - - ret = lzma_stream_buffer_decode( - &memlimit, - 0, - NULL, - ptr, - &src_pos, - original_len, - (page_buf), - &dst_pos, - len); - - - if (ret != LZMA_OK || (dst_pos <= 0 || dst_pos > len)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %ld bytes" - " size %lu len %lu.", - dst_pos, original_len, len); - fflush(stderr); - - ut_error; - } - - break; - } -#endif /* HAVE_LZMA */ - -#ifdef HAVE_LZO - case PAGE_LZO_ALGORITHM: { - ulint olen = 0; - - err = lzo1x_decompress((const unsigned char *)ptr, - original_len,(unsigned char *)(page_buf), &olen, NULL); - - if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Corruption: Page is marked as compressed" - " but decompression read only %ld bytes" - " size %lu len %lu.", - olen, original_len, len); - - fflush(stderr); - - ut_error; - } - break; - } -#endif /* HAVE_LZO */ - - default: - ib_logf(IB_LOG_LEVEL_ERROR, - " Corruption: Page is marked as compressed " - " but compression algorithm %s" - " is not known." - ,fil_get_compression_alg_name(algorithm)); - - fflush(stderr); - ut_error; - break; - } - - /* Leave the header alone */ - memmove(buf+FIL_PAGE_DATA, page_buf, original_len); - - mach_write_to_2(buf + FIL_PAGE_TYPE, page_type); - - ut_ad(memcmp(buf + FIL_PAGE_LSN + 4, - buf + (original_len + FIL_PAGE_DATA) - - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4) == 0); -} - /****************************************************************//** For page compressed pages compress the page before actual write operation. @@ -270,7 +103,7 @@ fil_compress_page( byte* lzo_mem) /*!< in: temporal memory used by LZO */ { int err = Z_OK; - int level = 0; + int level = compression_level; ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; ulint write_size=0; /* Cache to avoid change during function execution */ @@ -290,15 +123,11 @@ fil_compress_page( if (orig_page_type == 0 || orig_page_type == FIL_PAGE_TYPE_FSP_HDR || orig_page_type == FIL_PAGE_TYPE_XDES || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { + orig_page_type == FIL_PAGE_PAGE_COMPRESSED) { *out_len = len; return (buf); } - level = compression_level; - ut_ad(fil_space_is_page_compressed(space_id)); - fil_system_enter(); fil_space_t* space = fil_space_get_by_id(space_id); fil_system_exit(); @@ -577,16 +406,6 @@ fil_decompress_page( in_buf = page_buf; } - if (ptype == FIL_PAGE_TYPE_COMPRESSED) { - - fil_decompress_page_2(in_buf, buf, len, write_size); - // Need to free temporal buffer if no buffer was given - if (page_buf == NULL) { - ut_free(in_buf); - } - return; - } - /* Before actual decompress, make sure that page type is correct */ if (mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) != BUF_NO_CHECKSUM_MAGIC || diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index 0fffe60253e..34acab04241 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -31,6 +31,7 @@ Created 11/29/1995 Heikki Tuuri #include "buf0buf.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "mtr0log.h" #include "ut0byte.h" #include "page0page.h" diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 5cc232a3b35..aeb3e4fb5c1 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -81,6 +81,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fsp0fsp.h" #include "sync0sync.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "trx0xa.h" #include "row0merge.h" #include "dict0boot.h" @@ -106,7 +107,6 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fts0priv.h" #include "page0zip.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X)) @@ -246,7 +246,6 @@ static char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; -extern my_bool srv_encrypt_tables; extern uint srv_n_fil_crypt_threads; extern uint srv_fil_crypt_rotate_key_age; extern uint srv_n_fil_crypt_iops; @@ -613,6 +612,11 @@ ib_cb_t innodb_api_cb[] = { (ib_cb_t) ib_cursor_stmt_begin }; +static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG, + "Default encryption key id used for table encryption.", + NULL, NULL, + FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0); + /** Structure for CREATE TABLE options (table options). It needs to be called ha_table_option_struct. @@ -631,10 +635,10 @@ ha_create_table_option innodb_table_option_list[]= HA_TOPTION_NUMBER("PAGE_COMPRESSION_LEVEL", page_compression_level, 0, 1, 9, 1), /* With this option user can enable atomic writes feature for this table */ HA_TOPTION_ENUM("ATOMIC_WRITES", atomic_writes, "DEFAULT,ON,OFF", 0), - /* With this option the user can enable page encryption for the table */ - HA_TOPTION_BOOL("PAGE_ENCRYPTION", page_encryption, 0), + /* With this option the user can enable encryption for the table */ + HA_TOPTION_ENUM("ENCRYPTED", encryption, "DEFAULT,YES,NO", 0), /* With this option the user defines the key identifier using for the encryption */ - HA_TOPTION_NUMBER("PAGE_ENCRYPTION_KEY", page_encryption_key, 0, 1, 255, 1), + HA_TOPTION_SYSVAR("ENCRYPTION_KEY_ID", encryption_key_id, default_encryption_key_id), HA_TOPTION_END }; @@ -1013,12 +1017,10 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_pages_page_decompressed, SHOW_LONGLONG}, {"num_pages_page_compression_error", (char*) &export_vars.innodb_pages_page_compression_error, SHOW_LONGLONG}, - {"num_pages_page_encrypted", - (char*) &export_vars.innodb_pages_page_encrypted, SHOW_LONGLONG}, - {"num_pages_page_decrypted", - (char*) &export_vars.innodb_pages_page_decrypted, SHOW_LONGLONG}, - {"num_pages_page_encryption_error", - (char*) &export_vars.innodb_pages_page_encryption_error, SHOW_LONGLONG}, + {"num_pages_encrypted", + (char*) &export_vars.innodb_pages_encrypted, SHOW_LONGLONG}, + {"num_pages_decrypted", + (char*) &export_vars.innodb_pages_decrypted, SHOW_LONGLONG}, {"have_lz4", (char*) &innodb_have_lz4, SHOW_BOOL}, {"have_lzo", @@ -11557,8 +11559,6 @@ innobase_table_flags( modified by another thread while the table is being created. */ const ulint default_compression_level = page_zip_level; - const ulint default_encryption_key = srv_default_page_encryption_key; - *flags = 0; *flags2 = 0; @@ -11757,10 +11757,7 @@ index_bad: options->page_compressed, options->page_compression_level == 0 ? default_compression_level : options->page_compression_level, - options->atomic_writes, - options->page_encryption, - options->page_encryption_key == 0 ? - default_encryption_key : options->page_encryption_key); + options->atomic_writes); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { *flags2 |= DICT_TF2_TEMPORARY; @@ -11796,37 +11793,27 @@ ha_innobase::check_table_options( enum row_type row_format = table->s->row_type; ha_table_option_struct *options= table->s->option_struct; atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes; + fil_encryption_t encrypt = (fil_encryption_t)options->encryption; - if (options->page_encryption) { - if (srv_encrypt_tables) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION not available if innodb_encrypt_tables=ON"); - return "INNODB_ENCRYPT_TABLES"; - } + if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT && !use_tablespace) { + push_warning( + thd, Sql_condition::WARN_LEVEL_WARN, + HA_WRONG_CREATE_OPTION, + "InnoDB: ENCRYPTED requires innodb_file_per_table"); + return "ENCRYPTED"; + } - if (!use_tablespace) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION requires" - " innodb_file_per_table."); - return "PAGE_ENCRYPTION"; - } + if (encrypt == FIL_SPACE_ENCRYPTION_OFF && srv_encrypt_tables == 2) { + push_warning( + thd, Sql_condition::WARN_LEVEL_WARN, + HA_WRONG_CREATE_OPTION, + "InnoDB: ENCRYPTED=OFF cannot be used when innodb_encrypt_tables=FORCE"); + return "ENCRYPTED"; } /* Check page compression requirements */ if (options->page_compressed) { - if (srv_encrypt_tables) { - push_warning( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_COMPRESSION not available if innodb_encrypt_tables=ON"); - return "PAGE_COMPRESSED"; - } - if (row_format == ROW_TYPE_COMPRESSED) { push_warning( thd, Sql_condition::WARN_LEVEL_WARN, @@ -11896,29 +11883,16 @@ ha_innobase::check_table_options( } } - if (options->page_encryption_key != 0) { - if (options->page_encryption == false) { - /* ignore this to allow alter table without changing page_encryption_key ...*/ - } - - if (options->page_encryption_key < 1 || options->page_encryption_key > 255) { + if (encrypt == FIL_SPACE_ENCRYPTION_ON || + (encrypt == FIL_SPACE_ENCRYPTION_DEFAULT && srv_encrypt_tables)) { + if (!encryption_key_id_exists(options->encryption_key_id)) { push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN, HA_WRONG_CREATE_OPTION, - "InnoDB: invalid PAGE_ENCRYPTION_KEY = %lu." - " Valid values are [1..255]", - options->page_encryption_key); - return "PAGE_ENCRYPTION_KEY"; - } - - if (!has_encryption_key(options->page_encryption_key)) { - push_warning_printf( - thd, Sql_condition::WARN_LEVEL_WARN, - HA_WRONG_CREATE_OPTION, - "InnoDB: PAGE_ENCRYPTION_KEY encryption key %lu not available", - options->page_encryption_key + "InnoDB: ENCRYPTION_KEY_ID %lu not available", + options->encryption_key_id ); - return "PAGE_ENCRYPTION_KEY"; + return "ENCRYPTION_KEY_ID"; } } @@ -11980,6 +11954,10 @@ ha_innobase::create( const char* stmt; size_t stmt_len; + /* Cache table options */ + ha_table_option_struct *options= form->s->option_struct; + fil_encryption_t encrypt = (fil_encryption_t)options->encryption; + ulint key_id = options->encryption_key_id; DBUG_ENTER("ha_innobase::create"); @@ -12238,6 +12216,27 @@ ha_innobase::create( DBUG_ASSERT(innobase_table != 0); + /* If user has requested that table should be encrypted or table + should remain as unencrypted store crypt data */ + if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT) { + ulint maxsize; + ulint zip_size = fil_space_get_zip_size(innobase_table->space); + fil_space_crypt_t* old_crypt_data = fil_space_get_crypt_data(innobase_table->space); + fil_space_crypt_t* crypt_data; + + crypt_data = fil_space_create_crypt_data(key_id); + crypt_data->page0_offset = fsp_header_get_crypt_offset(zip_size, &maxsize); + crypt_data->encryption = encrypt; + + /* If there is old crypt data, copy IV */ + if (old_crypt_data) { + memcpy(crypt_data->iv, old_crypt_data->iv, old_crypt_data->iv_length); + crypt_data->iv_length = old_crypt_data->iv_length; + } + + fil_space_set_crypt_data(innobase_table->space, crypt_data); + } + innobase_copy_frm_flags_from_create_info(innobase_table, create_info); dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE); @@ -20307,13 +20306,20 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa UINT_MAX32, /* Maximum setting */ 0); -static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0, - "Encrypt all tables in the storage engine", - 0, 0, 0); +static const char* srv_encrypt_tables_names[] = { "OFF", "ON", "FORCE", 0 }; +static TYPELIB srv_encrypt_tables_typelib = { + array_elements(srv_encrypt_tables_names)-1, 0, srv_encrypt_tables_names, + NULL +}; +static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables, + PLUGIN_VAR_OPCMDARG, + "Enable encryption for tables. " + "Don't forget to enable --innodb-encrypt-log too", + NULL, NULL, 0, &srv_encrypt_tables_typelib); static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, PLUGIN_VAR_RQCMDARG, - "No of threads performing background key rotation and " + "Number of threads performing background key rotation and " "scrubbing", NULL, innodb_encryption_threads_update, @@ -20322,7 +20328,9 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, static MYSQL_SYSVAR_UINT(encryption_rotate_key_age, srv_fil_crypt_rotate_key_age, PLUGIN_VAR_RQCMDARG, - "Rotate any page having a key older than this", + "Key rotation - re-encrypt in background " + "all pages that were encrypted with a key that " + "many (or more) versions behind", NULL, innodb_encryption_rotate_key_age_update, srv_fil_crypt_rotate_key_age, 0, UINT_MAX32, 0); @@ -20334,37 +20342,22 @@ static MYSQL_SYSVAR_UINT(encryption_rotation_iops, srv_n_fil_crypt_iops, innodb_encryption_rotation_iops_update, srv_n_fil_crypt_iops, 0, UINT_MAX32, 0); -static MYSQL_SYSVAR_UINT(default_page_encryption_key, srv_default_page_encryption_key, - PLUGIN_VAR_RQCMDARG, - "Encryption key used for page encryption.", - NULL, - NULL, - DEFAULT_ENCRYPTION_KEY, 1, 255, 0); - static MYSQL_SYSVAR_BOOL(scrub_log, srv_scrub_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log scrubbing", + "Enable background redo log (ib_logfile0, ib_logfile1...) scrubbing", 0, 0, 0); -/* - If innodb_scrub_log is on, logs will be scrubbed in less than - (((innodb_log_file_size * innodb_log_files_in_group) / 512 ) / - ((1000 * 86400) / innodb_scrub_log_interval)) - days. - In above formula, the first line calculates the number of log blocks to scrub, - and the second line calculates the number of log blocks scrubbed in one day. -*/ -static MYSQL_SYSVAR_ULONGLONG(scrub_log_interval, innodb_scrub_log_interval, +static MYSQL_SYSVAR_ULONGLONG(scrub_log_speed, innodb_scrub_log_speed, PLUGIN_VAR_OPCMDARG, - "Innodb redo log scrubbing interval in ms", + "Background redo log scrubbing speed in bytes/sec", NULL, NULL, - 2000, /* default */ - 10, /* min */ - ULONGLONG_MAX, 0);/* max */ + 256, /* 256 bytes/sec, corresponds to 2000 ms scrub_log_interval */ + 1, /* min */ + 50000, 0); /* 50Kbyte/sec, corresponds to 10 ms scrub_log_interval */ static MYSQL_SYSVAR_BOOL(encrypt_log, srv_encrypt_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log encryption/decryption.", + "Enable redo log encryption", NULL, NULL, FALSE); static MYSQL_SYSVAR_BOOL(immediate_scrub_data_uncompressed, @@ -20409,7 +20402,7 @@ static MYSQL_SYSVAR_UINT(background_scrub_data_interval, UINT_MAX32, 0); #ifdef UNIV_DEBUG -static MYSQL_SYSVAR_BOOL(scrub_force_testing, +static MYSQL_SYSVAR_BOOL(debug_force_scrubbing, srv_scrub_force_testing, 0, "Perform extra scrubbing to increase test exposure", @@ -20644,9 +20637,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(encryption_rotate_key_age), MYSQL_SYSVAR(encryption_rotation_iops), MYSQL_SYSVAR(scrub_log), - MYSQL_SYSVAR(scrub_log_interval), + MYSQL_SYSVAR(scrub_log_speed), MYSQL_SYSVAR(encrypt_log), - MYSQL_SYSVAR(default_page_encryption_key), + MYSQL_SYSVAR(default_encryption_key_id), /* Scrubing feature */ MYSQL_SYSVAR(immediate_scrub_data_uncompressed), MYSQL_SYSVAR(background_scrub_data_uncompressed), @@ -20654,7 +20647,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(background_scrub_data_interval), MYSQL_SYSVAR(background_scrub_data_check_interval), #ifdef UNIV_DEBUG - MYSQL_SYSVAR(scrub_force_testing), + MYSQL_SYSVAR(debug_force_scrubbing), #endif MYSQL_SYSVAR(instrument_semaphores), NULL @@ -20674,7 +20667,7 @@ maria_declare_plugin(xtradb) innodb_status_variables_export,/* status variables */ innobase_system_variables, /* system variables */ INNODB_VERSION_STR, /* string version */ - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ + MariaDB_PLUGIN_MATURITY_BETA /* maturity */ }, i_s_xtradb_read_view, i_s_xtradb_internal_hash_tables, diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 0acf77da28f..aadd2fc5bb8 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -71,9 +71,8 @@ struct ha_table_option_struct srv_use_atomic_writes=1. Atomic writes are not used if value OFF.*/ - bool page_encryption; /*!< Flag for an encrypted table */ - /* Following can't be unsigned as it's compared with ULINT_UNDEFINED */ - int page_encryption_key; /*!< ID of the encryption key */ + uint encryption; /*!< DEFAULT, ON, OFF */ + int encryption_key_id; /*!< encryption key id */ }; /** The class defining a handle to an Innodb table */ diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 7e8e6e4598e..8b1bd89d1c5 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -282,8 +282,8 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (new_options->page_encryption != old_options->page_encryption || - new_options->page_encryption_key != old_options->page_encryption_key) { + if (new_options->encryption != old_options->encryption || + new_options->encryption_key_id != old_options->encryption_key_id) { ha_alter_info->unsupported_reason = innobase_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 20bc4331bc8..9b5c7beb298 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -72,6 +72,8 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits) #include "btr0btr.h" #include "page0zip.h" #include "sync0arr.h" +#include "fil0fil.h" +#include "fil0crypt.h" /** structure associates a name string with a file page type and/or buffer page state. */ @@ -790,7 +792,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_trx = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ @@ -1048,7 +1050,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_locks = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ @@ -1229,7 +1231,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /*******************************************************************//** @@ -1563,7 +1565,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = @@ -1611,7 +1613,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /* Fields of the dynamic tables @@ -1910,7 +1912,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_per_index = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_per_index_reset = @@ -1959,7 +1961,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_per_index_reset = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table information_schema.innodb_cmpmem. */ @@ -2201,7 +2203,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = @@ -2249,7 +2251,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_metrics */ @@ -2772,7 +2774,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_metrics = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_ft_default_stopword */ static ST_FIELD_INFO i_s_stopword_fields_info[] = @@ -2884,7 +2886,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_default_stopword = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED @@ -3051,7 +3053,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_deleted = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -3133,7 +3135,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_being_deleted = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED and @@ -3422,7 +3424,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_index_cache = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /*******************************************************************//** @@ -3856,7 +3858,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_index_table = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG */ @@ -4049,7 +4051,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_config = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */ @@ -4596,7 +4598,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_stats = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */ @@ -5305,7 +5307,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] = @@ -5850,7 +5852,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page_lru = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /*******************************************************************//** @@ -6142,7 +6144,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_TABLESTATS ***********************************************/ @@ -6430,7 +6432,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablestats = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_INDEXES **************************************************/ @@ -6680,7 +6682,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_COLUMNS **************************************************/ @@ -6915,7 +6917,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_columns = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_FIELDS ***************************************************/ @@ -7123,7 +7125,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_FOREIGN ********************************************/ @@ -7346,7 +7348,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_FOREIGN_COLS ********************************************/ @@ -7561,7 +7563,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** SYS_TABLESPACES ********************************************/ @@ -7828,7 +7830,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tablespaces = STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_DATAFILES ************************************************/ @@ -8015,7 +8017,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_datafiles = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; static ST_FIELD_INFO i_s_innodb_changed_pages_info[] = @@ -8384,7 +8386,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_changed_pages = STRUCT_FLD(version, 0x0100 /* 1.0 */), STRUCT_FLD(status_vars, NULL), STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** TABLESPACES_ENCRYPTION ********************************************/ @@ -8664,7 +8666,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_encryption = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_BETA }; /** TABLESPACES_SCRUBBING ********************************************/ @@ -8962,7 +8964,7 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_scrubbing = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA) }; /** INNODB_MUTEXES *********************************************/ @@ -9176,7 +9178,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_mutexes = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; /** SYS_SEMAPHORE_WAITS ************************************************/ @@ -9453,5 +9455,5 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_semaphore_waits = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; diff --git a/storage/xtradb/handler/xtradb_i_s.cc b/storage/xtradb/handler/xtradb_i_s.cc index 96e31b94470..207682e3154 100644 --- a/storage/xtradb/handler/xtradb_i_s.cc +++ b/storage/xtradb/handler/xtradb_i_s.cc @@ -176,7 +176,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_xtradb_read_view = STRUCT_FLD(status_vars, NULL), STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; static ST_FIELD_INFO xtradb_internal_hash_tables_fields_info[] = @@ -381,7 +381,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_xtradb_internal_hash_tables = STRUCT_FLD(status_vars, NULL), STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; @@ -514,5 +514,5 @@ UNIV_INTERN struct st_mysql_plugin i_s_xtradb_rseg = STRUCT_FLD(status_vars, NULL), STRUCT_FLD(system_vars, NULL), STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), }; diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index 7eb58216698..912fbb9194f 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -1469,16 +1469,19 @@ buf_own_zip_mutex_for_page( The hook that is called just before a page is written to disk. The function encrypts the content of the page and returns a pointer to a frame that will be written instead of the real frame. */ +UNIV_INTERN byte* buf_page_encrypt_before_write( /*==========================*/ buf_page_t* page, /*!< in/out: buffer page to be flushed */ - const byte* frame); + const byte* frame, + ulint space_id); /********************************************************************** The hook that is called after page is written to disk. The function releases any resources needed for encryption that was allocated in buf_page_encrypt_before_write */ +UNIV_INTERN ibool buf_page_encrypt_after_write( /*=========================*/ @@ -1488,6 +1491,7 @@ buf_page_encrypt_after_write( The hook that is called just before a page is read from disk. The function allocates memory that is used to temporarily store disk content before getting decrypted */ +UNIV_INTERN byte* buf_page_decrypt_before_read( /*=========================*/ @@ -1498,19 +1502,35 @@ buf_page_decrypt_before_read( The hook that is called just after a page is read from disk. The function decrypt disk content into buf_page_t and releases the temporary buffer that was allocated in buf_page_decrypt_before_read */ +UNIV_INTERN ibool buf_page_decrypt_after_read( /*========================*/ buf_page_t* page); /*!< in/out: buffer page read from disk */ -/********************************************************************//** -Release memory allocated for page decryption. -Only used in scenarios where read fails, e.g due to tablespace being dropped */ -void -buf_page_decrypt_cleanup( -/*=====================*/ - buf_page_t* page); /*!< in/out: buffer page read from disk */ +/** @brief The temporary memory structure. +NOTE! The definition appears here only for other modules of this +directory (buf) to see it. Do not use from outside! */ + +typedef struct { + bool reserved; /*!< true if this slot is reserved + */ +#ifdef HAVE_LZO + byte* lzo_mem; /*!< Temporal memory used by LZO */ +#endif + byte* crypt_buf; /*!< for encryption the data needs to be + copied to a separate buffer before it's + encrypted&written. this as a page can be + read while it's being flushed */ + byte* crypt_buf_free; /*!< for encryption, allocated buffer + that is then alligned */ + byte* comp_buf; /*!< for compression we need + temporal buffer because page + can be read while it's being flushed */ + byte* comp_buf_free; /*!< for compression, allocated + buffer that is then alligned */ +} buf_tmp_buffer_t; /** The common buffer control block structure for compressed and uncompressed frames */ @@ -1587,19 +1607,16 @@ struct buf_page_t{ operation needed. */ unsigned key_version; /*!< key version for this block */ - byte* crypt_buf; /*!< for encryption the data needs to be - copied to a separate buffer before it's - encrypted&written. this as a page can be - read while it's being flushed */ - byte* crypt_buf_free; /*!< for encryption, allocated buffer - that is then alligned */ - byte* comp_buf; /*!< for compression we need - temporal buffer because page - can be read while it's being flushed */ - byte* comp_buf_free; /*!< for compression, allocated - buffer that is then alligned */ - bool encrypt_later; /*!< should we encrypt the page - at os0file.cc ? */ + + ulint real_size; /*!< Real size of the page + Normal pages == UNIV_PAGE_SIZE + page compressed pages, payload + size alligned to sector boundary. + */ + + buf_tmp_buffer_t* slot; /*!< Slot for temporary memory + used for encryption/compression + or NULL */ #ifndef UNIV_HOTBACKUP buf_page_t* hash; /*!< node used in chaining to buf_pool->page_hash or @@ -1918,6 +1935,17 @@ struct buf_buddy_stat_t { ib_uint64_t relocated_usec; }; +/** @brief The temporary memory array structure. + +NOTE! The definition appears here only for other modules of this +directory (buf) to see it. Do not use from outside! */ + +typedef struct { + ulint n_slots; /*!< Total number of slots */ + buf_tmp_buffer_t *slots; /*!< Pointer to the slots in the + array */ +} buf_tmp_array_t; + /** @brief The buffer pool structure. NOTE! The definition appears here only for other modules of this @@ -2091,6 +2119,10 @@ struct buf_pool_t{ /*!< Sentinel records for buffer pool watches. */ + buf_tmp_array_t* tmp_arr; + /*!< Array for temporal memory + used in compression and encryption */ + #if BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN # error "BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN" #endif diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic index b522751833f..8d8a314e2ef 100644 --- a/storage/xtradb/include/buf0buf.ic +++ b/storage/xtradb/include/buf0buf.ic @@ -918,27 +918,16 @@ buf_block_free( mutex_exit(&block->mutex); } -/********************************************************************//** -Get crypt buffer. */ -UNIV_INLINE -byte* -buf_page_get_crypt_buffer( -/*=========================*/ - const buf_page_t* bpage) /*!< in: buffer pool page */ -{ - return bpage->crypt_buf; -} - /********************************************************************//** Get buf frame. */ UNIV_INLINE void * buf_page_get_frame( -/*=========================*/ +/*===============*/ const buf_page_t* bpage) /*!< in: buffer pool page */ { - if (bpage->crypt_buf) { - return buf_page_get_crypt_buffer(bpage); + if (bpage->slot && bpage->slot->crypt_buf) { + return bpage->slot->crypt_buf; } else if (bpage->zip.data) { return bpage->zip.data; } else { diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index ef8c9878297..0d3aac32df9 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -929,10 +929,8 @@ dict_tf_set( pages */ ulint page_compression_level, /*!< in: table page compression level */ - ulint atomic_writes, /*!< in: table atomic + ulint atomic_writes) /*!< in: table atomic writes option value*/ - bool page_encrypted,/*!< in: table uses page encryption */ - ulint page_encryption_key) /*!< in: page encryption key */ __attribute__((nonnull)); /********************************************************************//** Convert a 32 bit integer table flags to the 32 bit integer that is diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index c480b3c6216..e5f4ec21bd2 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -543,9 +543,6 @@ dict_tf_is_valid( ulint data_dir = DICT_TF_HAS_DATA_DIR(flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags); - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(flags); - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(flags); - /* Make sure there are no bits that we do not know about. */ if (unused != 0) { @@ -556,12 +553,10 @@ dict_tf_is_valid( "InnoDB: compact %ld atomic_blobs %ld\n" "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n" - "InnoDB: page_encryption %ld page_encryption_key %ld\n", + "InnoDB: atomic_writes %ld\n", unused, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes, - page_encryption, page_encryption_key + page_compression, page_compression_level, atomic_writes ); return(false); @@ -861,9 +856,7 @@ dict_tf_set( pages */ ulint page_compression_level, /*!< in: table page compression level */ - ulint atomic_writes, /*!< in: table atomic writes setup */ - bool page_encrypted, /*!< in: table uses page encryption */ - ulint page_encryption_key /*!< in: page encryption key */) + ulint atomic_writes) /*!< in: table atomic writes setup */ { atomic_writes_t awrites = (atomic_writes_t)atomic_writes; @@ -904,11 +897,6 @@ dict_tf_set( *flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES); ut_a(dict_tf_get_atomic_writes(*flags) == awrites); - - if (page_encrypted) { - *flags |= (1 << DICT_TF_POS_PAGE_ENCRYPTION) - | (page_encryption_key << DICT_TF_POS_PAGE_ENCRYPTION_KEY); - } } /********************************************************************//** @@ -931,11 +919,6 @@ dict_tf_to_fsp_flags( ulint fsp_flags; ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); - - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(table_flags); - /* Keys are limited to 255 values */ - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(table_flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure", @@ -963,14 +946,6 @@ dict_tf_to_fsp_flags( if page compression is used for this table. */ fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level); - /* In addition, tablespace flags also contain if the page - encryption is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_ENCRYPTION(fsp_flags, page_encryption); - - /* In addition, tablespace flags also contain page encryption key if the page - encryption is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_ENCRYPTION_KEY(fsp_flags, page_encryption_key); - /* In addition, tablespace flags also contain flag if atomic writes is used for this table */ fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes); @@ -1012,8 +987,6 @@ dict_sys_tables_type_to_tf( | DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL | DICT_TF_MASK_ATOMIC_WRITES - | DICT_TF_MASK_PAGE_ENCRYPTION - | DICT_TF_MASK_PAGE_ENCRYPTION_KEY ); @@ -1050,9 +1023,7 @@ dict_tf_to_sys_tables_type( | DICT_TF_MASK_DATA_DIR | DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL - | DICT_TF_MASK_ATOMIC_WRITES - | DICT_TF_MASK_PAGE_ENCRYPTION - | DICT_TF_MASK_PAGE_ENCRYPTION_KEY); + | DICT_TF_MASK_ATOMIC_WRITES); return(type); } diff --git a/storage/xtradb/include/dict0pagecompress.ic b/storage/xtradb/include/dict0pagecompress.ic index a71b2b34b07..811976434a8 100644 --- a/storage/xtradb/include/dict0pagecompress.ic +++ b/storage/xtradb/include/dict0pagecompress.ic @@ -42,8 +42,6 @@ dict_tf_verify_flags( ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); - ulint page_encryption = DICT_TF_GET_PAGE_ENCRYPTION(table_flags); - ulint page_encryption_key = DICT_TF_GET_PAGE_ENCRYPTION_KEY(table_flags); ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags); ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags); @@ -52,9 +50,6 @@ dict_tf_verify_flags( ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags); - ulint fsp_page_encryption = FSP_FLAGS_GET_PAGE_ENCRYPTION(fsp_flags); - ulint fsp_page_encryption_key = FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(fsp_flags); - DBUG_EXECUTE_IF("dict_tf_verify_flags_failure", return(ULINT_UNDEFINED);); @@ -112,27 +107,6 @@ dict_tf_verify_flags( return (FALSE); } - if (page_encryption != fsp_page_encryption) { - fprintf(stderr, - "InnoDB: Error: table flags has page_encryption %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_encryption %ld\n", - page_encryption, fsp_page_encryption); - - return (FALSE); - } - - if (page_encryption_key != fsp_page_encryption_key) { - fprintf(stderr, - "InnoDB: Error: table flags has page_encryption_key %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_encryption_key %ld\n", - page_encryption_key, fsp_page_encryption_key); - - return (FALSE); - } - - return(TRUE); } diff --git a/storage/xtradb/include/fil0crypt.h b/storage/xtradb/include/fil0crypt.h new file mode 100644 index 00000000000..65c51c75d41 --- /dev/null +++ b/storage/xtradb/include/fil0crypt.h @@ -0,0 +1,387 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0crypt.h +The low-level file system encryption support functions + +Created 04/01/2015 Jan Lindström +*******************************************************/ + +#ifndef fil0crypt_h +#define fil0crypt_h + +/* This key will be used if nothing else is given */ +#define FIL_DEFAULT_ENCRYPTION_KEY 1 + +/** Enum values for encryption table option */ +typedef enum { + FIL_SPACE_ENCRYPTION_DEFAULT = 0, /* Tablespace encrypted if + srv_encrypt_tables = ON */ + FIL_SPACE_ENCRYPTION_ON = 1, /* Tablespace is encrypted always */ + FIL_SPACE_ENCRYPTION_OFF = 2 /* Tablespace is not encrypted */ +} fil_encryption_t; + +/** + * CRYPT_SCHEME_UNENCRYPTED + * + * Used as intermediate state when convering a space from unencrypted + * to encrypted + */ +/** + * CRYPT_SCHEME_1 + * + * xxx is AES_CTR or AES_CBC (or another block cypher with the same key and iv lengths) + * L = AES_ECB(KEY, IV) + * CRYPT(PAGE) = xxx(KEY=L, IV=C, PAGE) + */ + +#define CRYPT_SCHEME_1 1 +#define CRYPT_SCHEME_1_IV_LEN 16 +#define CRYPT_SCHEME_UNENCRYPTED 0 + +/* Cached L or key for given key_version */ +struct key_struct +{ + uint key_version; /*!< Version of the key */ + uint key_length; /*!< Key length */ + unsigned char key[MY_AES_MAX_KEY_LENGTH]; /*!< Cached key + (that is L in CRYPT_SCHEME_1) */ +}; + +struct fil_space_rotate_state_t +{ + time_t start_time; // time when rotation started + ulint active_threads; // active threads in space + ulint next_offset; // next "free" offset + ulint max_offset; // max offset needing to be rotated + uint min_key_version_found; // min key version found but not rotated + lsn_t end_lsn; // max lsn created when rotating this space + bool starting; // initial write of IV + bool flushing; // space is being flushed at end of rotate + struct { + bool is_active; // is scrubbing active in this space + time_t last_scrub_completed; // when was last scrub completed + } scrubbing; +}; + +struct fil_space_crypt_struct +{ + ulint type; // CRYPT_SCHEME + uint keyserver_requests; // no of key requests to key server + uint key_count; // No of initalized key-structs + uint key_id; // Key id for this space + key_struct keys[3]; // cached L = AES_ECB(KEY, IV) + uint min_key_version; // min key version for this space + ulint page0_offset; // byte offset on page 0 for crypt data + fil_encryption_t encryption; // Encryption setup + + ib_mutex_t mutex; // mutex protecting following variables + bool closing; // is tablespace being closed + fil_space_rotate_state_t rotate_state; + + uint iv_length; // length of IV + byte iv[1]; // IV-data +}; + +/* structure containing encryption specification */ +typedef struct fil_space_crypt_struct fil_space_crypt_t; + +/********************************************************************* +Init global resources needed for tablespace encryption/decryption */ +UNIV_INTERN +void +fil_space_crypt_init(); + +/********************************************************************* +Cleanup global resources needed for tablespace encryption/decryption */ +UNIV_INTERN +void +fil_space_crypt_cleanup(); + +/********************************************************************* +Create crypt data, i.e data that is used for a single tablespace */ +UNIV_INTERN +fil_space_crypt_t * +fil_space_create_crypt_data(uint key_id); + +/********************************************************************* +Destroy crypt data */ +UNIV_INTERN +void +fil_space_destroy_crypt_data( +/*=========================*/ + fil_space_crypt_t **crypt_data); /*!< in/out: crypt data */ + +/********************************************************************* +Get crypt data for a space*/ +UNIV_INTERN +fil_space_crypt_t * +fil_space_get_crypt_data( +/*======================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Set crypt data for a space*/ +UNIV_INTERN +void +fil_space_set_crypt_data( +/*======================*/ + ulint space, /*!< in: tablespace id */ + fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */ + +/********************************************************************* +Compare crypt data*/ +UNIV_INTERN +int +fil_space_crypt_compare( +/*======================*/ + const fil_space_crypt_t* crypt_data1, /*!< in: crypt data */ + const fil_space_crypt_t* crypt_data2); /*!< in: crypt data */ + +/********************************************************************* +Read crypt data from buffer page */ +UNIV_INTERN +fil_space_crypt_t * +fil_space_read_crypt_data( +/*======================*/ + ulint space, /*!< in: tablespace id */ + const byte* page, /*!< in: buffer page */ + ulint offset); /*!< in: offset where crypt data is stored */ + +/********************************************************************* +Write crypt data to buffer page */ +UNIV_INTERN +void +fil_space_write_crypt_data( +/*=======================*/ + ulint space, /*!< in: tablespace id */ + byte* page, /*!< in: buffer page */ + ulint offset, /*!< in: offset where to store data */ + ulint maxsize, /*!< in: max space available to store crypt data in */ + mtr_t * mtr); /*!< in: mini-transaction */ + +/********************************************************************* +Clear crypt data from page 0 (used for import tablespace) */ +UNIV_INTERN +void +fil_space_clear_crypt_data( +/*======================*/ + byte* page, /*!< in: buffer page */ + ulint offset); /*!< in: offset where crypt data is stored */ + +/********************************************************************* +Parse crypt data log record */ +UNIV_INTERN +byte* +fil_parse_write_crypt_data( +/*=======================*/ + byte* ptr, /*!< in: start of log record */ + byte* end_ptr, /*!< in: end of log record */ + buf_block_t*); /*!< in: buffer page to apply record to */ + +/********************************************************************* +Check if extra buffer shall be allocated for decrypting after read */ +UNIV_INTERN +bool +fil_space_check_encryption_read( +/*==============================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Check if page shall be encrypted before write */ +UNIV_INTERN +bool +fil_space_check_encryption_write( +/*==============================*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Encrypt buffer page */ +UNIV_INTERN +void +fil_space_encrypt( +/*===============*/ + ulint space, /*!< in: tablespace id */ + ulint offset, /*!< in: page no */ + lsn_t lsn, /*!< in: page lsn */ + const byte* src_frame,/*!< in: page frame */ + ulint size, /*!< in: size of data to encrypt */ + byte* dst_frame); /*!< in: where to encrypt to */ + +/********************************************************************* +Decrypt buffer page */ +UNIV_INTERN +void +fil_space_decrypt( +/*===============*/ + ulint space, /*!< in: tablespace id */ + const byte* src_frame,/*!< in: page frame */ + ulint page_size, /*!< in: size of data to encrypt */ + byte* dst_frame); /*!< in: where to decrypt to */ + + +/********************************************************************* +Decrypt buffer page +@return true if page was encrypted */ +UNIV_INTERN +bool +fil_space_decrypt( +/*===============*/ + fil_space_crypt_t* crypt_data, /*!< in: crypt data */ + const byte* src_frame,/*!< in: page frame */ + ulint page_size, /*!< in: page size */ + byte* dst_frame); /*!< in: where to decrypt to */ + +/********************************************************************* +fil_space_verify_crypt_checksum +NOTE: currently this function can only be run in single threaded mode +as it modifies srv_checksum_algorithm (temporarily) +@return true if page is encrypted AND OK, false otherwise */ +UNIV_INTERN +bool +fil_space_verify_crypt_checksum( +/*===============*/ + const byte* src_frame,/*!< in: page frame */ + ulint zip_size); /*!< in: size of data to encrypt */ + +/********************************************************************* +Init threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_init(); + +/********************************************************************* +Set thread count (e.g start or stops threads) used for key rotation */ +UNIV_INTERN +void +fil_crypt_set_thread_cnt( +/*=====================*/ + uint new_cnt); /*!< in: requested #threads */ + +/********************************************************************* +End threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_end(); + +/********************************************************************* +Cleanup resources for threads for key rotation */ +UNIV_INTERN +void +fil_crypt_threads_cleanup(); + +/********************************************************************* +Set rotate key age */ +UNIV_INTERN +void +fil_crypt_set_rotate_key_age( +/*=====================*/ + uint rotate_age); /*!< in: requested rotate age */ + +/********************************************************************* +Set rotation threads iops */ +UNIV_INTERN +void +fil_crypt_set_rotation_iops( +/*=====================*/ + uint iops); /*!< in: requested iops */ + +/********************************************************************* +Mark a space as closing */ +UNIV_INTERN +void +fil_space_crypt_mark_space_closing( +/*===============*/ + ulint space); /*!< in: tablespace id */ + +/********************************************************************* +Wait for crypt threads to stop accessing space */ +UNIV_INTERN +void +fil_space_crypt_close_tablespace( +/*===============*/ + ulint space); /*!< in: tablespace id */ + +/** Struct for retreiving info about encryption */ +struct fil_space_crypt_status_t { + ulint space; /*!< tablespace id */ + ulint scheme; /*!< encryption scheme */ + uint min_key_version; /*!< min key version */ + uint current_key_version;/*!< current key version */ + uint keyserver_requests;/*!< no of key requests to key server */ + bool rotating; /*!< is key rotation ongoing */ + bool flushing; /*!< is flush at end of rotation ongoing */ + ulint rotate_next_page_number; /*!< next page if key rotating */ + ulint rotate_max_page_number; /*!< max page if key rotating */ +}; + +/********************************************************************* +Get crypt status for a space +@return 0 if crypt data found */ +UNIV_INTERN +int +fil_space_crypt_get_status( +/*==================*/ + ulint id, /*!< in: space id */ + struct fil_space_crypt_status_t * status); /*!< out: status */ + +/** Struct for retreiving statistics about encryption key rotation */ +struct fil_crypt_stat_t { + ulint pages_read_from_cache; + ulint pages_read_from_disk; + ulint pages_modified; + ulint pages_flushed; + ulint estimated_iops; +}; + +/********************************************************************* +Get crypt rotation statistics */ +UNIV_INTERN +void +fil_crypt_total_stat( +/*==================*/ + fil_crypt_stat_t* stat); /*!< out: crypt stat */ + +/** Struct for retreiving info about scrubbing */ +struct fil_space_scrub_status_t { + ulint space; /*!< tablespace id */ + bool compressed; /*!< is space compressed */ + time_t last_scrub_completed; /*!< when was last scrub completed */ + bool scrubbing; /*!< is scrubbing ongoing */ + time_t current_scrub_started; /*!< when started current scrubbing */ + ulint current_scrub_active_threads; /*!< current scrub active threads */ + ulint current_scrub_page_number; /*!< current scrub page no */ + ulint current_scrub_max_page_number; /*!< current scrub max page no */ +}; + +/********************************************************************* +Get scrub status for a space +@return 0 if no scrub info found */ +UNIV_INTERN +int +fil_space_get_scrub_status( +/*==================*/ + ulint id, /*!< in: space id */ + struct fil_space_scrub_status_t * status); /*!< out: status */ + +#ifndef UNIV_NONINL +#include "fil0crypt.ic" +#endif + +#endif /* fil0crypt_h */ diff --git a/storage/xtradb/include/fil0crypt.ic b/storage/xtradb/include/fil0crypt.ic new file mode 100644 index 00000000000..0a1a60dfab8 --- /dev/null +++ b/storage/xtradb/include/fil0crypt.ic @@ -0,0 +1,68 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0fil.h +The low-level file system encryption support functions + +Created 04/01/2015 Jan Lindström +*******************************************************/ + +/*******************************************************************//** +Find out whether the page is page encrypted +@return true if page is page encrypted, false if not */ +UNIV_INLINE +bool +fil_page_is_encrypted( +/*==================*/ + const byte *buf) /*!< in: page */ +{ + return(mach_read_from_4(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) != 0); +} + +/*******************************************************************//** +Find out whether the page can be decrypted. +The function for decrypting the page should already be executed before this. +@return 1 if key provider not available or key is not available + 0 if decryption should be possible +*/ +UNIV_INLINE +bool +fil_page_encryption_status( +/*===================*/ + const byte *buf, /*!< in: page */ + ulint space_id) /*!< in: space_id */ +{ + fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space_id); + ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE); + + if (page_type == FIL_PAGE_TYPE_FSP_HDR) { + if (crypt_data != NULL) { + if (!encryption_key_id_exists(crypt_data->key_id)) { + /* accessing table would surely fail, because no key or no key provider available */ + return 1; + } + } + } else { + ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + if (!encryption_key_version_exists(crypt_data->key_id, key)) { + return 1; + } + } + return 0; +} diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 2e92c2b09b2..c7ecaf8b628 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -26,7 +26,6 @@ Created 10/25/1995 Heikki Tuuri #ifndef fil0fil_h #define fil0fil_h -#define MSG_CANNOT_DECRYPT "can not decrypt" #include "univ.i" #ifndef UNIV_INNOCHECKSUM @@ -132,24 +131,6 @@ extern fil_addr_t fil_addr_null; used to encrypt the page + 32-bit checksum or 64 bits of zero if no encryption */ -/** If page type is FIL_PAGE_COMPRESSED then the 8 bytes starting at -FIL_PAGE_FILE_FLUSH_LSN are broken down as follows: */ - -/** Control information version format (u8) */ -static const ulint FIL_PAGE_VERSION = FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; - -/** Compression algorithm (u8) */ -static const ulint FIL_PAGE_ALGORITHM_V1 = FIL_PAGE_VERSION + 1; - -/** Original page type (u16) */ -static const ulint FIL_PAGE_ORIGINAL_TYPE_V1 = FIL_PAGE_ALGORITHM_V1 + 1; - -/** Original data size in bytes (u16)*/ -static const ulint FIL_PAGE_ORIGINAL_SIZE_V1 = FIL_PAGE_ORIGINAL_TYPE_V1 + 2; - -/** Size after compression (u16)*/ -static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; - #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this contains the space id of the page */ #define FIL_PAGE_SPACE_ID FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID @@ -169,10 +150,7 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; /* @} */ /** File page types (values of FIL_PAGE_TYPE) @{ */ -#define FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED 35631 /* page compressed + - encrypted page */ #define FIL_PAGE_PAGE_COMPRESSED 34354 /*!< Page compressed page */ -#define FIL_PAGE_PAGE_ENCRYPTED 34355 /*!< Page encrypted page */ #define FIL_PAGE_INDEX 17855 /*!< B-tree node */ #define FIL_PAGE_UNDO_LOG 2 /*!< Undo log page */ #define FIL_PAGE_INODE 3 /*!< Index node */ @@ -199,6 +177,9 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; #define FIL_LOG 502 /*!< redo log */ /* @} */ +/* structure containing encryption specification */ +typedef struct fil_space_crypt_struct fil_space_crypt_t; + /** The number of fsyncs done to the log */ extern ulint fil_n_log_flushes; @@ -210,9 +191,6 @@ extern ulint fil_n_pending_tablespace_flushes; /** Number of files currently open */ extern ulint fil_n_file_opened; -/* structure containing encryption specification */ -typedef struct fil_space_crypt_struct fil_space_crypt_t; - struct fsp_open_info { ibool success; /*!< Has the tablespace been opened? */ const char* check_msg; /*!< fil_check_first_page() message */ @@ -963,9 +941,6 @@ fil_space_get_n_reserved_extents( Reads or writes data. This operation is asynchronous (aio). @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do i/o on a tablespace which does not exist */ -#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, lsn, encrypt) \ - _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL, lsn, encrypt) - UNIV_INTERN dberr_t _fil_io( @@ -1000,11 +975,24 @@ _fil_io( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - trx_t* trx, - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: encrypt later ? */ + trx_t* trx) /*!< in: trx */ __attribute__((nonnull(8))); + +#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size) \ + _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL) + +/*******************************************************************//** +Returns the block size of the file space +@return block size */ +UNIV_INTERN +ulint +fil_space_get_block_size( +/*=====================*/ + ulint id, /*!< in: space id */ + ulint offset, /*!< in: page offset */ + ulint len); /*!< in: page len */ + /**********************************************************************//** Waits for an aio operation to complete. This function is used to write the handler for completed requests. The aio array of pending requests is divided @@ -1298,12 +1286,6 @@ fil_space_t* fil_space_get_by_id( /*================*/ ulint id); /*!< in: space id */ -/*******************************************************************//** -Return space name */ -char* -fil_space_name( -/*===========*/ - fil_space_t* space); /*!< in: space */ /****************************************************************** Get id of first tablespace or ULINT_UNDEFINED if none */ @@ -1318,253 +1300,16 @@ ulint fil_get_next_space( ulint id); /*!< in: space id */ -/********************************************************************* -Init global resources needed for tablespace encryption/decryption */ -void -fil_space_crypt_init(); - -/********************************************************************* -Cleanup global resources needed for tablespace encryption/decryption */ -void -fil_space_crypt_cleanup(); - -/********************************************************************* -Create crypt data, i.e data that is used for a single tablespace */ -fil_space_crypt_t * -fil_space_create_crypt_data(); - -/********************************************************************* -Destroy crypt data */ -UNIV_INTERN -void -fil_space_destroy_crypt_data( -/*=========================*/ - fil_space_crypt_t **crypt_data); /*!< in/out: crypt data */ - -/********************************************************************* -Get crypt data for a space*/ -fil_space_crypt_t * -fil_space_get_crypt_data( -/*======================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Set crypt data for a space*/ -void -fil_space_set_crypt_data( -/*======================*/ - ulint space, /*!< in: tablespace id */ - fil_space_crypt_t* crypt_data); /*!< in: crypt data */ - -/********************************************************************* -Compare crypt data*/ -int -fil_space_crypt_compare( -/*======================*/ - const fil_space_crypt_t* crypt_data1, /*!< in: crypt data */ - const fil_space_crypt_t* crypt_data2); /*!< in: crypt data */ - -/********************************************************************* -Read crypt data from buffer page */ -fil_space_crypt_t * -fil_space_read_crypt_data( -/*======================*/ - ulint space, /*!< in: tablespace id */ - const byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ - -/********************************************************************* -Write crypt data to buffer page */ -void -fil_space_write_crypt_data( -/*=======================*/ - ulint space, /*!< in: tablespace id */ - byte* page, /*!< in: buffer page */ - ulint offset, /*!< in: offset where to store data */ - ulint maxsize, /*!< in: max space available to store crypt data in */ - mtr_t * mtr); /*!< in: mini-transaction */ - -/********************************************************************* -Clear crypt data from page 0 (used for import tablespace) */ -void -fil_space_clear_crypt_data( -/*======================*/ - byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ - -/********************************************************************* -Parse crypt data log record */ -byte* -fil_parse_write_crypt_data( -/*=======================*/ - byte* ptr, /*!< in: start of log record */ - byte* end_ptr, /*!< in: end of log record */ - buf_block_t*); /*!< in: buffer page to apply record to */ - -/********************************************************************* -Check if extra buffer shall be allocated for decrypting after read */ -UNIV_INTERN -bool -fil_space_check_encryption_read( -/*==============================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Check if page shall be encrypted before write */ -UNIV_INTERN -bool -fil_space_check_encryption_write( -/*==============================*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Encrypt buffer page */ -void -fil_space_encrypt( -/*===============*/ - ulint space, /*!< in: tablespace id */ - ulint offset, /*!< in: page no */ - lsn_t lsn, /*!< in: page lsn */ - const byte* src_frame,/*!< in: page frame */ - ulint size, /*!< in: size of data to encrypt */ - byte* dst_frame, /*!< in: where to encrypt to */ - ulint page_encryption_key); /*!< in: page encryption key id if page - encrypted */ - -/********************************************************************* -Decrypt buffer page */ -void -fil_space_decrypt( -/*===============*/ - ulint space, /*!< in: tablespace id */ - const byte* src_frame,/*!< in: page frame */ - ulint page_size, /*!< in: size of data to encrypt */ - byte* dst_frame); /*!< in: where to decrypt to */ - - -/********************************************************************* -Decrypt buffer page -@return true if page was encrypted */ -bool -fil_space_decrypt( -/*===============*/ - fil_space_crypt_t* crypt_data, /*!< in: crypt data */ - const byte* src_frame,/*!< in: page frame */ - ulint page_size, /*!< in: page size */ - byte* dst_frame); /*!< in: where to decrypt to */ - -/********************************************************************* -fil_space_verify_crypt_checksum -NOTE: currently this function can only be run in single threaded mode -as it modifies srv_checksum_algorithm (temporarily) -@return true if page is encrypted AND OK, false otherwise */ -bool -fil_space_verify_crypt_checksum( -/*===============*/ - const byte* src_frame,/*!< in: page frame */ - ulint zip_size); /*!< in: size of data to encrypt */ - -/********************************************************************* -Init threads for key rotation */ -void -fil_crypt_threads_init(); - -/********************************************************************* -Set thread count (e.g start or stops threads) used for key rotation */ -void -fil_crypt_set_thread_cnt( -/*=====================*/ - uint new_cnt); /*!< in: requested #threads */ - -/********************************************************************* -End threads for key rotation */ -void -fil_crypt_threads_end(); - -/********************************************************************* -Cleanup resources for threads for key rotation */ -void -fil_crypt_threads_cleanup(); - -/********************************************************************* -Set rotate key age */ -void -fil_crypt_set_rotate_key_age( -/*=====================*/ - uint rotate_age); /*!< in: requested rotate age */ - -/********************************************************************* -Set rotation threads iops */ -void -fil_crypt_set_rotation_iops( -/*=====================*/ - uint iops); /*!< in: requested iops */ - -/********************************************************************* -Mark a space as closing */ -UNIV_INTERN -void -fil_space_crypt_mark_space_closing( -/*===============*/ - ulint space); /*!< in: tablespace id */ - -/********************************************************************* -Wait for crypt threads to stop accessing space */ -UNIV_INTERN -void -fil_space_crypt_close_tablespace( -/*===============*/ - ulint space); /*!< in: tablespace id */ - -/** Struct for retreiving info about encryption */ -struct fil_space_crypt_status_t { - ulint space; /*!< tablespace id */ - ulint scheme; /*!< encryption scheme */ - uint min_key_version; /*!< min key version */ - uint current_key_version;/*!< current key version */ - uint keyserver_requests;/*!< no of key requests to key server */ - bool rotating; /*!< is key rotation ongoing */ - bool flushing; /*!< is flush at end of rotation ongoing */ - ulint rotate_next_page_number; /*!< next page if key rotating */ - ulint rotate_max_page_number; /*!< max page if key rotating */ -}; - -/********************************************************************* -Get crypt status for a space -@return 0 if crypt data found */ -int -fil_space_crypt_get_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_crypt_status_t * status); /*!< out: status */ - -/** Struct for retreiving statistics about encryption key rotation */ -struct fil_crypt_stat_t { - ulint pages_read_from_cache; - ulint pages_read_from_disk; - ulint pages_modified; - ulint pages_flushed; - ulint estimated_iops; -}; - -/********************************************************************* -Get crypt rotation statistics */ -void -fil_crypt_total_stat( -/*==================*/ - fil_crypt_stat_t* stat); /*!< out: crypt stat */ - #endif /*******************************************************************//** Return space flags */ +UNIV_INLINE ulint fil_space_flags( /*===========*/ fil_space_t* space); /*!< in: space */ - - /****************************************************************//** Does error handling when a file operation fails. @return TRUE if we should retry the operation */ @@ -1580,30 +1325,14 @@ os_file_handle_error_no_exit( /*******************************************************************//** Return page type name */ +UNIV_INLINE const char* fil_get_page_type_name( /*===================*/ ulint page_type); /*!< in: FIL_PAGE_TYPE */ -/** Struct for retreiving info about scrubbing */ -struct fil_space_scrub_status_t { - ulint space; /*!< tablespace id */ - bool compressed; /*!< is space compressed */ - time_t last_scrub_completed; /*!< when was last scrub completed */ - bool scrubbing; /*!< is scrubbing ongoing */ - time_t current_scrub_started; /*!< when started current scrubbing */ - ulint current_scrub_active_threads; /*!< current scrub active threads */ - ulint current_scrub_page_number; /*!< current scrub page no */ - ulint current_scrub_max_page_number; /*!< current scrub max page no */ -}; - -/********************************************************************* -Get scrub status for a space -@return 0 if no scrub info found */ -int -fil_space_get_scrub_status( -/*==================*/ - ulint id, /*!< in: space id */ - struct fil_space_scrub_status_t * status); /*!< out: status */ +#ifndef UNIV_NONINL +#include "fil0fil.ic" +#endif #endif /* fil0fil_h */ diff --git a/storage/xtradb/include/fil0fil.ic b/storage/xtradb/include/fil0fil.ic new file mode 100644 index 00000000000..b1e65e6dddb --- /dev/null +++ b/storage/xtradb/include/fil0fil.ic @@ -0,0 +1,108 @@ +/***************************************************************************** + +Copyright (c) 2015, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fil0fil.ic +The low-level file system support functions + +Created 31/03/2015 Jan Lindström +*******************************************************/ + +#ifndef fil0fil_ic +#define fil0fil_ic + +/*******************************************************************//** +Return space name */ +UNIV_INLINE +char* +fil_space_name( +/*===========*/ + fil_space_t* space) /*!< in: space */ +{ + return (space->name); +} + +/*******************************************************************//** +Return space flags */ +UNIV_INLINE +ulint +fil_space_flags( +/*===========*/ + fil_space_t* space) /*!< in: space */ +{ + return (space->flags); +} + +/*******************************************************************//** +Return page type name */ +UNIV_INLINE +const char* +fil_get_page_type_name( +/*===================*/ + ulint page_type) /*!< in: FIL_PAGE_TYPE */ +{ + switch(page_type) { + case FIL_PAGE_PAGE_COMPRESSED: + return (const char*)"PAGE_COMPRESSED"; + case FIL_PAGE_INDEX: + return (const char*)"INDEX"; + case FIL_PAGE_UNDO_LOG: + return (const char*)"UNDO LOG"; + case FIL_PAGE_INODE: + return (const char*)"INODE"; + case FIL_PAGE_IBUF_FREE_LIST: + return (const char*)"IBUF_FREE_LIST"; + case FIL_PAGE_TYPE_ALLOCATED: + return (const char*)"ALLOCATED"; + case FIL_PAGE_IBUF_BITMAP: + return (const char*)"IBUF_BITMAP"; + case FIL_PAGE_TYPE_SYS: + return (const char*)"SYS"; + case FIL_PAGE_TYPE_TRX_SYS: + return (const char*)"TRX_SYS"; + case FIL_PAGE_TYPE_FSP_HDR: + return (const char*)"FSP_HDR"; + case FIL_PAGE_TYPE_XDES: + return (const char*)"XDES"; + case FIL_PAGE_TYPE_BLOB: + return (const char*)"BLOB"; + case FIL_PAGE_TYPE_ZBLOB: + return (const char*)"ZBLOB"; + case FIL_PAGE_TYPE_ZBLOB2: + return (const char*)"ZBLOB2"; + case FIL_PAGE_TYPE_COMPRESSED: + return (const char*)"ORACLE PAGE COMPRESSED"; + default: + return (const char*)"PAGE TYPE CORRUPTED"; + } +} + +/****************************************************************//** +Get block size from fil node +@return block size*/ +UNIV_INLINE +ulint +fil_node_get_block_size( +/*====================*/ + fil_node_t* node) /*!< in: Node where to get block + size */ +{ + return (node->file_block_size); +} + +#endif /* fil0fil_ic */ diff --git a/storage/xtradb/include/fil0pageencryption.h b/storage/xtradb/include/fil0pageencryption.h deleted file mode 100644 index fa2b1a5c592..00000000000 --- a/storage/xtradb/include/fil0pageencryption.h +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - -Copyright (C) 2014 eperi GmbH. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -#ifndef fil0pageencryption_h -#define fil0pageencryption_h - -#define PAGE_ENCRYPTION_WRONG_KEY 1 -#define PAGE_ENCRYPTION_WRONG_PAGE_TYPE 2 -#define PAGE_ENCRYPTION_ERROR 3 -#define PAGE_ENCRYPTION_KEY_MISSING 4 -#define PAGE_ENCRYPTION_OK 0 -#define PAGE_ENCRYPTION_WILL_NOT_ENCRYPT 5 - -/* This key will be used if nothing else is given */ -#define DEFAULT_ENCRYPTION_KEY 1 - -#include "fsp0fsp.h" -#include "fsp0pageencryption.h" - -/******************************************************************//** -@file include/fil0pageencryption.h -Helper functions for encryption/decryption page data on to table space. - -Created 08/25/2014 -***********************************************************************/ - -/*******************************************************************//** -Find out whether the page is page encrypted. -Returns the page encryption flag of the space, or false if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return true if page encrypted, false if not or space not found */ -ibool -fil_space_is_page_encrypted( -/*========================*/ - ulint id); /*!< in: space id */ - -/*******************************************************************//** -Find out whether the page is page encrypted -@return true if page is page encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_encrypted( -/*==================*/ - const byte *buf); /*!< in: page */ -/*******************************************************************//** -Find out whether the page is page compressed and then encrypted -@return true if page is page compressed+encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_compressed_encrypted( -/*=============================*/ - const byte *buf); /*!< in: page */ - -/*******************************************************************//** -Find out whether the page can be decrypted -@return true if page can be decrypted, false if not. */ -UNIV_INLINE -ulint -fil_page_encryption_status( -/*=======================*/ - const byte *buf); /*!< in: page */ - - -#endif // fil0pageencryption_h diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index 57e5b9490b1..8fdacc51277 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -58,10 +58,6 @@ is found in a remote location, not the default data directory. */ #define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 #define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4 -/** Number of flag bits used to indicate the page compression and compression level */ -#define FSP_FLAGS_WIDTH_PAGE_ENCRYPTION 1 -#define FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY 8 - /** Number of flag bits used to indicate atomic writes for this tablespace */ #define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2 @@ -73,9 +69,7 @@ is found in a remote location, not the default data directory. */ + FSP_FLAGS_WIDTH_DATA_DIR \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY) + + FSP_FLAGS_WIDTH_ATOMIC_WRITES ) /** A mask of all the known/used bits in tablespace flags */ #define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) @@ -99,15 +93,9 @@ dictionary */ /** Zero relative shift position of the ATOMIC_WRITES field */ #define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \ + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL) -/** Zero relative shift position of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_POS_PAGE_ENCRYPTION (FSP_FLAGS_POS_ATOMIC_WRITES \ +/** Zero relative shift position of the PAGE_SSIZE field */ +#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \ + FSP_FLAGS_WIDTH_ATOMIC_WRITES) -/** Zero relative shift position of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY (FSP_FLAGS_POS_PAGE_ENCRYPTION \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION) - /** Zero relative shift position of the PAGE_SSIZE field */ -#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY \ - + FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY) /** Zero relative shift position of the start of the DATA DIR bits */ #define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \ + FSP_FLAGS_WIDTH_PAGE_SSIZE) @@ -143,15 +131,6 @@ dictionary */ #define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \ ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \ << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Bit mask of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_MASK_PAGE_ENCRYPTION \ - ((~(~0 << FSP_FLAGS_WIDTH_PAGE_ENCRYPTION)) \ - << FSP_FLAGS_POS_PAGE_ENCRYPTION) -/** Bit mask of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_MASK_PAGE_ENCRYPTION_KEY \ - ((~(~0 << FSP_FLAGS_WIDTH_PAGE_ENCRYPTION_KEY)) \ - << FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY) - /** Bit mask of the ATOMIC_WRITES field */ #define FSP_FLAGS_MASK_ATOMIC_WRITES \ ((~(~0 << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \ @@ -192,14 +171,6 @@ dictionary */ #define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \ ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \ >> FSP_FLAGS_POS_ATOMIC_WRITES) -/** Return the value of the PAGE_ENCRYPTION field */ -#define FSP_FLAGS_GET_PAGE_ENCRYPTION(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_ENCRYPTION) \ - >> FSP_FLAGS_POS_PAGE_ENCRYPTION) -/** Return the value of the PAGE_ENCRYPTION_KEY field */ -#define FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_ENCRYPTION_KEY) \ - >> FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY) /** Set a PAGE_SSIZE into the correct bits in a given tablespace flags. */ @@ -216,13 +187,6 @@ tablespace flags. */ #define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \ (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)) -/** Set a PAGE_ENCRYPTION into the correct bits in a given tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_ENCRYPTION(flags, encryption) \ - (flags | (encryption << FSP_FLAGS_POS_PAGE_ENCRYPTION)) -/** Set a PAGE_ENCRYPTION_KEY into the correct bits in a given tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_ENCRYPTION_KEY(flags, encryption_key) \ - (flags | (encryption_key << FSP_FLAGS_POS_PAGE_ENCRYPTION_KEY)) - /** Set a ATOMIC_WRITES into the correct bits in a given tablespace flags. */ #define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \ diff --git a/storage/xtradb/include/fsp0pageencryption.h b/storage/xtradb/include/fsp0pageencryption.h deleted file mode 100644 index 631aa72211c..00000000000 --- a/storage/xtradb/include/fsp0pageencryption.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - - Copyright (C) 2014 eperi GmbH. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************/ - -/******************************************************************//** -@file include/fsp0pageencryption.h -Helper functions for extracting/storing page encryption information to file space. - -Created 08/28/2014 -***********************************************************************/ - -#ifndef FSP0PAGEENCRYPTION_H_ -#define FSP0PAGEENCRYPTION_H_ - -#define FIL_PAGE_ENCRYPTION_AES_128 16 /*!< Encryption algorithm AES-128. */ -#define FIL_PAGE_ENCRYPTION_AES_196 24 /*!< Encryption algorithm AES-196. */ -#define FIL_PAGE_ENCRYPTION_AES_256 32 /*!< Encryption algorithm AES-256. */ - -#define FIL_PAGE_ENCRYPTED_SIZE 2 /*!< Number of bytes used to store - actual payload data size onencrypted - pages. */ - -/********************************************************************//** -Determine if the tablespace is page encrypted from dict_table_t::flags. -@return TRUE if page encrypted, FALSE if not page encrypted */ -UNIV_INLINE -ibool -fsp_flags_is_page_encrypted( -/*=========================*/ - ulint flags); /*!< in: tablespace flags */ - - -/********************************************************************//** -Extract the page encryption key from tablespace flags. -A tablespace has only one physical page encryption key -whether that page is encrypted or not. -@return page encryption key of the file-per-table tablespace, -or zero if the table is not encrypted. */ -UNIV_INLINE -ulint -fsp_flags_get_page_encryption_key( -/*=================================*/ - ulint flags); /*!< in: tablespace flags */ - - -#ifndef UNIV_NONINL -#include "fsp0pageencryption.ic" -#endif - - -#endif /* FSP0PAGEENCRYPTION_H_ */ diff --git a/storage/xtradb/include/fsp0pageencryption.ic b/storage/xtradb/include/fsp0pageencryption.ic deleted file mode 100644 index d3137001fc5..00000000000 --- a/storage/xtradb/include/fsp0pageencryption.ic +++ /dev/null @@ -1,168 +0,0 @@ -/***************************************************************************** - - Copyright (C) 2014 eperi GmbH. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -/******************************************************************//** -@file include/fsp0pageencryption.ic -Implementation for helper functions for encrypting/decrypting pages -and atomic writes information to file space. - -Created 08/28/2014 -***********************************************************************/ - -#include "fsp0fsp.h" -#include "fil0pageencryption.h" - -/********************************************************************//** -Determine if the tablespace is page encrypted from dict_table_t::flags. -@return TRUE if page encrypted, FALSE if not page encrypted */ -UNIV_INLINE -ibool -fsp_flags_is_page_encrypted( -/*=========================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_ENCRYPTION(flags)); -} - -/********************************************************************//** -Extract the page encryption key from tablespace flags. -A tablespace has only one physical page encryption key -whether that page is encrypted or not. -@return page encryption key of the file-per-table tablespace, -or zero if the table is not encrypted. */ -UNIV_INLINE -ulint -fsp_flags_get_page_encryption_key( -/*=================================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_ENCRYPTION_KEY(flags)); -} - - -/*******************************************************************//** -Returns the page encryption flag of the space, or false if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return true if page encrypted, false if not or space not found */ -UNIV_INLINE -ibool -fil_space_is_page_encrypted( -/*=========================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_is_page_encrypted(flags)); - } - - return(flags); -} - -/*******************************************************************//** -Returns the page encryption key of the space, or 0 if the space -is not encrypted. The tablespace must be cached in the memory cache. -@return page compression level, ULINT_UNDEFINED if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_encryption_key( -/*=================================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_get_page_encryption_key(flags)); - } - - return(flags); -} - - - -/*******************************************************************//** -Find out whether the page is page encrypted -@return true if page is page encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_encrypted( -/*===================*/ - const byte *buf) /*!< in: page */ -{ - return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_ENCRYPTED); -} - -/*******************************************************************//** -Find out whether the page is page is first compressed and then encrypted -@return true if page is page compressed+encrypted, false if not */ -UNIV_INLINE -ibool -fil_page_is_compressed_encrypted( -/*=============================*/ - const byte *buf) /*!< in: page */ -{ - return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); -} - -/*******************************************************************//** -Find out whether the page can be decrypted. -This is the case, if the page is already decrypted and is not the first page of the table space. -If the page is already decrypted it is not of the FIL_PAGE_PAGE_ENCRYPTED type. -if it is the first page of the table space, it is assumed that a page can be decrypted if the -key found in the flags (part of the 1st page) can be read from the key provider. -The case, if the key changed, is currently not caught. -The function for decrypting the page should already be executed before this. -@return PAGE_ENCRYPTION_KEY_MISSING if key provider is available, but key is not available - PAGE_ENCRYPTION_ERROR if other error occurred - 0 if decryption should be possible -*/ -UNIV_INLINE -ulint -fil_page_encryption_status( -/*===================*/ - const byte *buf) /*!< in: page */ -{ - ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE); - - if (page_type == FIL_PAGE_TYPE_FSP_HDR) { - ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf); - if (fsp_flags_is_page_encrypted(flags)) { - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - /* accessing table would surely fail, because no key or no key provider available */ - if (!has_encryption_key(fsp_flags_get_page_encryption_key(flags))) { - return PAGE_ENCRYPTION_KEY_MISSING; - } - return PAGE_ENCRYPTION_ERROR; - } - } - } - - if(page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - ulint key = mach_read_from_4(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - if (!has_encryption_key(key)) { - return PAGE_ENCRYPTION_KEY_MISSING; - } - return PAGE_ENCRYPTION_ERROR; - } - return 0; -} diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index f00d754ac66..a2996ecacc8 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -715,34 +715,6 @@ fts_drop_index_tables( dict_index_t* index) /*!< in: Index to drop */ __attribute__((nonnull, warn_unused_result)); -/****************************************************************** -Wait for background threads to stop using FTS index -*/ -UNIV_INTERN -void -fts_wait_bg_to_stop_using_index( -/*======================*/ - trx_t* trx, /*!< in: transaction */ - dict_index_t* index, /*!< in: FTS Index */ - bool drop_table); /*!< in: in addition to stop - using index, also prevent - threads from start using it, - used by drop table */ - -/****************************************************************** -Wait for background threads to stop using any FTS index of the table -*/ -UNIV_INTERN -void -fts_wait_bg_to_stop_using_table( -/*======================*/ - trx_t* trx, /*!< in: transaction */ - dict_table_t* table, /*!< in: table to stop threads */ - bool drop_table); /*!< in: in addition to stop - using table, also prevent - threads from start using it, - used by drop table */ - /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ diff --git a/storage/xtradb/include/log0crypt.h b/storage/xtradb/include/log0crypt.h index 9c7c0229ba4..c3cfd973e8d 100644 --- a/storage/xtradb/include/log0crypt.h +++ b/storage/xtradb/include/log0crypt.h @@ -11,11 +11,13 @@ Created 11/25/2013 Minli Zhu #include "ut0byte.h" #include "ut0lst.h" #include "ut0rnd.h" -#include "my_aes.h" +#include "my_crypt.h" #define PURPOSE_BYTE_LEN MY_AES_BLOCK_SIZE - 1 #define PURPOSE_BYTE_OFFSET 0 -#define UNENCRYPTED_KEY_VER 0 +#define UNENCRYPTED_KEY_VER ENCRYPTION_KEY_NOT_ENCRYPTED + +typedef int Crypt_result; /* If true, enable redo log encryption. */ extern my_bool srv_encrypt_log; diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h index cda4a692aec..3b5654b0ddf 100644 --- a/storage/xtradb/include/log0log.h +++ b/storage/xtradb/include/log0log.h @@ -1101,8 +1101,8 @@ struct log_t{ #endif /* UNIV_LOG_ARCHIVE */ extern os_event_t log_scrub_event; -/* log scrubbing interval in ms */ -extern ulonglong innodb_scrub_log_interval; +/* log scrubbing speed, in bytes/sec */ +extern ulonglong innodb_scrub_log_speed; /*****************************************************************//** This is the main thread for log scrub. It waits for an event and diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index f93bf026903..154adf085b8 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -323,24 +323,21 @@ The wrapper functions have the prefix of "innodb_". */ # define os_aio(type, mode, name, file, buf, offset, \ n, message1, message2, space_id, \ - trx, page_compressed, page_compression_level, write_size, \ - page_encryption, page_encryption_key, lsn, encrypt) \ + trx, write_size) \ pfs_os_aio_func(type, mode, name, file, buf, offset, \ - n, message1, message2, space_id, trx, \ - page_compressed, page_compression_level, write_size, \ - page_encryption, page_encryption_key, lsn, encrypt, \ + n, message1, message2, space_id, trx, write_size, \ __FILE__, __LINE__) -# define os_file_read(file, buf, offset, n, compressed) \ - pfs_os_file_read_func(file, buf, offset, n, NULL, compressed, \ +# define os_file_read(file, buf, offset, n) \ + pfs_os_file_read_func(file, buf, offset, n, NULL, \ __FILE__, __LINE__) -# define os_file_read_trx(file, buf, offset, n, trx, compressed) \ - pfs_os_file_read_func(file, buf, offset, n, trx, compressed, \ +# define os_file_read_trx(file, buf, offset, n, trx) \ + pfs_os_file_read_func(file, buf, offset, n, trx, \ __FILE__, __LINE__) -# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ - pfs_os_file_read_no_error_handling_func(file, buf, offset, n, compressed, \ +# define os_file_read_no_error_handling(file, buf, offset, n) \ + pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \ __FILE__, __LINE__) # define os_file_write(name, file, buf, offset, n) \ @@ -376,22 +373,18 @@ to original un-instrumented file I/O APIs */ # define os_file_close(file) os_file_close_func(file) # define os_aio(type, mode, name, file, buf, offset, n, message1, \ - message2, space_id, trx, \ - page_compressed, page_compression_level, write_size, \ - page_encryption, page_encryption_key, lsn, encrypt) \ + message2, space_id, trx, write_size) \ os_aio_func(type, mode, name, file, buf, offset, n, \ - message1, message2, space_id, trx, \ - page_compressed, page_compression_level, write_size, \ - page_encryption, page_encryption_key, lsn, encrypt) + message1, message2, space_id, trx, write_size) -# define os_file_read(file, buf, offset, n, compressed) \ - os_file_read_func(file, buf, offset, n, NULL, compressed) +# define os_file_read(file, buf, offset, n) \ + os_file_read_func(file, buf, offset, n, NULL) -# define os_file_read_trx(file, buf, offset, n, trx, compressed) \ - os_file_read_func(file, buf, offset, n, trx, compressed) +# define os_file_read_trx(file, buf, offset, n, trx) \ + os_file_read_func(file, buf, offset, n, trx) -# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ - os_file_read_no_error_handling_func(file, buf, offset, n, compressed) +# define os_file_read_no_error_handling(file, buf, offset, n) \ + os_file_read_no_error_handling_func(file, buf, offset, n) # define os_file_write(name, file, buf, offset, n) \ os_file_write_func(name, file, buf, offset, n) @@ -747,8 +740,6 @@ pfs_os_file_read_func( os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ trx_t* trx, /*!< in: trx */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -767,8 +758,6 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -801,21 +790,11 @@ pfs_os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ ulint* write_size,/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption - key to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later, /*!< in: should we encrypt ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ /*******************************************************************//** @@ -979,9 +958,7 @@ os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - trx_t* trx, /*!< in: trx */ - ibool compressed); /*!< in: is this file space - compressed ? */ + trx_t* trx); /*!< in: trx */ /*******************************************************************//** Rewind file to its start, read at most size - 1 bytes from it to str, and NUL-terminate str. All errors are silently ignored. This function is @@ -1006,9 +983,7 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed); /*!< in: is this file space - compressed ? */ + ulint n); /*!< in: number of bytes to read */ /*******************************************************************//** NOTE! Use the corresponding macro os_file_write(), not directly this @@ -1194,21 +1169,11 @@ os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size);/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption key - to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later); /*!< in: should we encrypt ? */ /************************************************************************//** Wakes up all async i/o threads so that they know to exit themselves in shutdown. */ diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic index 39599ba2047..b25f1577362 100644 --- a/storage/xtradb/include/os0file.ic +++ b/storage/xtradb/include/os0file.ic @@ -220,23 +220,11 @@ pfs_os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< in: page compression - level to be used */ ulint* write_size,/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption - key to be used */ - - lsn_t lsn, /*!< in: lsn of the newest - modification */ - bool encrypt_later, /*!< in: encrypt later ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -253,8 +241,7 @@ pfs_os_aio_func( result = os_aio_func(type, mode, name, file, buf, offset, n, message1, message2, space_id, trx, - page_compression, page_compression_level, write_size , - page_encryption, page_encryption_key, lsn, encrypt_later); + write_size); register_pfs_file_io_end(locker, n); @@ -276,8 +263,6 @@ pfs_os_file_read_func( os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ trx_t* trx, - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -288,7 +273,7 @@ pfs_os_file_read_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_func(file, buf, offset, n, trx, compressed); + result = os_file_read_func(file, buf, offset, n, trx); register_pfs_file_io_end(locker, n); @@ -311,8 +296,6 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - ibool compressed, /*!< in: is this file space - compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -323,7 +306,7 @@ pfs_os_file_read_no_error_handling_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_no_error_handling_func(file, buf, offset, n, compressed); + result = os_file_read_no_error_handling_func(file, buf, offset, n); register_pfs_file_io_end(locker, n); diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h index 70868463448..094eb0de610 100644 --- a/storage/xtradb/include/srv0mon.h +++ b/storage/xtradb/include/srv0mon.h @@ -329,9 +329,8 @@ enum monitor_id_t { MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR, /* New monitor variables for page encryption */ - MONITOR_OVLD_PAGES_PAGE_ENCRYPTED, - MONITOR_OVLD_PAGES_PAGE_DECRYPTED, - MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR, + MONITOR_OVLD_PAGES_ENCRYPTED, + MONITOR_OVLD_PAGES_DECRYPTED, /* Index related counters */ MONITOR_MODULE_INDEX, diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index de33f767021..b8a57098f40 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -133,12 +133,10 @@ struct srv_stats_t { ulint_ctr_64_t pages_page_decompressed; /* Number of page compression errors */ ulint_ctr_64_t pages_page_compression_error; - /* Number of pages encrypted with page encryption */ - ulint_ctr_64_t pages_page_encrypted; - /* Number of pages decrypted with page encryption */ - ulint_ctr_64_t pages_page_decrypted; - /* Number of page encryption errors */ - ulint_ctr_64_t pages_page_encryption_error; + /* Number of pages encrypted */ + ulint_ctr_64_t pages_encrypted; + /* Number of pages decrypted */ + ulint_ctr_64_t pages_decrypted; /** Number of data read in total (in bytes) */ ulint_ctr_1_t data_read; @@ -685,7 +683,7 @@ extern my_bool srv_print_all_deadlocks; extern my_bool srv_cmp_per_index_enabled; /* is encryption enabled */ -extern my_bool srv_encrypt_tables; +extern ulong srv_encrypt_tables; /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars; @@ -705,9 +703,6 @@ that semaphore times out in InnoDB */ #define DEFAULT_SRV_FATAL_SEMAPHORE_TIMEOUT 600 extern ulong srv_fatal_semaphore_wait_threshold; -/** Default encryption key used for page encryption */ -extern uint srv_default_page_encryption_key; - /** Enable semaphore request instrumentation */ extern my_bool srv_instrument_semaphores; @@ -1238,16 +1233,13 @@ struct export_var_t{ compression */ ib_int64_t innodb_pages_page_compression_error;/*!< Number of page compression errors */ - ib_int64_t innodb_pages_page_encrypted;/*!< Number of pages - encrypted by page encryption */ - ib_int64_t innodb_pages_page_decrypted;/*!< Number of pages - decrypted by page encryption */ - ib_int64_t innodb_pages_page_encryption_error;/*!< Number of page - encryption errors */ + ib_int64_t innodb_pages_encrypted; /*!< Number of pages + encrypted */ + ib_int64_t innodb_pages_decrypted; /*!< Number of pages + decrypted */ ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */ - ulint innodb_sec_rec_cluster_reads_avoided; - /*!< srv_sec_rec_cluster_reads_avoided */ + ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */ ulint innodb_encryption_rotation_pages_read_from_cache; ulint innodb_encryption_rotation_pages_read_from_disk; diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc index abebdd8c61a..c3c943a808f 100644 --- a/storage/xtradb/log/log0crypt.cc +++ b/storage/xtradb/log/log0crypt.cc @@ -26,13 +26,12 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "m_string.h" #include "log0crypt.h" #include -#include +#include #include "log0log.h" #include "srv0start.h" // for srv_start_lsn #include "log0recv.h" // for recv_sys -#include "mysql/plugin_encryption_key_management.h" // for BAD_ENCRYPTION_KEY_VERSION #include "ha_prototypes.h" // IB_LOG_ /* If true, enable redo log encryption. */ @@ -48,6 +47,8 @@ byte redo_log_crypt_msg[MY_AES_BLOCK_SIZE] = {0}; * encryption/decryption. */ byte aes_ctr_nonce[MY_AES_BLOCK_SIZE] = {0}; +#define LOG_DEFAULT_ENCRYPTION_KEY 1 + /*********************************************************************//** Generate a 128-bit value used to generate crypt key for redo log. It is generated via the concatenation of 1 purpose byte (0x02) and 15-byte @@ -70,7 +71,7 @@ log_init_crypt_msg_and_nonce(void) /*==============================*/ { mach_write_to_1(redo_log_crypt_msg, redo_log_purpose_byte); - if (my_random_bytes(redo_log_crypt_msg + 1, PURPOSE_BYTE_LEN) != AES_OK) + if (my_random_bytes(redo_log_crypt_msg + 1, PURPOSE_BYTE_LEN) != MY_AES_OK) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: generate " @@ -79,7 +80,7 @@ log_init_crypt_msg_and_nonce(void) abort(); } - if (my_random_bytes(aes_ctr_nonce, MY_AES_BLOCK_SIZE) != AES_OK) + if (my_random_bytes(aes_ctr_nonce, MY_AES_BLOCK_SIZE) != MY_AES_OK) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: generate " @@ -117,7 +118,8 @@ log_init_crypt_key( } byte mysqld_key[MY_AES_BLOCK_SIZE] = {0}; - if (get_encryption_key(crypt_ver, mysqld_key, MY_AES_BLOCK_SIZE)) + uint keylen= sizeof(mysqld_key); + if (encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY, crypt_ver, mysqld_key, &keylen)) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: getting mysqld crypto key " @@ -126,14 +128,12 @@ log_init_crypt_key( } uint32 dst_len; - my_aes_encrypt_dynamic_type func= get_aes_encrypt_func(MY_AES_ALGORITHM_ECB); - int rc= (*func)(crypt_msg, MY_AES_BLOCK_SIZE, //src, srclen + int rc= my_aes_encrypt_ecb(crypt_msg, MY_AES_BLOCK_SIZE, //src, srclen key, &dst_len, //dst, &dstlen (unsigned char*)&mysqld_key, sizeof(mysqld_key), - NULL, 0, - 1); + NULL, 0, 1); - if (rc != AES_OK || dst_len != MY_AES_BLOCK_SIZE) + if (rc != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) { ib_logf(IB_LOG_LEVEL_ERROR, "Redo log crypto: getting redo log crypto key " @@ -170,23 +170,12 @@ log_blocks_crypt( const bool is_encrypt) /*!< in: encrypt or decrypt*/ { byte *log_block = (byte*)block; - Crypt_result rc = AES_OK; + Crypt_result rc = MY_AES_OK; uint32 src_len, dst_len; byte aes_ctr_counter[MY_AES_BLOCK_SIZE]; ulint log_block_no, log_block_start_lsn; - byte *key; - ulint lsn; - if (is_encrypt) - { - ut_a(log_sys && log_sys->redo_log_crypt_ver != UNENCRYPTED_KEY_VER); - key = (byte *)(log_sys->redo_log_crypt_key); - lsn = log_sys->lsn; + ulint lsn = is_encrypt ? log_sys->lsn : srv_start_lsn; - } else { - ut_a(recv_sys && recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER); - key = (byte *)(recv_sys->recv_log_crypt_key); - lsn = srv_start_lsn; - } ut_a(size % OS_FILE_LOG_BLOCK_SIZE == 0); src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE; for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) @@ -206,13 +195,28 @@ log_blocks_crypt( mach_write_to_4(aes_ctr_counter + 11, log_block_no); bzero(aes_ctr_counter + 15, 1); - int rc = (* my_aes_encrypt_dynamic)(log_block + LOG_BLOCK_HDR_SIZE, src_len, - dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, - (unsigned char*)key, 16, - aes_ctr_counter, MY_AES_BLOCK_SIZE, - 1); + int rc; + if (is_encrypt) { + ut_a(log_sys); + ut_a(log_sys->redo_log_crypt_ver != UNENCRYPTED_KEY_VER); + rc = encryption_encrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len, + dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, + (unsigned char*)(log_sys->redo_log_crypt_key), 16, + aes_ctr_counter, MY_AES_BLOCK_SIZE, 1, + LOG_DEFAULT_ENCRYPTION_KEY, + log_sys->redo_log_crypt_ver); + } else { + ut_a(recv_sys); + ut_a(recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER); + rc = encryption_decrypt(log_block + LOG_BLOCK_HDR_SIZE, src_len, + dst_block + LOG_BLOCK_HDR_SIZE, &dst_len, + (unsigned char*)(recv_sys->recv_log_crypt_key), 16, + aes_ctr_counter, MY_AES_BLOCK_SIZE, 1, + LOG_DEFAULT_ENCRYPTION_KEY, + recv_sys->recv_log_crypt_ver); + } - ut_a(rc == AES_OK); + ut_a(rc == MY_AES_OK); ut_a(dst_len == src_len); log_block += OS_FILE_LOG_BLOCK_SIZE; dst_block += OS_FILE_LOG_BLOCK_SIZE; @@ -261,12 +265,11 @@ log_crypt_set_ver_and_key( if (srv_encrypt_log) { unsigned int vkey; - vkey = get_latest_encryption_key_version(); + vkey = encryption_key_get_latest_version(LOG_DEFAULT_ENCRYPTION_KEY); encrypted = true; if (vkey == UNENCRYPTED_KEY_VER || - vkey == BAD_ENCRYPTION_KEY_VERSION || - vkey == (unsigned int)CRYPT_KEY_UNKNOWN) { + vkey == ENCRYPTION_KEY_VERSION_INVALID) { encrypted = false; ib_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc index 37cf18c1a0d..9fee7aba47c 100644 --- a/storage/xtradb/log/log0log.cc +++ b/storage/xtradb/log/log0log.cc @@ -1384,7 +1384,7 @@ log_group_file_header_flush( (ulint) (dest_offset / UNIV_PAGE_SIZE), (ulint) (dest_offset % UNIV_PAGE_SIZE), OS_FILE_LOG_BLOCK_SIZE, - buf, group, 0, 0, false); + buf, group, 0); srv_stats.os_log_pending_writes.dec(); } @@ -1415,7 +1415,7 @@ log_group_encrypt_before_write( const ulint size) /*!< in: size of log blocks */ { - Crypt_result result = AES_OK; + Crypt_result result = MY_AES_OK; ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0); byte* dst_frame = (byte*)malloc(size); @@ -1423,14 +1423,14 @@ log_group_encrypt_before_write( //encrypt log blocks content result = log_blocks_encrypt(block, size, dst_frame); - if (result == AES_OK) + if (result == MY_AES_OK) { ut_ad(block[0] == dst_frame[0]); memcpy(block, dst_frame, size); } free(dst_frame); - return (result == AES_OK); + return (result == MY_AES_OK); } /******************************************************//** @@ -1551,7 +1551,7 @@ loop: fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, group->space_id, 0, (ulint) (next_offset / UNIV_PAGE_SIZE), (ulint) (next_offset % UNIV_PAGE_SIZE), write_len, buf, - group, 0, 0, false); + group, 0); srv_stats.os_log_pending_writes.dec(); @@ -2144,7 +2144,7 @@ log_group_checkpoint( write_offset / UNIV_PAGE_SIZE, write_offset % UNIV_PAGE_SIZE, OS_FILE_LOG_BLOCK_SIZE, - buf, ((byte*) group + 1), 0, 0, false); + buf, ((byte*) group + 1), 0); ut_ad(((ulint) group & 0x1UL) == 0); } @@ -2226,7 +2226,7 @@ log_group_read_checkpoint_info( fil_io(OS_FILE_READ | OS_FILE_LOG, true, group->space_id, 0, field / UNIV_PAGE_SIZE, field % UNIV_PAGE_SIZE, - OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL, 0, 0, false); + OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL, 0); } /******************************************************//** @@ -2572,13 +2572,13 @@ log_group_decrypt_after_read( // decrypt log blocks content result = log_blocks_decrypt(frame, size, dst_frame); - if (result == AES_OK) + if (result == MY_AES_OK) { memcpy(frame, dst_frame, size); } free(dst_frame); - return (result == AES_OK); + return (result == MY_AES_OK); } /******************************************************//** @@ -2639,7 +2639,7 @@ loop: fil_io(OS_FILE_READ | OS_FILE_LOG, sync, group->space_id, 0, (ulint) (source_offset / UNIV_PAGE_SIZE), (ulint) (source_offset % UNIV_PAGE_SIZE), - len, buf, (type == LOG_ARCHIVE) ? &log_archive_io : NULL, 0, 0, false); + len, buf, (type == LOG_ARCHIVE) ? &log_archive_io : NULL, 0); if (recv_sys->recv_log_crypt_ver != UNENCRYPTED_KEY_VER && !log_group_decrypt_after_read(group, buf, len)) @@ -2771,7 +2771,7 @@ log_group_archive_file_header_write( dest_offset / UNIV_PAGE_SIZE, dest_offset % UNIV_PAGE_SIZE, 2 * OS_FILE_LOG_BLOCK_SIZE, - buf, &log_archive_io, 0, 0, false); + buf, &log_archive_io, 0); } /******************************************************//** @@ -2808,7 +2808,7 @@ log_group_archive_completed_header_write( dest_offset % UNIV_PAGE_SIZE, OS_FILE_LOG_BLOCK_SIZE, buf + LOG_FILE_ARCH_COMPLETED, - &log_archive_io, 0, 0, false); + &log_archive_io, 0); } /******************************************************//** @@ -2953,7 +2953,7 @@ loop: (ulint) (next_offset / UNIV_PAGE_SIZE), (ulint) (next_offset % UNIV_PAGE_SIZE), ut_calc_align(len, OS_FILE_LOG_BLOCK_SIZE), buf, - &log_archive_io, 0, 0, false); + &log_archive_io, 0); start_lsn += len; next_offset += len; @@ -4187,8 +4187,8 @@ log_scrub() next_lbn_to_pad = log_block_convert_lsn_to_no(log_sys->lsn); } -/* log scrubbing interval in ms. */ -UNIV_INTERN ulonglong innodb_scrub_log_interval; +/* log scrubbing speed, in bytes/sec */ +UNIV_INTERN ulonglong innodb_scrub_log_speed; /*****************************************************************//** This is the main thread for log scrub. It waits for an event and @@ -4208,7 +4208,10 @@ DECLARE_THREAD(log_scrub_thread)( while(srv_shutdown_state == SRV_SHUTDOWN_NONE) { - os_event_wait_time(log_scrub_event, innodb_scrub_log_interval * 1000); + /* log scrubbing interval in µs. */ + ulonglong interval = 1000*1000*512/innodb_scrub_log_speed; + + os_event_wait_time(log_scrub_event, interval); log_scrub(); diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc index 60ae4a50626..e18677973b0 100644 --- a/storage/xtradb/log/log0online.cc +++ b/storage/xtradb/log/log0online.cc @@ -283,7 +283,7 @@ log_online_read_bitmap_page( ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0); success = os_file_read(bitmap_file->file, page, bitmap_file->offset, - MODIFIED_PAGE_BLOCK_SIZE, FALSE); + MODIFIED_PAGE_BLOCK_SIZE); if (UNIV_UNLIKELY(!success)) { diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index c7fb3be9625..46f5954d44f 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -56,6 +56,7 @@ Created 9/20/1997 Heikki Tuuri #include "trx0undo.h" #include "trx0rec.h" #include "fil0fil.h" +#include "fil0crypt.h" #ifndef UNIV_HOTBACKUP # include "buf0rea.h" # include "srv0srv.h" @@ -3177,7 +3178,7 @@ recv_recovery_from_checkpoint_start_func( fil_io(OS_FILE_READ | OS_FILE_LOG, true, max_cp_group->space_id, 0, 0, 0, LOG_FILE_HDR_SIZE, - log_hdr_buf, max_cp_group, 0, 0, false); + log_hdr_buf, max_cp_group, 0); if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, (byte*)"ibbackup", (sizeof "ibbackup") - 1)) { @@ -3208,7 +3209,7 @@ recv_recovery_from_checkpoint_start_func( fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, max_cp_group->space_id, 0, 0, 0, OS_FILE_LOG_BLOCK_SIZE, - log_hdr_buf, max_cp_group, 0, 0, false); + log_hdr_buf, max_cp_group, 0); } log_hdr_log_block_size @@ -3871,7 +3872,7 @@ ask_again: /* Read the archive file header */ fil_io(OS_FILE_READ | OS_FILE_LOG, true, group->archive_space_id, 0, 0, 0, - LOG_FILE_HDR_SIZE, buf, NULL, 0, 0, false); + LOG_FILE_HDR_SIZE, buf, NULL, 0); /* Check if the archive file header is consistent */ @@ -3945,7 +3946,7 @@ ask_again: fil_io(OS_FILE_READ | OS_FILE_LOG, true, group->archive_space_id, 0, read_offset / UNIV_PAGE_SIZE, - read_offset % UNIV_PAGE_SIZE, len, buf, NULL, 0, 0, false); + read_offset % UNIV_PAGE_SIZE, len, buf, NULL, 0); ret = recv_scan_log_recs( (buf_pool_get_n_pages() diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index d7d224dc6dd..75750df5639 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -45,7 +45,6 @@ Created 10/21/1995 Heikki Tuuri #include "fil0fil.h" #include "fsp0fsp.h" #include "fil0pagecompress.h" -#include "fil0pageencryption.h" #include "buf0buf.h" #include "btr0types.h" #include "trx0trx.h" @@ -238,21 +237,6 @@ struct os_aio_slot_t{ completed */ ulint bitmap; - byte* page_compression_page; /*!< Memory allocated for - page compressed page and - freed after the write - has been completed */ - - byte* page_encryption_page; /*!< Memory allocated for - page encrypted page and - freed after the write - has been completed */ - - ibool page_compression; - ulint page_compression_level; - - ibool page_encryption; - ulint page_encryption_key; ulint* write_size; /*!< Actual write size initialized after fist successfull trim @@ -260,31 +244,13 @@ struct os_aio_slot_t{ initialized we do not trim again if actual page size does not decrease. */ - byte* page_buf; /*!< Actual page buffer for - page compressed pages, do not - free this */ - - byte* page_buf2; /*!< Actual page buffer for - page encrypted pages, do not - free this */ - byte* tmp_encryption_buf; /*!< a temporal buffer used by page encryption */ - - ibool page_compression_success; - /*!< TRUE if page compression was successfull, false if not */ - ibool page_encryption_success; - /*!< TRUE if page encryption was successfull, false if not */ - - lsn_t lsn; /* lsn of the newest modification */ - ulint file_block_size;/*!< file block size */ - bool encrypt_later; /*!< should we encrypt the page */ #ifdef LINUX_NATIVE_AIO struct iocb control; /* Linux control block for aio */ int n_bytes; /* bytes written/read. */ int ret; /* AIO return code */ #endif /* WIN_ASYNC_IO */ - byte *lzo_mem; /* Temporal memory used by LZO */ }; /** The asynchronous i/o array structure */ @@ -401,39 +367,6 @@ os_file_trim( /*=========*/ os_aio_slot_t* slot); /*!< in: slot structure */ -/**********************************************************************//** -Allocate memory for temporal buffer used for page compression. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf( -/*===================*/ - os_aio_slot_t* slot); /*!< in: slot structure */ - -#ifdef HAVE_LZO -/**********************************************************************//** -Allocate memory for temporal memory used for page compression when -LZO compression method is used */ -UNIV_INTERN -void -os_slot_alloc_lzo_mem( -/*===================*/ - os_aio_slot_t* slot); /*!< in: slot structure */ -#endif - -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf2( - os_aio_slot_t* slot); /*!< in: slot structure */ -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. */ -UNIV_INTERN -void -os_slot_alloc_tmp_encryption_buf( - os_aio_slot_t* slot); /*!< in: slot structure */ /****************************************************************//** Does error handling when a file operation fails. @return TRUE if we should retry the operation */ @@ -3114,9 +3047,7 @@ os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - trx_t* trx, - ibool compressed) /*!< in: is this file space - compressed ? */ + trx_t* trx) { #ifdef __WIN__ BOOL ret; @@ -3212,9 +3143,7 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n, /*!< in: number of bytes to read */ - ibool compressed) /*!< in: is this file space - compressed ? */ + ulint n) /*!< in: number of bytes to read */ { #ifdef __WIN__ BOOL ret; @@ -4275,8 +4204,6 @@ os_aio_array_free( /*==============*/ os_aio_array_t*& array) /*!< in, own: array to free */ { - ulint i; - os_mutex_free(array->mutex); os_event_free(array->not_full); os_event_free(array->is_empty); @@ -4288,31 +4215,6 @@ os_aio_array_free( } #endif /* LINUX_NATIVE_AIO */ - for (i = 0; i < array->n_slots; i++) { - os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); - - if (slot->page_compression_page) { - ut_free(slot->page_compression_page); - slot->page_compression_page = NULL; - } - - if (slot->lzo_mem) { - ut_free(slot->lzo_mem); - slot->lzo_mem = NULL; - } - - if (slot->page_encryption_page) { - ut_free(slot->page_encryption_page); - slot->page_encryption_page = NULL; - } - - if (slot->tmp_encryption_buf) { - ut_free(slot->tmp_encryption_buf); - slot->tmp_encryption_buf = NULL; - } - } - - ut_free(array->slots); ut_free(array); @@ -4658,22 +4560,11 @@ os_aio_array_reserve_slot( os_offset_t offset, /*!< in: file offset */ ulint len, /*!< in: length of the block to read or write */ ulint space_id, - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< page encryption key - to be used */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size)/*!< in/out: Actual write size initialized after first successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - lsn_t lsn, /*!< in: lsn of the newest - modification */ - bool encrypt_later) /*!< in: should we encrypt the page */ { os_aio_slot_t* slot = NULL; #ifdef WIN_ASYNC_IO @@ -4762,96 +4653,13 @@ found: slot->type = type; slot->buf = static_cast(buf); slot->offset = offset; - slot->lsn = lsn; slot->io_already_done = FALSE; slot->space_id = space_id; - slot->page_compression_success = FALSE; - slot->page_encryption_success = FALSE; - slot->write_size = write_size; - slot->page_compression_level = page_compression_level; - slot->page_compression = page_compression; - slot->page_encryption_key = page_encryption_key; - slot->page_encryption = page_encryption; - slot->encrypt_later = encrypt_later; if (message1) { slot->file_block_size = fil_node_get_block_size(message1); } - - /* If the space is page compressed and this is write operation - then we encrypt the page */ - if (message1 && type == OS_FILE_WRITE && page_compression) { - ulint real_len = len; - byte* tmp = NULL; - - /* Release the array mutex while encrypting */ - os_mutex_exit(array->mutex); - - // We allocate memory for page compressed buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf(slot); - -#ifdef HAVE_LZO - if (innodb_compression_algorithm == 3) { - os_slot_alloc_lzo_mem(slot); - } -#endif - - /* Call page compression */ - tmp = fil_compress_page( - fil_node_get_space_id(slot->message1), - (byte *)buf, - slot->page_buf, - len, - page_compression_level, - fil_node_get_block_size(slot->message1), - &real_len, - slot->lzo_mem - ); - - /* If compression succeeded, set up the length and buffer */ - if (tmp != buf) { - len = real_len; - buf = slot->page_buf; - slot->len = real_len; - slot->page_compression_success = TRUE; - } else { - slot->page_compression_success = FALSE; - } - - /* Take array mutex back, not sure if this is really needed - below */ - os_mutex_enter(array->mutex); - - } - - /* If the space is page encryption and this is write operation - then we encrypt the page */ - if (message1 && type == OS_FILE_WRITE && (page_encryption || encrypt_later)) { - /* Release the array mutex while encrypting */ - os_mutex_exit(array->mutex); - - // We allocate memory for page encrypted buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf2(slot); - - fil_space_encrypt( - fil_node_get_space_id(slot->message1), - slot->offset, - slot->lsn, - (byte *)buf, - slot->len, - slot->page_buf2, - slot->page_encryption_key); - - slot->page_encryption_success = TRUE; - buf = slot->page_buf2; - - /* Take array mutex back */ - os_mutex_enter(array->mutex); - } - slot->buf = (byte *)buf; #ifdef WIN_ASYNC_IO @@ -5130,22 +4938,11 @@ os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ibool page_compression, /*!< in: is page compression used - on this file space */ - ulint page_compression_level, /*!< page compression - level to be used */ - ulint* write_size,/*!< in/out: Actual write size initialized + ulint* write_size)/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - ibool page_encryption, /*!< in: is page encryption used - on this file space */ - ulint page_encryption_key, /*!< in: page encryption key - to be used */ - lsn_t lsn, /*!< in: lsn of the newest modification */ - bool encrypt_later) /*!< in: should we encrypt before - writing the page */ { os_aio_array_t* array; os_aio_slot_t* slot; @@ -5178,8 +4975,7 @@ os_aio_func( no need to use an i/o-handler thread */ if (type == OS_FILE_READ) { - ret = os_file_read_func(file, buf, offset, n, trx, - page_compression); + ret = os_file_read_func(file, buf, offset, n, trx); } else { ut_ad(!srv_read_only_mode); ut_a(type == OS_FILE_WRITE); @@ -5247,9 +5043,7 @@ try_again: slot = os_aio_array_reserve_slot(type, array, message1, message2, file, name, buf, offset, n, space_id, - page_compression, page_compression_level, - page_encryption, page_encryption_key, - write_size, lsn, encrypt_later); + write_size); if (type == OS_FILE_READ) { if (srv_use_native_aio) { @@ -5278,15 +5072,8 @@ try_again: if (srv_use_native_aio) { os_n_file_writes++; #ifdef WIN_ASYNC_IO - if (page_encryption && slot->page_encryption_success) { - buffer = slot->page_buf2; - n = slot->len; - } else if (page_compression && slot->page_compression_success) { - buffer = slot->page_buf; - n = slot->len; - } else { - buffer = buf; - } + n = slot->len; + buffer = buf; ret = WriteFile(file, buffer, (DWORD) n, &len, &(slot->control)); @@ -5445,22 +5232,12 @@ os_aio_windows_handle( switch (slot->type) { case OS_FILE_WRITE: - if (slot->message1 && slot->page_encryption && slot->page_encryption_success) { - ret_val = os_file_write(slot->name, slot->file, slot->page_buf2, - slot->offset, slot->len); - } else { - if (slot->message1 && slot->page_compression && slot->page_compression_success) { - ret_val = os_file_write(slot->name, slot->file, slot->page_buf, + ret_val = os_file_write(slot->name, slot->file, slot->buf, slot->offset, slot->len); - } else { - ret_val = os_file_write(slot->name, slot->file, slot->buf, - slot->offset, slot->len); - } - } break; case OS_FILE_READ: ret_val = os_file_read(slot->file, slot->buf, - slot->offset, slot->len, slot->page_compression); + slot->offset, slot->len); break; default: ut_error; @@ -5485,45 +5262,10 @@ os_aio_windows_handle( ret_val = ret && len == slot->len; } - if (slot->type == OS_FILE_READ) { - if (fil_page_is_compressed_encrypted(slot->buf) || - fil_page_is_encrypted(slot->buf)) { - ut_ad(slot->message1 != NULL); - os_slot_alloc_page_buf2(slot); - os_slot_alloc_tmp_encryption_buf(slot); - - // Decrypt the data - fil_space_decrypt( - fil_node_get_space_id(slot->message1), - slot->buf, - slot->len, - slot->page_buf2); - // Copy decrypted buffer back to buf - memcpy(slot->buf, slot->page_buf2, slot->len); - } - - if (fil_page_is_compressed(slot->buf)) { - /* We allocate memory for page compressed buffer if - and only if it is not yet allocated. */ - os_slot_alloc_page_buf(slot); - -#ifdef HAVE_LZO - if (fil_page_is_lzo_compressed(slot->buf)) { - os_slot_alloc_lzo_mem(slot); - } -#endif - fil_decompress_page(slot->page_buf, slot->buf, - slot->len, slot->write_size); - } - } else { - /* OS_FILE_WRITE */ - if (slot->page_compression_success && - (fil_page_is_compressed(slot->page_buf) || - fil_page_is_compressed_encrypted(slot->buf))) { - if (srv_use_trim && os_fallocate_failed == FALSE) { - // Deallocate unused blocks from file system - os_file_trim(slot); - } + if (slot->type == OS_FILE_WRITE) { + if (srv_use_trim && os_fallocate_failed == FALSE) { + // Deallocate unused blocks from file system + os_file_trim(slot); } } @@ -5616,48 +5358,10 @@ retry: /* We have not overstepped to next segment. */ ut_a(slot->pos < end_pos); - if (slot->type == OS_FILE_READ) { - /* If the page is page encrypted we decrypt */ - if (fil_page_is_compressed_encrypted(slot->buf) || - fil_page_is_encrypted(slot->buf)) { - os_slot_alloc_page_buf2(slot); - os_slot_alloc_tmp_encryption_buf(slot); - ut_ad(slot->message1 != NULL); - - // Decrypt the data - fil_space_decrypt(fil_node_get_space_id(slot->message1), - slot->buf, - slot->len, - slot->page_buf2); - // Copy decrypted buffer back to buf - memcpy(slot->buf, slot->page_buf2, slot->len); - } - - /* If the table is page compressed and this - is read, we decompress before we announce - the read is complete. For writes, we free - the compressed page. */ - if (fil_page_is_compressed(slot->buf)) { - // We allocate memory for page compressed buffer if and only - // if it is not yet allocated. - os_slot_alloc_page_buf(slot); -#ifdef HAVE_LZO - if (fil_page_is_lzo_compressed(slot->buf)) { - os_slot_alloc_lzo_mem(slot); - } -#endif - fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size); - } - } else { - /* OS_FILE_WRITE */ - if (slot->page_compression_success && - (fil_page_is_compressed(slot->page_buf) || - fil_page_is_compressed_encrypted(slot->buf))) { - ut_ad(slot->page_compression_page); - if (srv_use_trim && os_fallocate_failed == FALSE) { - // Deallocate unused blocks from file system - os_file_trim(slot); - } + if (slot->type == OS_FILE_WRITE) { + if (srv_use_trim && os_fallocate_failed == FALSE) { + // Deallocate unused blocks from file system + os_file_trim(slot); } } @@ -6140,8 +5844,7 @@ consecutive_loop: } else { ret = os_file_read( aio_slot->file, combined_buf, - aio_slot->offset, total_len, - aio_slot->page_compression); + aio_slot->offset, total_len); } srv_set_io_thread_op_info(global_segment, "file i/o done"); @@ -6714,91 +6417,6 @@ os_file_trim( } -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf2( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - - if(slot->page_buf2 == NULL) { - byte* cbuf2; - byte* cbuf; - - cbuf2 = static_cast(ut_malloc(UNIV_PAGE_SIZE*2)); - cbuf = static_cast(ut_align(cbuf2, UNIV_PAGE_SIZE)); - slot->page_encryption_page = static_cast(cbuf2); - slot->page_buf2 = static_cast(cbuf); - memset(slot->page_encryption_page, 0, UNIV_PAGE_SIZE*2); - } -} - -/**********************************************************************//** -Allocate memory for temporal buffer used for page compression. This -buffer is freed later. */ -UNIV_INTERN -void -os_slot_alloc_page_buf( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if (slot->page_buf == NULL) { - byte* cbuf2; - byte* cbuf; - ulint asize = UNIV_PAGE_SIZE; -#ifdef HAVE_SNAPPY - asize += snappy_max_compressed_length(asize) - UNIV_PAGE_SIZE; -#endif - /* We allocate extra to avoid memory overwrite on - compression */ - cbuf2 = static_cast(ut_malloc(asize*2)); - cbuf = static_cast(ut_align(cbuf2, UNIV_PAGE_SIZE)); - slot->page_compression_page = static_cast(cbuf2); - slot->page_buf = static_cast(cbuf); - ut_a(slot->page_buf != NULL); - memset(slot->page_compression_page, 0, asize*2); - } -} - -#ifdef HAVE_LZO -/**********************************************************************//** -Allocate memory for temporal memory used for page compression when -LZO compression method is used */ -UNIV_INTERN -void -os_slot_alloc_lzo_mem( -/*===================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if(slot->lzo_mem == NULL) { - slot->lzo_mem = static_cast(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); - ut_a(slot->lzo_mem != NULL); - memset(slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); - } -} -#endif - -/**********************************************************************//** -Allocate memory for temporal buffer used for page encryption. */ -UNIV_INTERN -void -os_slot_alloc_tmp_encryption_buf( -/*=============================*/ - os_aio_slot_t* slot) /*!< in: slot structure */ -{ - ut_a(slot != NULL); - if (slot->tmp_encryption_buf == NULL) { - slot->tmp_encryption_buf = static_cast(ut_malloc(64)); - memset(slot->tmp_encryption_buf, 0, 64); - } -} - /***********************************************************************//** Try to get number of bytes per sector from file system. @return file block size */ diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index 5a086ccebb4..ac0e75929a4 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -2552,7 +2552,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size, FALSE); + srv_sort_buf_size); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" @@ -3380,7 +3380,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size, FALSE); + srv_sort_buf_size); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 61494bed68a..fc08a4c6f07 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -786,7 +786,7 @@ row_merge_read( #endif /* UNIV_DEBUG */ success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, - ofs, srv_sort_buf_size, FALSE); + ofs, srv_sort_buf_size); #ifdef POSIX_FADV_DONTNEED /* Each block is read exactly once. Free up the file cache. */ diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 5b2b9ac1503..5929bb21f7b 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -57,6 +57,7 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "btr0defragment.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "ibuf0ibuf.h" #include "fts0fts.h" #include "fts0types.h" diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc index 5bac6214c5b..6595c42ca40 100644 --- a/storage/xtradb/srv/srv0mon.cc +++ b/storage/xtradb/srv/srv0mon.cc @@ -985,20 +985,15 @@ static monitor_info_t innodb_counter_info[] = MONITOR_NONE, MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR}, - {"compress_pages_page_encrypted", "compression", - "Number of pages encrypted by page encryption", + {"compress_pages_encrypted", "compression", + "Number of pages encrypted", MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_ENCRYPTED}, + MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_ENCRYPTED}, - {"compress_pages_page_decrypted", "compression", - "Number of pages decrypted by page encryption", + {"compress_pages_decrypted", "compression", + "Number of pages decrypted", MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_DECRYPTED}, - - {"compress_pages_page_encryption_error", "compression", - "Number of page encryption errors ", - MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR}, + MONITOR_DEFAULT_START, MONITOR_OVLD_PAGES_DECRYPTED}, /* ========== Counters for Index ========== */ {"module_index", "index", "Index Manager", @@ -2013,14 +2008,11 @@ srv_mon_process_existing_counter( case MONITOR_OVLD_PAGES_PAGE_COMPRESSION_ERROR: value = srv_stats.pages_page_compression_error; break; - case MONITOR_OVLD_PAGES_PAGE_ENCRYPTED: - value = srv_stats.pages_page_encrypted; + case MONITOR_OVLD_PAGES_ENCRYPTED: + value = srv_stats.pages_encrypted; break; - case MONITOR_OVLD_PAGES_PAGE_DECRYPTED: - value = srv_stats.pages_page_decrypted; - break; - case MONITOR_OVLD_PAGES_PAGE_ENCRYPTION_ERROR: - value = srv_stats.pages_page_encryption_error; + case MONITOR_OVLD_PAGES_DECRYPTED: + value = srv_stats.pages_decrypted; break; default: diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 37adca6975b..ab05605114b 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -75,10 +75,10 @@ Created 10/8/1995 Heikki Tuuri #include "mysql/plugin.h" #include "mysql/service_thd_wait.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "fil0pagecompress.h" #include #include "btr0scrub.h" -#include "fil0pageencryption.h" /* prototypes of new functions added to ha_innodb.cc for kill_idle_transaction */ ibool innobase_thd_is_idle(const void* thd); @@ -670,9 +670,6 @@ thread ensures that we flush the log files at least once per second. */ static time_t srv_last_log_flush_time; -/** Default encryption key used for page encryption */ -UNIV_INTERN uint srv_default_page_encryption_key = DEFAULT_ENCRYPTION_KEY; - /** Enable semaphore request instrumentation */ UNIV_INTERN my_bool srv_instrument_semaphores = FALSE; @@ -1990,9 +1987,8 @@ srv_export_innodb_status(void) export_vars.innodb_page_compressed_trim_op_saved = srv_stats.page_compressed_trim_op_saved; export_vars.innodb_pages_page_decompressed = srv_stats.pages_page_decompressed; export_vars.innodb_pages_page_compression_error = srv_stats.pages_page_compression_error; - export_vars.innodb_pages_page_decrypted = srv_stats.pages_page_decrypted; - export_vars.innodb_pages_page_encrypted = srv_stats.pages_page_encrypted; - export_vars.innodb_pages_page_encryption_error = srv_stats.pages_page_encryption_error; + export_vars.innodb_pages_decrypted = srv_stats.pages_decrypted; + export_vars.innodb_pages_encrypted = srv_stats.pages_encrypted; export_vars.innodb_defragment_compression_failures = btr_defragment_compression_failures; diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index ddf261cc236..e775646cb38 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -3,7 +3,7 @@ Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2015, MariaDB Corporation Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -52,6 +52,7 @@ Created 2/16/1996 Heikki Tuuri #include "os0file.h" #include "os0thread.h" #include "fil0fil.h" +#include "fil0crypt.h" #include "fsp0fsp.h" #include "rem0rec.h" #include "mtr0mtr.h" @@ -1153,7 +1154,7 @@ check_first_page: *sum_of_new_sizes += srv_data_file_sizes[i]; - crypt_data = fil_space_create_crypt_data(); + crypt_data = fil_space_create_crypt_data(FIL_DEFAULT_ENCRYPTION_KEY); } ret = os_file_close(files[i]); diff --git a/tests/test_innodb_log_encryption.sh b/tests/test_innodb_log_encryption.sh deleted file mode 100644 index 774afa76d3b..00000000000 --- a/tests/test_innodb_log_encryption.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash -################################################################## -# - restart server with default (no encryption, no key ver and key). -# - verify various inputs will not corrupt. -# - verify transition from without crypto to with crypto and vice versa work. -# - verify transition from various key versions, including dynamically change it -# after startup, work. -################################################################## -TEST_INSTANCE_NAME="test" -TEST_INSTANCE_DIR="/tmp/instance" -TEST_INSTANCE_PATH=${TEST_INSTANCE_DIR}/${TEST_INSTANCE_NAME} -TEST_INSTANCE_SOCK_FILENAME=mysql.sock -TEST_INSTANCE_SOCK=${TEST_INSTANCE_PATH}/${TEST_INSTANCE_SOCK_FILENAME} -TEST_INSTANCE_ERR_FILE=${TEST_INSTANCE_PATH}/mysql.err -TEST_INSTANCE_DATA_DIR=${TEST_INSTANCE_PATH}/datadir - -google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys" google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--innodb_encrypt_log=1" google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --innodb_encrypt_log=1" google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=11" google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=12 --innodb_encrypt_log=1" google/instance restart ${TEST_INSTANCE_NAME} - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=123 --innodb_encrypt_log=1" google/instance restart ${TEST_INSTANCE_NAME} - -# -- manually create a database sbtest -# mysql> create database sbtest; - -sysbench --test=oltp --oltp-table-size=1000 --mysql-user=root --mysql-socket=${TEST_INSTANCE_SOCK} prepare & - -sysbench --num-threads=10 --test=oltp --oltp-table-size=1000 --mysql-user=root --mysql-socket=${TEST_INSTANCE_SOCK} run & - -# -- change key version through mysql client -# mysql -S ${TEST_INSTANCE_SOCK} k -u root -# mysql> set global variable debug_crypto_key_version=7; -# ps aux | grep mysqld -# -- simulate a fast shutdown -# kill - -MYSQLD_EXTRA_ARGS="--debug_use_static_keys" google/instance restart ${TEST_INSTANCE_NAME} - -google/instance restart ${TEST_INSTANCE_NAME} - -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 - -################################################################## -# - clean shutdown. -# - remove InnoDB redo log files. -# - start the server with encryption on. -# - verify no corruption. -################################################################## -MYSQLD_EXTRA_ARGS="--innodb_fast_shutdown=0" google/instance restart ${TEST_INSTANCE_NAME} -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile0 ${TEST_INSTANCE_DATA_DIR}/ib_logfile0.1 -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile1 ${TEST_INSTANCE_DATA_DIR}/ib_logfile1.1 -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=777 --innodb_encrypt_log=1 --innodb_fast_shutdown=0" google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - clean shutdown. -# - remove InnoDB redo log files. -# - start the server with encryption off. -# - verify no corruption. -################################################################## -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile0 ${TEST_INSTANCE_DATA_DIR}/ib_logfile0.2 -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile1 ${TEST_INSTANCE_DATA_DIR}/ib_logfile1.2 -google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - verify fresh start of mysqld instance with encryption off. -################################################################## -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DIR} ${TEST_INSTANCE_DIR}.200 -google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - verify fresh start of mysqld instance with encryption on. -################################################################## -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DIR} ${TEST_INSTANCE_DIR}.300 -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=888 --innodb_encrypt_log=1" google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - fast shutdown. -# - remove InnoDB redo log files. -# - start the server with encryption on. -# - verify no corruption. -################################################################## -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile0 ${TEST_INSTANCE_DATA_DIR}/ib_logfile0.3 -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile1 ${TEST_INSTANCE_DATA_DIR}/ib_logfile1.3 -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=999 --innodb_encrypt_log=1" google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - fast shutdown while running workload. -# - remove InnoDB redo log files. -# - start the server with encryption on. -# - verify no corruption. -################################################################## -# -- manually create a database sbtest -# mysql> create database sbtest; -sysbench --test=oltp --oltp-table-size=1000 --mysql-user=root --mysql-socket=${TEST_INSTANCE_SOCK} prepare & -sysbench --num-threads=10 --test=oltp --oltp-table-size=1000 --mysql-user=root --mysql-socket=${TEST_INSTANCE_SOCK} run & -google/instance stop ${TEST_INSTANCE_NAME} -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile0 ${TEST_INSTANCE_DATA_DIR}/ib_logfile0.4 -mv ${TEST_INSTANCE_DATA_DIR}/ib_logfile1 ${TEST_INSTANCE_DATA_DIR}/ib_logfile1.4 -MYSQLD_EXTRA_ARGS="--debug_use_static_keys --debug_crypto_key_version=333 --innodb_encrypt_log=1" google/instance start ${TEST_INSTANCE_NAME} -grep -n corrupt ${TEST_INSTANCE_ERR_FILE} | tail -100 -################################################################## -# - clean up -################################################################## -google/instance stop ${TEST_INSTANCE_NAME} -MYSQLD_EXTRA_ARGS="--debug_use_static_keys" google/instance start ${TEST_INSTANCE_NAME} -google/instance stop ${TEST_INSTANCE_NAME}