There is another option, which is a bit like option 3 - use one big VBO (probably with GL_STREAM_DRAW mode) that is reset each frame (by calling glBufferData with a NULL buffer pointer and the same size each time) then glMapBuffer-ed right away. The buffer is left mapped as it is filled in, then unmapped just before drawing. Repeat.
The call to glBufferData tells OpenGL that the old buffer contents aren't needed, so the glMapBuffer doesn't have to potentially wait to ensure the GPU is finished with by the GPU.
This approach seems to be the one officially sanctioned by the vertex_buffer_object extension. See the "Vertex arrays using a mapped buffer object" example:
http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt
This suggests that OpenGL (or the driver?) will be watching for this sort of behaviour, and (when spotted) arrange things so that it is performed efficiently.