[[PageOutline(2-3)]] = MySQL and its MySQLdb Python bindings Trac supports the [http://mysql.com MySQL] database backend, although there are a couple of [#KnownIssues]. MySQL is fully integrated in our test suite. == Requirements === MySQL '' '''Warning:''' The following guidelines applies to Trac starting with [milestone:0.11.1]. [[br]] For earlier versions of Trac, please see MySqlDb@22#MySQL. '' The recommended versions of MySQL are those from 5.0.x series. The [http://askmonty.org/wiki/index.php/MariaDB MariaDB] variant of MySQL works as well, tested MariaDB 5.3.3, MySQLdb 1.2.3 and Trac 0.12.3. In order to avoid Unicode and international characters problems in Trac, eg international characters turning into question marks with mysterious **"Incorrect string value"** errors logged, the Trac database MUST be configured with the ''`utf8`'' character set and the ''`utf8_bin`'' collation type. Also, all tables MUST be created as **InnoDB** or **TokuDB** type tables, because Trac uses a transaction mechanism that is not supported by MyISAM tables, see [comment:ticket:8067:5] and [http://dev.mysql.com/tech-resources/articles/storage-engine/part_3.html MySQL docs]. Be aware that the cluster storage engine NDB introduces some limits for Trac (#8567). A proper database can be created with any MySQL client, like this: {{{ CREATE DATABASE trac DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; }}} With MySQL version 5.5.3 and up, you can also select the [http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html mb4] variant of utf8, which enables you to store any Unicode character, not only those in the [WikiPedia:Basic_Multilingual_Plane Basic Multilingual Plane]. Note that you'll need at least Trac 0.12.3 for this (#9766). {{{ CREATE DATABASE trac DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; }}} To check character set settings for your database, issue the following commands: {{{ mysql> USE trac; Database changed mysql> SHOW VARIABLES WHERE variable_name IN ('character_set_database', 'collation_database'); +------------------------+----------+ | Variable_name | Value | +------------------------+----------+ | character_set_database | utf8 | | collation_database | utf8_bin | +------------------------+----------+ 2 rows in set (0.01 sec) mysql> }}} If you have for example `latin1` or `utf8` or `utf8_ci` collation, then read on to the [#Conversion] section below on how to change it. If you are setting a new collation on an existing database, make sure that column collations are converted too: {{{ mysql> SHOW FULL COLUMNS FROM `node_change`; +-------------+-------------+-----------+- | Field | Type | Collation | +-------------+-------------+-----------+- | rev | varchar(64) | utf8_bin | | path | text | utf8_bin | | node_type | varchar(32) | utf8_bin | | change_type | varchar(32) | utf8_bin | | base_path | text | utf8_bin | | base_rev | varchar(64) | utf8_bin | +-------------+-------------+-----------+- 6 rows in set (0.00 sec) }}} See #3884 for info about collations. Usually, you also want to create a user and give this user access to the database created above: {{{ GRANT ALL ON trac.* TO tracuser@localhost IDENTIFIED BY 'password'; }}} The connection string will then be: {{{ mysql://tracuser:password@localhost/trac }}} === MySQLdb The recommended version is [https://pypi.python.org/pypi/MySQL-python/ MySQL-python 1.2.2+], which must be compiled in ''thread-safe client'' mode. Earlier versions are known to be problematic. See http://cheeseshop.python.org/pypi/MySQL-python/1.2.2, which contains links to the .tar.gz source distribution as well as pre-built Windows eggs, but for Python 2.5 only as of this writing. Python 2.6 binaries for windows can be found [http://www.codegood.com/archives/4 here], unofficial site. Older versions can be found at the [https://sourceforge.net/projects/mysql-python/ mysql-python] Sourceforge project: || '''Version''' || '''Notes''' || || `MySQL-python 1.2.1_p2` || This was the previously recommended version -- **unsupported** || || `MySQL-python 1.2.0-3.2.2`, `MySQL-python 1.2.2b2` || Reported to have issues (see #3645) -- **unsupported** || || `MySQL-python-1.2.2b2` || Was [googlegroups:trac-users:e291b3ecb4a990a1 reported] to solve an `AttributeError: 'array.array' object has no attribute 'startswith'` error seen when viewing a changeset. These problems ought to be fixed in 1.2.2b3; if they are not, or if you have other issues, please file a bug in the [https://sourceforge.net/tracker/?group_id=22307&atid=374932 MySQL-python Bug Tracker] || On FreeBSD this package is called {{{py-MySQLdb}}} in [http://www.freshports.org/databases/py-MySQLdb55/ the ports collection]. If you are using ActiveState Python 2.6 on Windows, you can install with {{{pypm install mysql-python}}}. ==== Thread-safety is important You should make sure that you're using a thread-safe version of the bindings. To verify this, you can check the ''System Information'' section in the ''About Trac'' page, when you are logged with a user having the `CONFIG_VIEW` or the `TRAC_ADMIN` permission. You should see a line reading: '''MySQL''' `server: "...", client: "...", thread-safe: 1`. If you're seeing `thread-safe: 0` instead, the MySQL-python version you're using was not correctly built. Check the following resources to see what you should do: - [http://mysql-python.svn.sourceforge.net/viewvc/mysql-python/tags/MySQLdb-1.2.3/MySQLdb/README?revision=646 MySQLdb-1.2.3/MySQLdb/README], see the ''Building and installing'' section, - [http://mysql-python.svn.sourceforge.net/viewvc/mysql-python/tags/MySQLdb-1.2.3/MySQLdb/site.cfg?revision=646&content-type=text%2Fplain MySQLdb-1.2.3/MySQLdb/site.cfg] Note that even if you build MySQLdb to use the thread-safe libraries, ''About Trac'' may still report that it is not thread-safe. If that happens, verify that it is thread-safe by calling `MySQLdb.thread_safe()` from a standalone Python script, ie not under Apache. If the stand-alone test reports that MySQLdb is indeed thread-safe, then the problem may lie with the PHP module. For example, the Red Hat rpm for PHP is built to use the non-thread-safe MySQL libraries, and the Apache PHP module apparently gets loaded first. So when Python and MySQLdb load, they end up using the already loaded MySQL libraries, which are not thread-safe. The circumvention for this problem is to replace the non-thread-safe libs in `/usr/lib/mysql` with soft links, so as to have the non-thread-safe lib names point to the thread-safe libs; restart Apache, and now Trac should be running in thread-safe mode. == Conversion Procedures == #Conversion ==== Convert from MyISAM to InnoDB storage engine InnoDB is the default storage engine for MySQL since v5.5, but older databases may be defined using MyISAM. Check which tables are not already converted: {{{ SELECT table_name, engine FROM information_schema.tables WHERE table_schema = DATABASE(); }}} For every table in the Trac database which is not InnoDB run the following: {{{ ALTER TABLE `table_name` ENGINE = InnoDB; }}} ==== Convert to "utf8_bin" collation First modify the DB collation to ensure new tables will be created properly: {{{ ALTER DATABASE `trac_database` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; }}} Then modify the collation for tables. The command below changes the default collation for new columns and converts old columns as well. Run the following for every table: {{{ ALTER TABLE `table_name` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; }}} ==== Convert from SQLite to MySQL To convert from the default database SQLite to MySQL, please follow [wiki:SqLiteToMySql this comprehensive guide]. == Known Issues === Still Opened [[TicketQuery(keywords=~mysql&status=!closed&group=milestone)]] === Troubleshooting If you have an issue, such as `OperationalError: (2006, 'MySQL server has gone away')`, as in #3645, and your web frontend is Apache, you may have conflicting MySQL libraries. Read [mod-wsgi:ApplicationIssues#MySQL_Shared_Library_Conflicts]. Another possibility is that you've hit MySQL bug 36639, as explained in ticket:3645#comment:48. Changing collation to ''utf8'' may fail in MySQL 5.0.x on the MyISAM table type and display the "too big" indexes in some Trac tables. Upgrade to a higher version of MySQL and use InnoDB tables, see [comment:ticket:3659:5]. [[TicketQuery(keywords=~mysql&resolution=worksforme)]] Also noteworthy: [[TicketQuery(id=4378)]] If you get an error from Python when using `trac-admin` like this: {{{ OperationalError: (1045, "Access denied for user 'tracuser'@'localhost' (using password: YES)") }}} There are a few possibilities: 1. Try first to login on the command-line using the user `tracuser`: `mysql -p -h localhost -u tracuser` 1. Created user is not yet used by MySQL. Login to the MySQL server as root with `mysql -p` and type: `FLUSH PRIVILEGES;` 1. The user is added but the host does not match in the MySQL user table (occurred on a FreeBSD setup). Correct this with: `mysql -p; use mysql; UPDATE user SET Host="localhost" WHERE User="tracuser"; FLUSH PRIVILEGES;`