From bce788ea56b6a2c429e9fab81320ae95ebaa9512 Mon Sep 17 00:00:00 2001 From: David Scott Date: Wed, 26 Jan 2011 17:39:05 +0000 Subject: [PATCH] Change the database type to include the schema version, rather than tracking it separately all over the place. Signed-off-by: David Scott --- ocaml/database/backend_xml.ml | 12 +++++++---- ocaml/database/backend_xml.mli | 2 +- ocaml/database/db_cache.ml | 5 +++-- ocaml/database/db_cache_types.ml | 31 ++++++++++++++++++++--------- ocaml/database/db_cache_types.mli | 7 ++++++- ocaml/database/db_connections.ml | 12 +++++------ ocaml/db_process/xapi-db-process.ml | 2 +- ocaml/xapi/pool_db_backup.ml | 2 +- ocaml/xapi/redo_log_usage.ml | 2 +- ocaml/xapi/xapi.ml | 3 ++- 10 files changed, 51 insertions(+), 27 deletions(-) diff --git a/ocaml/database/backend_xml.ml b/ocaml/database/backend_xml.ml index c0eb43f4..195fe1dc 100644 --- a/ocaml/database/backend_xml.ml +++ b/ocaml/database/backend_xml.ml @@ -59,6 +59,8 @@ let populate_and_read_manifest dbconn = (* version_check manifest; *) update_index unmarshalled_db; iter_over_tables (fun name table -> set_table_in_cache cache name table) unmarshalled_db; + Db_cache_types.set_schema_vsn cache (manifest.Db_cache_types.schema_major_vsn, manifest.Db_cache_types.schema_minor_vsn); + manifest let populate dbconn = @@ -80,7 +82,7 @@ let flush_db_to_redo_log cache_to_flush = (* Atomically read the generation count and take a deep copy of the cache *) let (gen_count, cache_copy) = Db_lock.with_lock (fun () -> Generation.read_generation(), Db_cache_types.snapshot cache_to_flush) in debug "Flushing cache to redo-log"; - let db_cache_manifest = Db_cache_types.gen_manifest gen_count in + let db_cache_manifest = Db_cache_types.manifest_of_cache cache_to_flush gen_count in let write_db_to_fd = (fun out_fd -> Db_xml.To.fd out_fd (db_cache_manifest, cache_copy)) in Redo_log.write_db gen_count write_db_to_fd end @@ -102,7 +104,7 @@ let flush_common dbconn optional_cache = let do_flush cache_to_flush filename = flush_db_to_redo_log cache_to_flush; - let db_cache_manifest = Db_cache_types.gen_manifest (Generation.read_generation()) in + let db_cache_manifest = Db_cache_types.manifest_of_cache cache (Generation.read_generation()) in if not dbconn.Parse_db_conf.compress then Db_xml.To.file filename (db_cache_manifest, cache_to_flush) else @@ -181,9 +183,11 @@ let read_schema_vsn dbconn = let manifest, unmarshalled_db = unmarshall dbconn in manifest.Db_cache_types.schema_major_vsn, manifest.Db_cache_types.schema_minor_vsn -let create_empty_db dbconn = +let create_empty_db (major, minor) dbconn = let empty_cache = create_empty_cache () in + Db_cache_types.set_schema_vsn empty_cache (major, minor); + List.iter (fun tbl -> set_table_in_cache empty_cache tbl (create_empty_table ())) db_table_names; - let manifest = Db_cache_types.gen_manifest 0L (* new gen count *) in + let manifest = Db_cache_types.make_manifest major minor 0L (* new gen count *) in let marshall filename = Db_lock.with_lock (fun () -> Db_xml.To.file filename (manifest, empty_cache)) in atomically_write_to_db_file dbconn.Parse_db_conf.path marshall; diff --git a/ocaml/database/backend_xml.mli b/ocaml/database/backend_xml.mli index d57f3a1f..38b3469f 100644 --- a/ocaml/database/backend_xml.mli +++ b/ocaml/database/backend_xml.mli @@ -15,7 +15,7 @@ val populate: Parse_db_conf.db_connection -> unit val flush_dirty: Parse_db_conf.db_connection -> bool val force_flush_all: Parse_db_conf.db_connection -> Db_cache_types.cache option -> unit val read_schema_vsn: Parse_db_conf.db_connection -> int*int -val create_empty_db: Parse_db_conf.db_connection -> unit +val create_empty_db: int*int -> Parse_db_conf.db_connection -> unit val populate_and_read_manifest: Parse_db_conf.db_connection -> Db_cache_types.db_dump_manifest val notify_delete: Parse_db_conf.db_connection -> string -> string -> unit val flush_db_to_redo_log: Db_cache_types.cache -> unit diff --git a/ocaml/database/db_cache.ml b/ocaml/database/db_cache.ml index 1970cbcc..1e86a3fe 100644 --- a/ocaml/database/db_cache.ml +++ b/ocaml/database/db_cache.ml @@ -52,7 +52,7 @@ exception Too_many_values of (*class*) string * (*ref*) string * (*uuid*) stri module type DB_CACHE = sig - val dump_db_cache : Db_cache_types.db_dump_manifest -> Unix.file_descr -> unit + val dump_db_cache : Int64.t -> Unix.file_descr -> unit val stats : unit -> (string * int) list @@ -660,7 +660,8 @@ struct let processed_str = SExpr.string_of (SExpr.Node processed) in write_field context tbl objref fld processed_str) - let dump_db_cache db_cache_manifest fd = + let dump_db_cache generation fd = + let db_cache_manifest = Db_cache_types.manifest_of_cache Db_backend.cache generation in let time = Unix.gettimeofday() in (* Snapshot the cache (uses the lock) and then slowly serialise the copy *) Db_xml.To.fd fd (db_cache_manifest, snapshot cache); diff --git a/ocaml/database/db_cache_types.ml b/ocaml/database/db_cache_types.ml index 100cfbe5..7bfed2bc 100644 --- a/ocaml/database/db_cache_types.ml +++ b/ocaml/database/db_cache_types.ml @@ -15,7 +15,10 @@ open Db_exn type row = (string, string) Hashtbl.t type table = (string, row) Hashtbl.t -type cache = (string, table) Hashtbl.t +type cache = { + cache: (string, table) Hashtbl.t; + schema: (int * int) option ref; +} type where_record = {table:string; return:string; where_field:string; where_value:string} type structured_op_t = AddSet | RemoveSet | AddMap | RemoveMap @@ -33,13 +36,23 @@ type db_dump_manifest = generation_count : Generation.t } -let gen_manifest gen_count = +let make_manifest schema_major_vsn schema_minor_vsn gen_count = { - schema_major_vsn = Datamodel.schema_major_vsn; - schema_minor_vsn = Datamodel.schema_minor_vsn; + schema_major_vsn = schema_major_vsn; + schema_minor_vsn = schema_minor_vsn; generation_count = gen_count } +let schema_of_cache cache = match !(cache.schema) with +| None -> (0, 0) +| Some (major, minor) -> major, minor + +let manifest_of_cache cache gen_count = + let major, minor = schema_of_cache cache in + make_manifest major minor gen_count + +let set_schema_vsn cache (major, minor) = cache.schema := Some (major, minor) + (* Our versions of hashtbl.find *) let lookup_field_in_row row fld = try @@ -48,7 +61,7 @@ let lookup_field_in_row row fld = let lookup_table_in_cache cache tbl = try - Hashtbl.find cache tbl + Hashtbl.find cache.cache tbl with Not_found -> raise (DBCache_NotFound ("missing table",tbl,"")) let lookup_row_in_table tbl tblname objref = @@ -60,7 +73,7 @@ let iter_over_rows func table = Hashtbl.iter func table let iter_over_tables func cache = - Hashtbl.iter func cache + Hashtbl.iter func cache.cache let iter_over_fields func row = Hashtbl.iter func row @@ -72,19 +85,19 @@ let set_row_in_table table objref newval = Hashtbl.replace table objref newval let set_table_in_cache cache tblname newtbl = - Hashtbl.replace cache tblname newtbl + Hashtbl.replace cache.cache tblname newtbl let create_empty_row () = Hashtbl.create 20 let create_empty_table () = Hashtbl.create 20 -let create_empty_cache () = Hashtbl.create 20 +let create_empty_cache () = { cache = Hashtbl.create 20; schema = ref None } let fold_over_fields func row acc = Hashtbl.fold func row acc let fold_over_rows func table acc = Hashtbl.fold func table acc -let fold_over_tables func cache acc = Hashtbl.fold func cache acc +let fold_over_tables func cache acc = Hashtbl.fold func cache.cache acc let remove_row_from_table tbl objref = Hashtbl.remove tbl objref diff --git a/ocaml/database/db_cache_types.mli b/ocaml/database/db_cache_types.mli index 81f61132..c101ecfa 100644 --- a/ocaml/database/db_cache_types.mli +++ b/ocaml/database/db_cache_types.mli @@ -27,7 +27,12 @@ type db_dump_manifest = { schema_minor_vsn : int; generation_count : Int64.t; } -val gen_manifest : Int64.t -> db_dump_manifest + +val make_manifest : int -> int -> Int64.t -> db_dump_manifest +val manifest_of_cache: cache -> Int64.t -> db_dump_manifest + +val schema_of_cache: cache -> int * int +val set_schema_vsn: cache -> int * int -> unit val lookup_field_in_row : row -> string -> string val lookup_table_in_cache : cache -> string -> table diff --git a/ocaml/database/db_connections.ml b/ocaml/database/db_connections.ml index f2599fe0..71e474e3 100644 --- a/ocaml/database/db_connections.ml +++ b/ocaml/database/db_connections.ml @@ -111,16 +111,16 @@ let flush_dirty_and_maybe_exit dbconn exit_spec = end; was_anything_flushed ) - -let create_empty_db dbconn = +(* +let create_empty_db (major, minor) dbconn = Generation.create_fresh dbconn; - Backend_xml.create_empty_db dbconn - -let maybe_create_new_db dbconn = + Backend_xml.create_empty_db (major, minor) dbconn + *) +let maybe_create_new_db (major,minor) dbconn = if not (Sys.file_exists dbconn.Parse_db_conf.path) then begin Generation.create_fresh dbconn; - Backend_xml.create_empty_db dbconn + Backend_xml.create_empty_db (major,minor) dbconn end let force_flush_all dbconn = diff --git a/ocaml/db_process/xapi-db-process.ml b/ocaml/db_process/xapi-db-process.ml index fc301cbe..807aa64b 100644 --- a/ocaml/db_process/xapi-db-process.ml +++ b/ocaml/db_process/xapi-db-process.ml @@ -94,7 +94,7 @@ let do_write_database() = begin read_in_database(); if !xmltostdout then - Db_cache.DBCache.dump_db_cache (Db_cache_types.gen_manifest (Generation.read_generation())) (Unix.descr_of_out_channel stdout) + Db_cache.DBCache.dump_db_cache (Generation.read_generation()) (Unix.descr_of_out_channel stdout) else write_out_database !filename end diff --git a/ocaml/xapi/pool_db_backup.ml b/ocaml/xapi/pool_db_backup.ml index 180b1b71..5676aeb1 100644 --- a/ocaml/xapi/pool_db_backup.ml +++ b/ocaml/xapi/pool_db_backup.ml @@ -40,7 +40,7 @@ let write_database (s: Unix.file_descr) ~__context = let len = String.length minimally_compliant_miami_database in ignore (Unix.write s minimally_compliant_miami_database 0 len) else - Db_cache.DBCache.dump_db_cache (Db_cache_types.gen_manifest (Generation.read_generation())) s + Db_cache.DBCache.dump_db_cache (Generation.read_generation()) s (** Make sure the backup database version is compatible *) let version_check manifest = diff --git a/ocaml/xapi/redo_log_usage.ml b/ocaml/xapi/redo_log_usage.ml index 36c8bcfe..8317a7b7 100644 --- a/ocaml/xapi/redo_log_usage.ml +++ b/ocaml/xapi/redo_log_usage.ml @@ -91,7 +91,7 @@ let read_from_redo_log staging_path = raise NoGeneration | Some generation -> (* Write the in-memory cache to the file *) - let manifest = Db_cache_types.gen_manifest generation in + let manifest = Db_cache_types.manifest_of_cache Db_backend.cache generation in Db_xml.To.file staging_path (manifest, Db_backend.cache); Unixext.write_string_to_file (staging_path ^ ".generation") (Generation.to_string generation) end diff --git a/ocaml/xapi/xapi.ml b/ocaml/xapi/xapi.ml index ff1ced84..8b6ccfed 100644 --- a/ocaml/xapi/xapi.ml +++ b/ocaml/xapi/xapi.ml @@ -73,7 +73,8 @@ let start_database_engine () = Db_dirty.make_blank_dirty_records(); (* Check if db files exist, if not make them *) - List.iter Db_connections.maybe_create_new_db (Db_conn_store.read_db_connections()); + let major, minor = Datamodel.schema_major_vsn, Datamodel.schema_minor_vsn in + List.iter (Db_connections.maybe_create_new_db (major,minor)) (Db_conn_store.read_db_connections()); (* Initialise in-memory database cache *) debug "Populating db cache"; -- 2.39.5