Can you order posts from wp_query by two custom meta fields?

In pure SQL you can use comma separated strings to do what you want– that is, something like ORDER BY post_type,post_name,post_date. However, WP_QUERY will not allow that kind of thing to pass through. There is a rigid set of allowed values.

There are a couple of ways I can think of to do this.

You can “push” query vars to WP_Query just by adding them to your $args. Caveat: I do not know if this is intended behavior. It may be a quirk in the code base.

$args = array(
  'post_type' => 'post',
  'post_status' => 'publish',
  'posts_per_page' => 8,
  'orderby' => 'post_date,post_title',
  'order' => 'ASC',
  'myorderby' => 'post_date,post_name'
);

$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query();
$wp_query->query($args);

while ($wp_query->have_posts()) {
  $wp_query->the_post();
  echo $post->post_title.'<br/>';
}

Add a filter on posts_orderby

function posts_odb_filter_wpse_96900($odb) {
  global $wp_query;
  $myodb = $wp_query->get('myorderby');
  if (!empty($myodb)) {
    preg_match('/(ASC|DESC)$/',$odb,$dir);
    $odb = $myodb;
    if (!empty($dir[0])) {
      $odb .= ' '.$dir[0];
    }
  }
  return $odb;
}
add_filter('posts_orderby','posts_odb_filter_wpse_96900');

… and you can order to your heart’s content.

The (probably) more canonical way to do it is to check the query vars, or other information, and alter the query accordingly.

function posts_odb_filter_wpse_96900_v2($odb) {
  global $wp_query;
  if (is_front_page() && !is_main_query()) { // whatever conditions you need
    preg_match('/(ASC|DESC)$/',$odb,$dir);
    $odb .= ' post_date,post_name '.$dir[0];
  }
  return $odb;
}
add_filter('posts_orderby','posts_odb_filter_wpse_96900_v2');

The drawback of the second method is that you have to create a filter for each query that you need to alter.