#3673 closed defect (duplicate)
MySQL error #1071 when creating tables in UTF-8 database
| Reported by: | Owned by: | Christian Boos | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | general | Version: | 0.10b1 |
| Severity: | normal | Keywords: | mysql utf8 primary key |
| Cc: | Branch: | ||
| Release Notes: | |||
| API Changes: | |||
| Internal Changes: | |||
Description
Problem
When trac-admin tries to create the tables in an UTF-8 database
CREATE DATABASE `trac-test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
MySQL error 1071 is raised:
Creating and Initializing Project
Failed to create environment. (1071, 'Specified key was too long; max key length is 1000 bytes')
Traceback (most recent call last):
File "/usr/lib/python2.3/site-packages/trac/scripts/admin.py", line 611, in do_initenv
options=options)
File "/usr/lib/python2.3/site-packages/trac/env.py", line 124, in __init__
self.create(options)
File "/usr/lib/python2.3/site-packages/trac/env.py", line 228, in create
DatabaseManager(self).init_db()
File "/usr/lib/python2.3/site-packages/trac/db/api.py", line 65, in init_db
connector.init_db(**args)
File "/usr/lib/python2.3/site-packages/trac/db/mysql_backend.py", line 50, in init_db
cursor.execute(stmt)
File "/usr/lib/python2.3/site-packages/trac/db/util.py", line 48, in execute
return self.cursor.execute(sql)
File "/usr/lib/python2.3/site-packages/MySQLdb/cursors.py", line 137, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.3/site-packages/MySQLdb/connections.py", line 33, in defaulterrorhandler raise errorclass, errorvalue
OperationalError: (1071, 'Specified key was too long; max key length is 1000 bytes')
Failed to initialize environment. 1
Traceback (most recent call last):
File "/usr/lib/python2.3/site-packages/trac/scripts/admin.py", line 615, in do_initenv
sys.exit(1)
SystemExit: 1
Cause
This is because max key length is 1000 bytes, thus 333 characters in UTF-8. But mysql_backend.py defines 500 chars as maximum value. Thus, the table attachment would have a primary key longer than 1000 bytes:
PRIMARY KEY (`type`(166),`id`(166),`filename`(166)
Quick fix
Change following lines in mysql_backend.py (Trac 0.10b1):
61,62c61 < # In an UTF8 database the limit is 333 characters < limit = 333 / len(columns) --- > limit = 500 / len(columns)
The new primary key is
PRIMARY KEY (`type`(111),`id`(111),`filename`(111)
However, some keys ar shorter than necessary. For example table ticket_change:
PRIMARY KEY (`ticket`,`time`,`field`(111)
This is because the first two keys are of type int(11) and mysql_backend.py just counts the number of keys without checking their type.
Note
You could change the character set of the connection to latin1 and use latin1 database and tables. However, there is an other issue: #3659
Attachments (0)
Change History (6)
comment:1 by , 19 years ago
| Keywords: | mysql utf8 primary key added |
|---|
comment:2 by , 19 years ago
| Milestone: | → 0.10.1 |
|---|---|
| Owner: | changed from to |
comment:3 by , 19 years ago
comment:4 by , 19 years ago
| Milestone: | 0.10.4 |
|---|---|
| Resolution: | → duplicate |
| Status: | new → closed |
See #3676.
comment:5 by , 19 years ago
Hi there,
I think the quick fix is wrong, should it not introduce the 333 number, rather than remove it?
61,62c61 < limit = 500 / len(columns) --- > # In an UTF8 database the limit is 333 characters > limit = 333 / len(columns)
comment:6 by , 19 years ago
If you follow the duplicate track, you'll end up to the applied fix r4755 which effectively introduces the 333 number, so either use trunk or 0.10-stable and all is fine.



see comment:ticket:3659:5 for possible solution