From a1652c196e57f583cd5c95f7f48eeb6d8c8b285d Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 6 Nov 2018 18:08:02 +0900 Subject: MySQL: `ROW_FORMAT=DYNAMIC` create table option by default Since MySQL 5.7.9, the `innodb_default_row_format` option defines the default row format for InnoDB tables. The default setting is `DYNAMIC`. The row format is required for indexing on `varchar(255)` with `utf8mb4` columns. As long as using MySQL 5.6, CI won't be passed even if MySQL server setting is properly configured the same as MySQL 5.7 (`innodb_file_per_table = 1`, `innodb_file_format = 'Barracuda'`, and `innodb_large_prefix = 1`) since InnoDB table is created as the row format `COMPACT` by default on MySQL 5.6, therefore indexing on string with `utf8mb4` columns aren't succeeded. Making `ROW_FORMAT=DYNAMIC` create table option by default for legacy MySQL version would mitigate the indexing issue on the user side, and it makes CI would be passed on MySQL 5.6 which is configured properly. --- .../connection_adapters/mysql/schema_statements.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb index 66db4e4149..47b5c4b9ec 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb @@ -77,6 +77,10 @@ module ActiveRecord super end + def create_table(table_name, options: default_row_format, **) + super + end + def internal_string_options_for_primary_key super.tap do |options| if !row_format_dynamic_by_default? && CHARSETS_OF_4BYTES_MAXLEN.include?(charset) @@ -104,6 +108,20 @@ module ActiveRecord end end + def default_row_format + return if row_format_dynamic_by_default? + + unless defined?(@default_row_format) + if query_value("SELECT @@innodb_file_per_table = 1 AND @@innodb_file_format = 'Barracuda'") == 1 + @default_row_format = "ROW_FORMAT=DYNAMIC" + else + @default_row_format = nil + end + end + + @default_row_format + end + def schema_creation MySQL::SchemaCreation.new(self) end -- cgit v1.2.3