[viewvc-dev] RE: [viewvc-users] checkin DB svn log queries without additional tree change/changeset info

Asd Asdasd <[email protected]> Tue, 14 Jun 2011 21:33:24 -0400
Newsgroups gmane.comp.version-control.cvs.viewcvs.devel
Message-ID <[email protected]>
Hi,

I read bug 433... yes in its entirety :), and I hate to say 
it, but this smells to me like a data generation/semantics issue. Maybe 
I'm jumping the gun, but based on the symptoms, this is the feeling I 
get.

The immediate question I found myself asking while reading bug 433 was:

Why
 should the query result return file/dir information pertaining to a 
particular commit when all we're interested in is a "revision logs" 
listing? Why are we getting the penalty for data we don't want/care for?
 Is is not possible to separate the two?

I see that 
commits.revision in conjunction with 
commits.repositoryid is a good starting point for performing a "unique 
value" query filter for commit log data only, and then using the commits.descid as a FKEY 
to descs.id to get at the log message. Of course the accuracy of this 
depends on how the tables were populated (see methods i and ii below). That is, what uniquely 
represents a commit? Hence the semantics side of things, i.e. do we use the SVN implementation uniquely identifying change sets via global revision IDs or the more looser CVS way of unique log messages. But never the less, supposing all is good and well on that side of things, an an SQL query that might do the job is:

SELECT DISTINCT t1.revision, t1.repositoryid, t1.ci_when, t2.description FROM commits t1 LEFT JOIN descs t2 ON t1.descid = t2.id
 
I haven't fully tested the accuracy of the above vs. my SVN log messages due to point i. below but the count looks in the ballpark of all commits in all repositories used for loading the ViewVC Commit DB.

Now to the ways of loading data into the ViewVC Commit DB, there are two ways.

 i. If the tables were populated in a manner where log messages represent 
(keys) uniquely identify a commit, then for both CVS and SVN based data we might have 
collisions when duplicate log messages occur, e.g. the very common 
"Initial import" log messages. That is, different commits appear as one 
and the same simply because they have the same log message... unique change sets, as defined by SVN, melt into one.
ii. If 
the tables were to be populated by global revision numbers then we are 
good on the SVN-based data side, since this is directly available from 
the repository; uniqueness guaranteed by SVN. But we need to compensate 
for CVS' lack of unique commit ID's.

Based on the previous 
response on the dev list  (http://viewvc.tigris.org/ds/viewMessage.do?dsForumId=4255&dsMessageId=2765316) and the fact that commits.descid != commits.revision, DB 
population is currently done as per i. So why not do things as per ii with an 
additional functionality by "mimicking" global revision numbers for CVS 
data generation, based again on matching log messages, as is done right 
now? It seems fair that since it is CVS that lacks the data for uniquely identifying a change-set (a very useful/powerful concept for version control), it's data 
should be the only one that might get revision referencing (changeset) collisions. 
Currently this CVS limitation is also spilling over for SVN data in the 
Checkin DB. Instead of rewarding SVN data its punishing it to appease CVS :(. 

Looking back at the big picture, it seems that the 
433 stems from the query limiting values, which I remember reading that 
there are four, cfg.cvsdb.row_limit, cfg.options.limit_changes, etc... 
these are intended to reduce the load on the DB in order to keep up its 
performance. Generally when speaking of RDB's, the biggest bottleneck is
 disk I/O. Yes there are buffers/caches and other software mechanisms to
 help, but in the end disk I/O kills the fun for all :(. So with this in
 mind, it really matters how the schema is designed, and you can get a 
big performance boost there. Limiting query results is a good practice, 
if not for anything else but to prevent being your own DOS source :). 
But you can also keep up/improve the RDB's performance to a particular 
load with tweeks to the schema.

Now on the schema side of things.
 RDBs are blazingly fast when it comes to operating on a single table, 
the less joins/FKEYS the faster the query. Also different tables result 
in different indexes and different data sizes translating to different 
I/O requests which can really throw a wrench in benefiting from the 
hardware pipeline that is available from your controllers and disks. For
 a well performing RDB query predictability/consistency is needed. So if
 you can get away with putting more in one table vs. putting less but in
 more tables I would choose the former. Of course there is a point at 
which to stop, but this is why DBA's and RDB consultants cost so much 
and I am neither so take my opinion simply as that, an opinion, and at 
your own risk :). Thus I would merge the descs and commits tables. The 
spacial overhead of having multiple "description" entries is really 
worth the performance boost... space is really cheap now a days :). Then
 if you really want to boost things up, you can place different tables 
in different table spaces each mapped to a different disk for greater 
parallelism. That's what I learned in RDB deployment 101 thanks to nice 
discussion forums like this one :).

Of course a schema change implies backward compatibility issues, migration and support... we just don't get a break, do we? :) Well, kind of yes, because of the following facts which makes things simpler:

1. The source for the Checkin DB never really disappears, i.e. the CVS and SVN repositories are safe and sound. If they are gone then we have bigger issues on our hand... really big if there are no backups of them :(, but that's beyond the scope of this discussion.
2. The data in the Checkin DB always, or at least it should, reflects the latest CVS/SVN state.
3. The data in the Checkin DB is not modified to reflect things differently that what they are in CVS/SVN repositories.

Based on the above, there is no real issues except for time spent, to ask users to rebuild the Checkin DB in order to benefit from a more "performing" schema. For example when going to the next "major" revision change,i.e. from 1.1.x, 1.2.x.. hint hint :D.

So in summary it looks there are thee issues to tackle, two of which can be done without having to go to a next major rev.

1. Changing the loading of the DB to type ii. This will ensure no "lost" changesets.
2. Changing the query functionality in viewvc.cgi to just give us the tip of a repository's iceberg, i.e. rev, date, log, and only this as it is the typical starting place of any drill-down when searching for "what happened" with source code under version control.
3. Possible schema changes. Here I have to say that I have been very superficial in my analysis as it is meant only to start a discussion if seen as worth while.
- commits.revision, 
commits.repositoryid to used as a PK, or better generate a PK that is independent of this "business logic" and have commits.revision, 
commits.repositoryid as surrogate PKS at the business level if really need be
- maybe start looking at Hibernate, at least its concepts as a persistence layer might reduce some of the hurdles and give some inspiration, maybe even programmatic ones :) ... a quick Goolge search for "Hibernate Python" might give a currently available solution (open source of course :) )
- changing the table structures may be a place to look as well for increasing performance
- commits.revision should be an int and not a varchar(32), this I am sure of... better performance and more real to representing the way things are.

Thanks,
Most.


> Date: Tue, 14 Jun 2011 09:35:18 -0400
> From: [email protected]
> To: [email protected]
> CC: [email protected]
> Subject: Re: [viewvc-users] checkin DB svn log queries without additional tree change/changeset info
> 
> On 06/13/2011 09:11 PM, Asd Asdasd wrote:
> > Hi,
> > 
> > Is it possible to perform queries via viewvc.cgi on the Checkin DB only for
> > svn log information? For example, I want to see all svn logs related to
> > commits with a certain range of dates, pretty much the same way one gets
> > output via "svn log -r {2006-11-20}:{2006-11-29}", but with a nicer
> > interface :). These type of queries are typically used as the first step in
> > drilling down to more details about the source code under version control,
> > i.e. get one's bearings straight.
> > 
> > One reason for this is that so far I get tree changeset information as well,
> > and it looks like the SQL results related to such information is counted
> > against row_limit, thus limiting the output... plus its always nice to have
> > only what is needed in the output :).
> 
> I know this problem all too well.  You'll want to read issue #433's history.
> http://viewvc.tigris.org/issues/show_bug.cgi?id=433
> 
> No, I don't currently have a performance-aware solution for it.
> 
> -- 
> C. Michael Pilato <[email protected]>
> CollabNet   <>   www.collab.net   <>   Distributed Development On Demand
>

------------------------------------------------------
http://viewvc.tigris.org/ds/viewMessage.do?dsForumId=4251&dsMessageId=2765727

To unsubscribe from this discussion, e-mail: [[email protected]].