Reputation: 51229
When I use rake db:schema:load
to create the following table on my laptop running MySQL 5.6.22, it loads fine:
create_table "inv_audits", force: :cascade do |t|
t.integer "inv_node_id", limit: 2, null: false
t.integer "inv_object_id", limit: 4, null: false
t.integer "inv_version_id", limit: 4, null: false
t.integer "inv_file_id", limit: 4, null: false
t.string "url", limit: 16383
t.string "status", limit: 18, default: "unknown", null: false
t.datetime "created", null: false
t.datetime "verified"
t.datetime "modified"
t.integer "failed_size", limit: 8, default: 0, null: false
t.string "failed_digest_value", limit: 255
t.text "note", limit: 65535
end
However, when I try to do the same thing on my desktop running 5.7.21, it fails with Mysql2::Error: Row size too large.
The generated SQL, from the trace, is:
CREATE TABLE `inv_audits` (
`id` int(11) auto_increment PRIMARY KEY,
`inv_node_id` smallint NOT NULL,
`inv_object_id` int(11) NOT NULL,
`inv_version_id` int(11) NOT NULL,
`inv_file_id` int(11) NOT NULL,
`url` varchar(16383),
`status` varchar(18) DEFAULT 'unknown' NOT NULL,
`created` datetime NOT NULL,
`verified` datetime,
`modified` datetime,
`failed_size` bigint DEFAULT 0 NOT NULL,
`failed_digest_value` varchar(255),
`note` text
) ENGINE=InnoDB
Why would this fail in 5.7 but succeed in 5.6?
Both machines are 64-bit Macs running macOS High Sierra (10.13.4).
Upvotes: 2
Views: 134
Reputation: 108510
The characterset for the character type columns, in particular, the url
VARCHAR
column.
The length attribute on the datatype definition VARCHAR(16383)
specifies a number of characters.
But the InnoDB row size limit is in bytes.
With a single-byte characterset (e.g. latin1) the column would have maximum number of bytes of 16383 (plus space for the hidden length). This would be fine.
With a multi-byte characterset e.g. utf8 (up to 3 bytes per character) or utf8mb4 (up to 4 bytes per character), the number of bytes required will blow past the maximum allowed bytes for InnoDB row.
On the 5.6 system, we can do a
SHOW CREATE TABLE inv_audits
If there's no characterset/collation specified for the column, the default for the table is in effect. (The characterset for the table can be specified, if it's not, it inherits the default set for the database.)
To get the table created on 5.7, as test, cut the VARCHAR size down to 1/4 of the current value, and then take a look at the CREATE TABLE.
SHOW CREATE TABLE inv_audits
And it's going to be a multi-byte characterset like utf8 or utf8mb4.
I'd bet the root cause of the issue is that the default characterset is different in 5.6 and 5.7.
Upvotes: 4