I asked myself the same question recently.
In our project, we maintain one branch for each major version of the application. I assume that these are the same as the "production branches" you are talking about. We call them "maintenance branches", here.
My first thought was to completely get rid of the default branch of mercurial, and have one branch for each major version. This would lead to this structure :
branch tag
o v2 2.2
o | v3
| o v2 2.1
|/
o v2 2.0
|
| o v1 1.1
o | v2
| o v1
|/
o v1 1.0
|
o v1
It works, but there is a downside to this approach : if you clone a repo like this, a simple hg update will do nothing, since the default branch doesn't exist anymore. Personnaly, I expect to be in the latest development state, after performing an hg update.
In the end, we chose this structure :
branch tag
o maintenance-V2 2.2
o | default
| o maintenance-V2 2.1
|/
o default 2.0
|
| o maintenance-V1 1.1
o | default
| o maintenance-V1
|/
o default 1.0
|
o default
The default branch is the development branch, and the other are version maintenance ones. Performing an hg update brings you to the latest default changeset, which is in this example the next V3.