I'm afraid that, without common table expressions and/or window functions and without resorting to writing a procedure, this gets horribly verbose in MySQL
SELECT t.id, t.val second_largest
-- unpivot your columns into a table
FROM (
SELECT id, col1 val FROM my_table UNION ALL
SELECT id, col2 FROM my_table UNION ALL
SELECT id, col3 FROM my_table UNION ALL
SELECT id, col4 FROM my_table UNION ALL
SELECT id, coln FROM my_table
) t
-- retain only those records, where there exists exactly one record with a
-- column value greater than any other column value with the same id
WHERE 1 = (
SELECT COUNT(*)
-- Here, use unions to be sure that every value appears exactly once
FROM (
SELECT id, col1 val FROM my_table UNION
SELECT id, col2 FROM my_table UNION
SELECT id, col3 FROM my_table UNION
SELECT id, col4 FROM my_table UNION
SELECT id, coln FROM my_table
) u
WHERE t.id = u.id
AND t.val < u.val
)
Here's the SQLFiddle to check it (thanks to bluefeet for the heads-up with the schema!). The above solution will find the second largest column value in every row, even if the largest column value appears more than once.