meta_query and strange orderby behaviour

You could try

$args = array(
    'post_type'=> 'events',
    'meta_query' => array(
        array(
            'key' => '_startdate',
            'value' => $today,
            'compare' => '>=',
            'type' => 'DATE',
        ),
        array(
            'key' => '_enddate',
            'value' => $today,
            'compare' => '>=',
            'type' => 'DATE',
        ),
        'relation' => 'OR',
    ),
);
function jumpin_thru_hoops( $a ) {
    global $wpdb;
    $a = $wpdb->postmeta.'.meta_value+0 ASC';
    return $a;
}
add_filter( 'posts_orderby', 'jumpin_thru_hoops' );
$upcoming = new WP_Query( $args );
// or
$upcoming = get_posts( $args );
remove_filter( 'posts_orderby', 'jumpin_thru_hoops' );