To preface, the MySqlDb <https://trac.edgewall.org/wiki/MySqlDb#MySQL>
documentation
for Trac states the following:
Tables *must* be created as *InnoDB* or *TokuDB* type tables, because Trac
> uses a transaction mechanism that is not supported by MyISAM tables
>
I've created all my tables using InnoDB and installed Trac 1.2.3.
During trac-admin hotcopy, just before files are copied, trac-admin
executes the following to lock the database:
trac/env.py:1056: # Bogus statement to lock the database while
copying files
trac/env.py-1057- with self.env.db_transaction as db:
trac/env.py-1058- db("UPDATE system SET name=NULL WHERE name IS
NULL")
After the file copy completes, the database is still locked with the
statement above, and it starts the mysqldump; building the mysqldump
command line from the database URL. The initial value is set here:
trac/db/mysql_backend.py:243: args = [self.mysqldump_path,
'--no-defaults']
Note the '--no-defaults' in args[1].
With InnoDB, mysqldump should be run with '--single-transaction', which is
set in the appropriate my.cnf, but since '--no-defaults' is hard-coded, all
my.cnf files are ignored by default.
As a result, mysqldump tries to lock the database before running the dump.
However, the earlier statement is still holding the lock. This never exists
and you have to manually kill the dump or the session holding the earlier
lock.
In the DatabaseBackend
<https://trac.edgewall.org/wiki/DatabaseBackend#MySQL> documentation for
MySQL, there is mention of a parameter 'read_default_file', which you can
include in your 'database' URL, which should then tell mysqldump to read
that my.cnf.
However, when set, it is added to the same constructed mysqldump command
line started in the code above with the following:
trac/db/mysql_backend.py-255- elif name == 'read_default_file':
# Must be first
trac/db/mysql_backend.py:256: args.insert(1,
'--defaults-file=' + value)
This correctly makes '--defaults-file' first, but it pushes the original
first argument ('--no-defaults') to the second argument. These arguments
are mutually exclusive with any version of mysqldump I could find,
resulting in the confusing error:
$ mysqldump --defaults-file=trac/conf/my.cnf --no-defaults
mysqldump: unknown option '--no-defaults'
I had to apply the following patch to resolve this:
--- db/mysql_backend.py.orig 2018-10-27 15:19:15.285092905 -0700
+++ db/mysql_backend.py 2018-10-27 15:11:36.138342337 -0700
@@ -255,3 +255,3 @@
elif name == 'read_default_file': # Must be first
- args.insert(1, '--defaults-file=' + value)
+ args[1] = '--defaults-file=' + value
elif name == 'unix_socket':
The first argument should be replaced, not shifted. This patch and
including 'read_default_file' the database URL resolves the issue.
However, it seems to me that if Trac requires a transactional database, it
should, by default, work with that transactional database. Since the
database is already locked by the earlier statement, Trac could even just
disable all mysqldump locking by default, but ideally the initial lock
should be released once the mysqldump transaction starts to avoid lengthy
and unnecessary database locks.
I also question the use of '--no-defaults' at all. I have 'mysqldump'
working in all other situations, but Trac creates an unexpected situation
where both ~/.my.cnf and /etc/my.cnf are ignored, resulting in obscure
failures.
Has anyone experienced a similar issue or had this work without issue /
patching?
--
You received this message because you are subscribed to the Google Groups "Trac
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.