diff --git a/wp-includes/plugin.php b/wp-includes/plugin.php
index e5e5288..5db957d 100644
--- a/wp-includes/plugin.php
+++ b/wp-includes/plugin.php
@@ -784,6 +784,9 @@ function register_deactivation_hook($file, $function) {
  * should always check for the 'WP_UNINSTALL_PLUGIN' constant, before
  * executing.
  *
+ * The registration updates wp_options and so should only be called within an
+ * activation hook.
+ *
  * @since 2.7.0
  *
  * @param string   $file     Plugin file.
@@ -802,9 +805,11 @@ function register_uninstall_hook( $file, $callback ) {
         * uninstalling the plugin.
         */
        $uninstallable_plugins = (array) get_option('uninstall_plugins');
-       $uninstallable_plugins[plugin_basename($file)] = $callback;
-
-       update_option('uninstall_plugins', $uninstallable_plugins);
+    $key = plugin_basename($file);
+    if ( empty( $uninstallable_plugins[$key] ) || $uninstallable_plugins[$key] != $callback) {
+        $uninstallable_plugins[$key] = $callback;
+        update_option('uninstall_plugins', $uninstallable_plugins);
+    }
 }

 /**
