After Luka Jovic missed a sitter, the Ukraine side doubled their lead when Thibaut Courtois could only parry Tete's long-range drive and Raphael Varane put the rebound into his own net.
And it got even worse for Los Blancos when Tete's deft backheel found Manor Solomon free in the box and he rifled the ball into the corner to make it 3-0.
Karim Benzema was brought on at the break and the home side became more clinical with more movement in the final third. Luka Modric started the fightback with a stunning strike from around 25 yards, his first goal since January.
Vinicius Jr, who came on for the ineffective Jovic, made it 3-2 with his first touch after dispossessing Marlos.
Vinicius Junior, Real Madrid - Shakhtar
Image credit: Getty Images
But the visitors held on despite spurning some good opportunities of their own, and Federico Valverde's stoppage time strike being ruled out for offside, to pile on the misery for Real ahead of El Clasico with Barcelona.
TALKING POINT - Why were Real so bad?
Too many reasons to mention. The lack of senior players seemed to hurt them in terms of leadership.
But they were outhustled and tactically outclassed, similar to the wekeend loss against Cadiz.
And the selection of Jovic as a lone striker was a strange one. Perhaps Zidane took Shakhtar too lightly leaving Benzema, Vinicius Jr and Toni Kroos on the bench.
MAN OF THE MATCH - Tete (Shakhtar)
The Ukraine side have eight players aged 23 and under and the forward is among them. His runs behind the Real defence were clever, he took his goal well and could have bagged a hat-trick.
aleriy Bondar of Shakhtar Donetsk battles for possession with Raphael Varane of Real Madrid