I'm not an *expert* on GL, but I did just release a game with a GL backend.
1. Yes. Z-ordering aside, you want to be able to rearrange draws to a) minimize the number of state changes (texture, shader, framebuffer) over the entire render sequence, and b) batch as many draws as possible into a single call. (Uploading a full buffer of vertex data rather than one or two quads at a time.) This is.. *difficult*, to say the least, without a pushbuffer.
Furthermore, what the pushbuffer actually buys you is that the order you simulate in is not necessarily the order you render in, and that is *always* a good thing. Restricting one by the other is going to lead to finicky, inefficient code.
2. How you set this up is going to depend on what you actually need. Attaching vertex buffers to individual objects only really makes sense when you're dealing with complex models. Otherwise, it's better to just grab whatever buffer is available during the render process, and fill it up -- the batching buys more than not having to upload vertices again. (Hint: don't try to cache and reuse a VBO between draw calls -- abandon the buffer after each draw by reallocating. (The driver will clean it up after the draw is done.) Otherwise the serialization becomes a bottleneck.)
For textures, just wrap them in a handle struct. As long as nothing outside the renderer or asset system goes poking at the internals, you can switch between GL/DirectX/software at will. The game code itself doesn't actually care what the contents of the texture are. (Usually. If your game does, then you need to address that differently.)
Remember that abstraction isn't "these things must never touch!" Rather, it's about making sure that outside code doesn't care about the implementation details. Your game code can pass around handles to textures and shaders (or any other platform object) with no issues, as long as it doesn't have to care about the *contents* of that object.