Danish defender Andreas Christensen netted 'Gladbach's crucial winning goal on 76 minutes when the ball flew his way after captain Lars Stindl's shot cannoned off a Mainz defender and the centre-back stabbed home.
But Mainz had a goal ruled out when striker Pablo De Blasis poked his shot into the Gladbach goal on 89 minutes after the ball rolled free of Borussia's goalkeeper Yann Sommer following a save.
De Blasis was already off celebrating, but referee Robert Hartmann refused to give the goal, even though replays showed Sommer did not have a glove on the ball when De Blasis kicked it.
"The ball was in my hand, but it all happened very quickly. It was a very difficult decision to make," Sommer told Sky after the final whistle.
To add insult to injury, Hartmann sent off Mainz midfielder Jean-Philippe Gbamin for a second yellow card on 90 minutes.
"It's a pity that we have to talk about things other than football," fumed Mainz coach Martin Schmidt when asked about the disallowed goal as his side suffered their fourth away league defeat in a row.
The result lifts Gladbach up to 12th, a point below Mainz and six from the relegation places after a first Bundesliga win since September 24.
After their 4-0 Champions League thrashing at Barcelona in mid-week, Gladbach's sports director Max Eberl said their three Bundesliga games against Mainz, Augsburg and Wolfsburg matter more than the Barca defeat.
"I'll say it very clearly: up until Christmas, we must deliver results," Eberl said before kick-off.
But this was another poor performance from Gladbach, whose defence looked shaky, especially in the controversial scene around the disallowed goal and Schubert still remains in danger of becoming the sixth Bundesliga coach sacked this season.
Later on Sunday, Bayer Leverkusen poached a 1-0 win thanks to Stefan Kiessling's late header at Schalke, who played nearly the whole match with ten men.
Brazil defender Naldo was sent off after being shown a straight red-card with just four minutes gone for bringing down Javier Hernandez when 'Chicharito' was through on goal.
Despite the numerical disadvantage, Schalke outplayed Leverkusen for long periods as the visitors scored with their only clear chance.
Kiessling gave his side three points when he headed home Hakan Calhanoglu free-kick on 89 minutes for his first league goal of the season.
The result lifts Leverkusen to eighth as they wait to hear their last 16 opponents when the draw for the Champions League's knock-out stages is made on Monday (1100GMT) in Nyon, Switzerland.
On Saturday, Bayer Munich went back to the top of the table with a 5-0 win over Wolfsburg after RB Leipzig's three-week run as leaders was ended by a shock 1-0 defeat at Ingolstadt.
Both Leipzig and Bayern have 33 points, but Carlo Ancelotti's Bavarian giants top on goal difference with the teams to meet in Munich on December 21.