Sometimes less is more. You don't have to worry about balancing the brackets, so you don't really care about the opening brackets. Just find the third closing bracket and split there:
$_='[Microsoft][ODBC SQL Server Driver][SQL Server][0122]USAGE: Invoke
+StoredProcedure [param1], [param2], [param3], [param3]';
my ($one, $two) = /((?:.*?\]){3})(.*)/;
print "<$one>\n<$two>\n";