February 5, 2009

Perforce database maintenance


Perforce is so easy to setup and use that new admins often overlook the task of database maintenance, and for most sites, this isn't really a problem, but as a company grows, and the size of their Perforce database grows, it becomes increasingly important to do a little maintenance.

There are basically three things that you should be concerned about:

  1. Old labels
  2. Old clients/workspaces
  3. Old users

Each of these items can easily be checked and archived out of the database on a regular basis.

Essentially, you will need a script to run p4 -ztag labels, clients and users, and check the accessdate on each of the output items to see when the last time that object was accessed. You will need to pick a cut off time period, say 12 weeks, and decide that if the object hasn't been accessed in that time frame, you are going to archive it. For clients and users, this is pretty easy, you just remove the user from all the groups they are in, delete all the clients they own, and then delete the user. For clients/workspaces, you just delete them. This is making the assumption that you have set up a spec type depot so that Perforce will save those specs when you delete them. See "p4 help depot" for more information on spec depots. If you have an existing server, and are just add a spec type depot, but sure to run "p4 admin updatespecdepot -a" before you delete anything though because Perforce only creates deleted versions of specs that already exist in the spec depot.

To restore an archived workspace, you can go to the spec depot, sync out the last undeleted version of the workspace spec, then from the command prompt in the directory containing the synced file, you can run:

p4 client -i < workspace_file

Another way to do it after looking up the version number of the last undeleted revision would be:

p4 print -q //your_spec_depot/client/workspace#N | p4 client -i

where N is the last undeleted version number for the workspace file.

Now for labels, it is a little more complicated because you have to save both the spec, and the label contents. In order to make this easier, it is best to just store them both as files in the depot. To create the two files you need to store, you can run:

p4 label -o labelname > labelname.spec
p4 files @labelname > labelname.files

It it best to strip off everything after the version number in the list of files in labelname.files before storing it in the depot. In other words, you want the labelname.files to just contain something like //depot/path/file#N where N is the version number for each file in the label.

Then, you can just check those two files into a storage area in your depot, and then delete the label using:

p4 label -f -d labelname

To restore a label, you have to sync the two matching files that you created to save the label, then from command prompt in the directory containing the two files, you have to do the following:

  1. First check the labelname.spec file and make sure the lock option is set to unlocked.
  2. p4 label -i < labelname.spec
  3. p4 -x labelname.files labelsync -l labelname
  4. p4 label -f labelname (Reset the lock option to locked if that is the way it was originally.)

After doing all of your clean up, you need to:

  1. Stop your server
  2. Take a checkpoint
  3. Move your existing db files to a save directory
  4. Recover from the checkpoint
  5. Restart your server
  6. Delete the files from the save directory assuming there were no errors when restoring from the checkpoint.

This process compacts your db files and rebalances your b-trees after removing all the old data.

Note: You need to have super user rights on your server to do several of the steps above.

Also, all of the items above can be completely scripted using a script language of your choice. All of the above steps are also available in a fully tested set of scripts as part of the Perforce Server Deployment Package.