Custom shortcode breaks my page

Is the $my_id variable supposed to come from an attribute on the shortcode? E.g. [chapter my_id="123"]Lorum ipsum...[/chapter]

If so, at the beginning of your chapters() function, you need to retrieve the attributes out of the array being passed in. Something like:

extract( shortcode_atts( array(
    'foo' => 'something',
    'bar' => 'something else',
), $atts ) );

The values in that array are defaults which can be set if the keys don’t exist in your $attr (which comes from the shortcode tag in your content).

Otherwise, we need to know more about where $my_id is getting set in the first place. If you’re just trying to get the post ID of the current post that contains the shortcode, then maybe try this:

global $post;
$my_id = $post->ID;

Lastly, just as a best-practice, instead of directly calling MySQL functions, you might want to read up on the $wpdb interface, and use the core database access functions. It will help your code stay future-proof.