Edgewall Software
Modify

Opened 4 years ago

Closed 4 years ago

#11660 closed defect (fixed)

Trac / Subversion out-of-sync and cannot resync due to IntegrityError

Reported by: david.baran@… Owned by: Jun Omae
Priority: normal Milestone: 0.12.6
Component: version control Version: 1.0
Severity: critical Keywords: svn sync mysql needinfo
Cc:
Release Notes:

Fix raising a TypeError while executing repository sync reponame rev for cached subversion repository.

API Changes:

Description

Using Trac with Subversion, after a large commit set (141 files involved) Trac is out of sync. In log file, following line appeared:

2014-06-24 10:12:38,814 Trac[cache] WARNING: Revision 30759 already cached: IntegrityError(1062, "Duplicate entry '1-0000030759-trunk/tbskernel-parent/tbskernel-server/tbskernel-s' for key 'PRIMARY'")

resync from start failed with same error, and when trying to sync a specific revision, sync or resync commands failed:

Command used:

trac-admin /my-trac repository sync main 30560

Error message:

TypeError: %d format: a number is required, not unicode

In log file:

2014-06-25 09:10:40,407 Trac[env] INFO: -------------------------------- environment startup [Trac 1.0] --------------------------------
2014-06-25 09:10:40,765 Trac[console] ERROR: Exception in trac-admin command:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/admin/console.py", line 108, in onecmd
    rv = cmd.Cmd.onecmd(self, line) or 0
  File "/usr/lib/python2.7/cmd.py", line 220, in onecmd
    return self.default(line)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/admin/console.py", line 284, in default
    return cmd_mgr.execute_command(*args)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/admin/api.py", line 124, in execute_command
    return f(*fargs)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/versioncontrol/admin.py", line 155, in _do_sync
    self._sync(reponame, rev, clean=False)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/versioncontrol/admin.py", line 130, in _sync
    repos.sync_changeset(rev)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/versioncontrol/cache.py", line 104, in sync_changeset
    self._insert_changeset(db, rev, cset)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/trac/versioncontrol/cache.py", line 267, in _insert_changeset
    srev = self.db_rev(rev)
  File "/usr/local/lib/python2.7/dist-packages/Trac-1.0-py2.7.egg/tracopt/versioncontrol/svn/svn_fs.py", line 243, in db_rev
    return '%010d' % rev
TypeError: %d format: a number is required, not unicode

I checked my database collation, seems good:

mysql> connect trac
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Connection id:    2666
Current database: trac

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.00 sec)

How can I resync Trac with my subversion repository?

Attachments (0)

Change History (12)

comment:1 Changed 4 years ago by Jun Omae

Milestone: 0.12.6
Owner: set to Jun Omae
Status: newassigned
Version: 1.0-stable1.0

Good catch!

Reproduced on both 1.0-stable and 0.12-stable. The issue seems to be introduced in 0.12.4.

$ svnadmin create /dev/shm/svnrepos
$ svnadmin load -q /dev/shm/svnrepos < tracopt/versioncontrol/svn/tests/svnrepos.dump
$ ~/venv/trac/1.0/bin/trac-admin /dev/shm/t11660 initenv 'ticket:11660' sqlite:db/trac.db >/dev/null
$ ~/venv/trac/1.0/bin/trac-admin /dev/shm/t11660 config set components 'tracopt.versioncontrol.svn.*' enabled
$ ~/venv/trac/1.0/bin/trac-admin /dev/shm/t11660 config set logging log_type file
$ ~/venv/trac/1.0/bin/trac-admin /dev/shm/t11660 repository add '' /dev/shm/svnrepos
$ ~/venv/trac/1.0/bin/trac-admin /dev/shm/t11660 repository sync '' 1
TypeError: int argument required

I got the same stack trace while reproducing it.

...
  File "/home/jun66j5/venv/trac/1.0/lib/python2.5/site-packages/tracopt/versioncontrol/svn/svn_fs.py", line 243, in db_rev
    return '%010d' % rev
TypeError: int argument required

Applying the following would fix it.

  • trac/versioncontrol/cache.py

    diff --git a/trac/versioncontrol/cache.py b/trac/versioncontrol/cache.py
    index 3a1cb6d..c0c66f8 100644
    a b class CachedRepository(Repository):  
    101101                      """, (to_utimestamp(cset.date), cset.author,
    102102                            cset.message, self.id, srev))
    103103            else:
    104                 self._insert_changeset(db, rev, cset)
     104                self._insert_changeset(db, cset.rev, cset)
    105105        return old_cset
    106106
    107107    @cached('_metadata_id')

comment:2 Changed 4 years ago by anonymous

Hi Jomae,

Your fix resolve [TypeError: ...] problem when I try to sync Trac with my svn repository, but not the database issue, I'm still out of sync.

My current SVN repository changeset is 30826 (checked using svnlook youngest command) but when I try to resync all using resync command without rev option, it stop to 30758, and trac.log contains following lines:

2014-06-27 14:19:38,651 Trac[cache] WARNING: Revision 30759 already cached: IntegrityError(1062, "Duplicate entry '1-0000030759-trunk/tbskernel-parent/tbskernel-server/tbskernel-s' for key 'PRIMARY'")

Thanks for any help.

comment:3 in reply to:  2 Changed 4 years ago by Jun Omae

Replying to anonymous:

My current SVN repository changeset is 30826 (checked using svnlook youngest command) but when I try to resync all using resync command without rev option, it stop to 30758, and trac.log contains following lines:

Hmm. It seems that revision record for revision 30759 is missing but node_change records for revision 30759 are present.

Would you please check existence of the records?

SELECT COUNT(*) FROM revision WHERE repos=1 AND rev='0000030759';
SELECT COUNT(*) FROM node_change WHERE repos=1 AND rev='0000030759';

If the records for the revision are corrupted, to repair is to delete the records and execute repository sync with the revision.

DELETE FROM revision WHERE repos=1 AND rev='0000030759';
DELETE FROM node_change WHERE repos=1 AND rev='0000030759';
trac-admin /my-trac repository sync main 30759

comment:4 Changed 4 years ago by david.baran@…

I tried to remove revision from database and sync again, but I've still the same issue :

IntegrityError: (1062, "Duplicate entry '1-0000030759-trunk/tbskernel-parent/tbskernel-server/tbskernel-s' for key 'PRIMARY'")

I think the 30759 revision contains a lot of files with the same large path, and the primary key is too short to avoid duplicate entry. Can we alter the primary key to make it larger? Bad idea?

comment:5 Changed 4 years ago by Jun Omae

Keywords: mysql added

Indeed. Please check primary key of your node_change using SHOW CREATE TABLE node_change. Typically, node_change has the following.

If the database charset is utf8:

  PRIMARY KEY (`repos`,`rev`(20),`path`(255),`change_type`(2)),

If the database charset is utf8mb4:

  PRIMARY KEY (`repos`,`rev`(20),`path`(191),`change_type`(2)),

But we cannot make path size in the primary key larger caused by mysql limitation.

comment:6 Changed 4 years ago by david.baran@…

Database charset is utf8, so path should be truncated to 255 chars, but here, in the IntegrityError, path seems truncated to 52 chars:

trunk/tbskernel-parent/tbskernel-server/tbskernel-s

In my change set, this path (ending by tbskernel-s) does not exist, it's truncated from tbskernel-server-webapp. So I don't understand why there is a duplicate entry for this primary key.

In the trac sync mechanism, is there a way to bypass a repository revision, and sync from next one?

comment:7 Changed 4 years ago by Jun Omae

I don't understand why. Could you please post output of SHOW CREATE TABLE node_change?

The last synced revision is stored in youngest_rev of repository table. To skip the revision is updating the value to 30760 in your case.

$ ~/venv/trac/1.0.1/bin/trac-admin ~/var/trac/1.0-mysql repository sync '*'
Resyncing repository history for trac.svn...
12866 revisions cached.
Done.
$ mysql -u root
...
mysql> select * from repository;
+----+----------------+----------------------------------------------------------------------------------+
| id | name           | value                                                                            |
+----+----------------+----------------------------------------------------------------------------------+
|  1 | dir            | /home/jun66j5/var/svn/trac.edgewall.org                                          |
|  1 | name           | trac.svn                                                                         |
|  1 | repository_dir | svn:44411793-19fe-4dd3-b1a1-b3b79c121eec:/home/jun66j5/var/svn/trac.edgewall.org |
|  1 | type           | svn                                                                              |
|  1 | youngest_rev   | 12866                                                                            |
+----+----------------+----------------------------------------------------------------------------------+
5 rows in set (0.01 sec)

comment:8 Changed 4 years ago by david.baran@…

Here the output:

mysql> SHOW CREATE TABLE node_change;
+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| node_change | CREATE TABLE `node_change` (
  `repos` int(11) NOT NULL DEFAULT '0',
  `rev` text COLLATE utf8_bin NOT NULL,
  `path` text COLLATE utf8_bin NOT NULL,
  `node_type` text COLLATE utf8_bin,
  `change_type` text COLLATE utf8_bin NOT NULL,
  `base_path` text COLLATE utf8_bin,
  `base_rev` text COLLATE utf8_bin,
  PRIMARY KEY (`repos`,`rev`(20),`path`(255),`change_type`(2)),
  KEY `node_change_repos_rev_idx` (`repos`,`rev`(20))
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

Thanks for the hack, my repository is sync now.

If you need more information to debug this issue, please let me know.

comment:9 Changed 4 years ago by Jun Omae

Thanks for the reply and your help.

Oh, you use MyISAM database engine. All tables in Trac must be created as InnoDB or NDB which support transaction mechanism.

Also, considering the IntegrityError message with primary key,

Duplicate entry '1-0000030759-trunk/tbskernel-parent/tbskernel-server/tbskernel-s' for key 'PRIMARY'

I guess that the inserting record is the following. However, only A, C, D, E and M are used for change_type in Trac.

repos 1
rev(20) 0000030759
path(255) trunk/tbskernel-parent/tbskernel-server/tbskernel
change_type s

Other requests:

  1. Could you provide installed plugins in your environment?
  2. After changing the engines to InnoDB, please enable logging with debug_sql and retry to sync the revision. Then, could you please provide the trac.log?
    [trac]
    debug_sql = enabled
    [logging]
    log_level = DEBUG
    log_type = file
    

comment:10 Changed 4 years ago by Jun Omae

Release Notes: modified (diff)

Fixed raising a TypeError issue on repository sync command in [12882] and merged in [12883-12884].

comment:11 Changed 4 years ago by Jun Omae

Keywords: needinfo added

comment:12 Changed 4 years ago by Jun Omae

Resolution: fixed
Status: assignedclosed

I have not reproduce the original issue yet. But, closing since the second issue about repository sync REPONAME REV has been fixed.

Feel free to reopen it or create a new ticket if you have new information to reproduce. Thanks.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.