Checking the Philips/NXP application notes and having some hands-on experience you can try the following tricks.
#2 When connecting microcontrollers to the I2C bus, set an appropriate brownout level. Eg. this would be 2.7 V for an ATtiny25 at 3.3V. This is disabled by default causing mayhem on the I2C bus when the microcontroller is booting up. Here's an appropriate fuse setting for avrdude for I2C 2.7V brownout level (at 8 MHz):
#2 If you don't know anything about brownout, then there's a simple way around this. When switching on, make sure to switch on Vcc first and then connect the SDA/SCL lines after the devices have booted up. This applies to a Raspberry restart, too. This is a pain, by the way, so I suggest using an appropriate brownout level, this will save you a lot of hassle on the long run. Without this, when you do a device reset, the bus will hang leaving you to do the embarrassing reconnecting business.
#3 Use 100 kHz. Sometimes you can go above this, but usually stick to that for maximum compatibility - at least on the Raspberry. 400 kHz can work at times with multiple devices. The MHz regions in my experience can be achieved with newer or fewer number of devices, usually.
If these steps are not enough, because you're building a big I2C network, additional steps need to be taken to make sure you can isolate parts of the bus - even capacitively. This is when you'll probably have to get some additional hardware like the PCA9517 from NXP.
As an addition, you can just check whether your devices are connected to the I2C bus from a shell script. Which means you can power the I2C bus through a mosfet/transistor and then just reset the whole bus if it goes very wrong. Eg. if you have some device connected at the 03 address, and you can't find that device any more, then probably it makes sense to reboot that part of the circuit.
From a shell script, you can do something like:
if [ -z "`sudo i2cdetect -y 1 | grep 03`" ]
..... restart your mosfet
to monitor the situation eg, every minute.