[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 1 of 2] [database]: Simplify the database population code, in preparation for an upgrade simplification



# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1257263470 0
# Node ID 0baec4029c0a9f2b15c40dc912ce3f4b82a09740
# Parent  62ed86ba9fb24b1963c38f4b4a14c2119d66bb15
[database]: Simplify the database population code, in preparation for an 
upgrade simplification.

We now unconditionally force-flush all database backends on populate, rather 
than only flushing ones which had a lower generation count.
 -- there should now only be one database backend anyway
 -- we nolonger worry about write limiting
 -- the cost of writing once per xapi start is low but the cost of screwing up 
and not writing when we should is high

Move the call to populate() so that it's always done before the database 
upgrade.
 -- the database upgrade code now assumes the cache is loaded and ready for 
modification

Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>

diff -r 62ed86ba9fb2 -r 0baec4029c0a ocaml/database/db_cache.ml
--- a/ocaml/database/db_cache.ml        Tue Nov 03 12:56:58 2009 +0000
+++ b/ocaml/database/db_cache.ml        Tue Nov 03 15:51:10 2009 +0000
@@ -459,17 +459,8 @@
       Db_backend.blow_away_non_persistent_fields()
 
     let sync_all_db_connections() =
-      (* if any of the connections have an on-disk generation count <> the gen 
count of the db we populated from
-        then we need to force_flush them to "pull them to tip" *)
-      List.iter 
-       (fun (gen,db)->
-          let current_gen = Generation.read_generation() in
-          if gen<>current_gen then
-            begin
-              debug "Database '%s' out of sync; syncing up now." 
db.Parse_db_conf.path;
-              Db_connections.force_flush_all db
-            end)
-       (Db_connections.get_dbs_and_gen_counts())
+      (* Unconditionally force-flush all databases. *)
+      List.iter Db_connections.force_flush_all (List.map snd 
(Db_connections.get_dbs_and_gen_counts()))
 
     (* Executed on the master to post-process database after populating cache 
from db stored on disk *)
     let post_populate_hook () =
@@ -477,6 +468,8 @@
        * there's no need to keep it and it's preferable for it not to hang
        * around. *)
       Unixext.unlink_safe Xapi_globs.ha_metadata_db;
+      (* non-persistent fields will have been flushed to disk anyway [since 
non-persistent just means dont trigger a flush
+        if I change]. Hence we blank non-persistent fields with a suitable 
empty value, depending on their type *)
       Db_backend.blow_away_non_persistent_fields();
       (* Flush the in-memory cache to the redo-log *)
       Backend_xml.flush_db_to_redo_log Db_backend.cache
@@ -506,17 +499,6 @@
                  (* we know that the backup is XML format so, to get the 
manifest, we jump right in and use the xml backend directly here.. *)
                  let manifest = Backend_xml.populate_and_read_manifest 
Parse_db_conf.backup_file_dbconn in
                  Db_backend.post_restore_hook manifest;
-                 (* non-persistent fields will have been flushed to disk 
anyway [since non-persistent just means dont trigger a flush
-                    if I change]. Hence we blank non-persistent fields with a 
suitable empty value, depending on their type *);
-                 post_populate_hook();
-                 debug "removed non-persistent fields after backup";
-                 (* since we just restored from backup then flush new cache to 
all db connections *)
-                 List.iter 
-                   (fun (_,db)->
-                      debug "Database '%s' syncing up after restore from 
backup." db.Parse_db_conf.path;
-                      Db_connections.force_flush_all db
-                   )
-                   (Db_connections.get_dbs_and_gen_counts());
                  (* delete file that contained backup *)
                  Db_backend.try_and_delete_db_file 
Xapi_globs.db_temporary_restore_path;
                end
@@ -524,14 +506,15 @@
                begin
                  (* Check schema vsn is current; if not try and upgrade; if 
can't do that then fail startup.. *)
                  let most_recent_db = Db_connections.pick_most_recent_db 
connections in
+                 (* populate gets all field names from the existing (old) db 
file, not the (current) schema... which is nice: *)
+                 Backend_xml.populate most_recent_db;
+
                  debug "Path that I'm looking at to consider whether to 
upgrade = %s" most_recent_db.Parse_db_conf.path;
                  if Sys.file_exists most_recent_db.Parse_db_conf.path then
                    Db_upgrade.maybe_upgrade most_recent_db;
        
-                 (* populate from most recent database *)
-                 Backend_xml.populate most_recent_db;
-                 post_populate_hook ()
-               end
+               end;
+      post_populate_hook ()
 
     let spawn_db_flush_threads() =
       (* Spawn threads that flush cache to db connections at regular intervals 
*)
diff -r 62ed86ba9fb2 -r 0baec4029c0a ocaml/database/db_connections.ml
--- a/ocaml/database/db_connections.ml  Tue Nov 03 12:56:58 2009 +0000
+++ b/ocaml/database/db_connections.ml  Tue Nov 03 15:51:10 2009 +0000
@@ -124,6 +124,7 @@
     end
 
 let force_flush_all dbconn =
+  debug "About to flush database: %s" dbconn.Parse_db_conf.path;
   Db_conn_store.with_db_conn_lock dbconn
     (fun () ->
        begin
diff -r 62ed86ba9fb2 -r 0baec4029c0a ocaml/database/db_upgrade.ml
--- a/ocaml/database/db_upgrade.ml      Tue Nov 03 12:56:58 2009 +0000
+++ b/ocaml/database/db_upgrade.ml      Tue Nov 03 15:51:10 2009 +0000
@@ -213,6 +213,7 @@
        upgrade_bios_strings () (* GEORGE OEM -> BODIE/MNR *)   
 
 let upgrade_from_last_release dbconn =
+  (* NB the database cache has been populated already *)
   debug "Database schema version is that of last release: attempting upgrade";
 
   (* !!! UPDATE THIS WHEN MOVING TO NEW RELEASE !!! *)
@@ -231,9 +232,6 @@
 
   let table_names_new_in_this_release =
     List.filter (fun tblname -> not (List.mem tblname 
table_names_in_last_release)) table_names_in_this_release in
-  
-  (* populate gets all field names from the existing (old) db file, not the 
(current) schema... which is nice: *)
-  Backend_xml.populate dbconn;
 
   (* we also have to ensure that the in-memory cache contains the new tables 
added in this release that will not have been
      created by the proceeding populate (cos this is restricted to table names 
in last release). Unless the new tables are
3 files changed, 11 insertions(+), 29 deletions(-)
ocaml/database/db_cache.ml       |   35 +++++++++--------------------------
ocaml/database/db_connections.ml |    1 +
ocaml/database/db_upgrade.ml     |    4 +---


Attachment: xen-api.hg-2.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.