Changes between Version 7 and Version 8 of drmsSubscribe


Ignore:
Timestamp:
02/18/15 10:16:58 (10 years ago)
Author:
joe
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • drmsSubscribe

    v7 v8  
    110110If you miss more than about a month's worth of slony updates, it will be necessary to unsubscribe and resubscribe to regenerate your data tables. Obviously, this is to be avoided. 
    111111 
     112 
     113== VSO Specific Triggers == 
     114 
     115There are two triggers that may be installed after the subscription process 
     116 
     117=== Automatic data mirroring === 
     118 
     119Sites that are using the JMD to retrieve data will have a table in their database named `sunum_queue` : 
     120 
     121{{{ 
     122sdac_drms=# \d public.sunum_queue; 
     123                                     Table "public.sunum_queue" 
     124    Column    |            Type             |                       Modifiers 
     125--------------+-----------------------------+------------------------------------------------------- 
     126 queue_id     | bigint                      | not null default nextval('sunum_queue_key'::regclass) 
     127 sunum        | bigint                      | not null 
     128 series_name  | text                        | not null 
     129 timestamp    | timestamp without time zone | default now() 
     130 recnum       | bigint                      | 
     131 request_type | character varying(10)       | not null default 'MIRROR'::character varying 
     132 priority     | integer                     | not null default 0 
     133Indexes: 
     134    "sunum_queue_pkey" PRIMARY KEY, btree (queue_id) 
     135}}} 
     136 
     137The JMD will check this table for entries of files that it should retrieve.    We use a trigger on the table under slony control to write records into the `sunum_queue` table.  There is a script in the CVS tree to build the appropriate triggers: `vso/DataProviders/JSOC/db_triggers/sunum_queue_trigger_sampled.pl`.  It takes the following arguments: 
     138{{{ 
     139        Usage : ./sunum_queue_trigger_sampled.pl <series> [<instrument> [<cadence> [<max_age>]]] 
     140 
     141        series     : series name (with namespace) 
     142        instrument : hmi or aia 
     143        cadence    : integer, in seconds (should be a multiple of 72 for aia, 45 for hmi) 
     144        max_age    : maximum age, in days, of records to queue (default 14 days) 
     145}}} 
     146 
     147If given with just a series name, it will emit the SQL commands to create a trigger that retrieves all updates for observations within the last 14 days.  Specifying a cadence will allow you to retrieve observations at lower than the full data rate.  Note that only SQL is emitted to STDOUT, so that you can redirect this cleanly to a file.  Warnings and other messages are emitted to STDERR. 
     148 
     149{{{ 
     150[oneiros@sdo3 db_triggers]$ ./sunum_queue_trigger_sampled.pl hmi.v_720s 
     151 
     152-- You only need to issue this once.  In theory, it'd have already been 
     153-- done as part of the setup for DRMS & slony: 
     154-- 
     155-- CREATE LANGUAGE plpgsql; 
     156 
     157CREATE OR REPLACE FUNCTION hmi_v_720s_fc() returns TRIGGER as $hmi_v_720s_trg$ 
     158BEGIN 
     159  IF (TG_OP='INSERT' AND new.sunum > 0 and NEW.date__obs <> 'NaN') THEN 
     160    IF ( EXTRACT('epoch' FROM NOW()) - NEW.date__obs < 222134367 ) THEN 
     161      INSERT INTO sunum_queue (sunum,recnum,series_name) VALUES (new.sunum,NEW.recnum,'hmi.v_720s'); 
     162    END IF; 
     163 
     164  END IF; 
     165RETURN NEW; 
     166END 
     167$hmi_v_720s_trg$ LANGUAGE plpgsql; 
     168 
     169 
     170-- the drop trigger will fail the first time, but there's no 'OR REPLACE' on 
     171-- triggers, so this is so it'll work after the first time. 
     172-- (or just don't mess with the trigger; replacing the function is enough, 
     173-- as it's just linked by name) 
     174 
     175DROP TRIGGER hmi_v_720s_trg ON hmi.v_720s; 
     176CREATE TRIGGER hmi_v_720s_trg AFTER INSERT ON hmi.v_720s 
     177    FOR EACH ROW EXECUTE PROCEDURE hmi_v_720s_fc(); 
     178}}} 
     179 
     180=== VSO Shadow Tables === 
     181 
     182(note that most sites do not need this trigger.  Only SDAC and NSO currently incur this extra overhead) 
     183 
     184To speed searching for data, the VSO generates a materialized view that we refer to as the 'shadow tables'.  These tables are keep up-to-date with the DRMS series table via a trigger.  There are two scripts to build the SQL commands necessary, both in CVS: 
     185`vso/DataProviders/JSOC/db_triggers/shadow_aia_template.pl` and `vso/DataProviders/JSOC/db_triggers/shadow_hmi_template.pl`.  They take a series name as an argument.  Note that only SQL is emitted to STDOUT, so that you can redirect this cleanly to a file.  Warnings and other messages are emitted to STDERR. 
     186 
     187{{{ 
     188[oneiros@sdo3 db_triggers]$ perl shadow_hmi_template.pl hmi.v_720s 
     189SERIES : hmi.v_720s 
     190SHADOW : hmi__v_720s 
     191 
     192DROP TABLE vso.hmi__v_720s; 
     193 
     194CREATE TABLE vso.hmi__v_720s ( 
     195    date_obs    timestamp       NOT NULL, 
     196    date        timestamp       NOT NULL, 
     197    t_rec_index bigint          UNIQUE NOT NULL, 
     198    recnum      bigint          UNIQUE NOT NULL, 
     199    sunum       bigint          NOT NULL, 
     200    slotnum     integer         NOT NULL, 
     201    clusterid   bigint          NOT NULL, 
     202    fileid      varchar(255)    UNIQUE NOT NULL, 
     203 
     204    PRIMARY KEY (t_rec_index) 
     205); 
     206 
     207CREATE INDEX vso_hmi__v_720s_cluster  ON vso.hmi__v_720s ( clusterid ); 
     208CREATE INDEX vso_hmi__v_720s_date_obs ON vso.hmi__v_720s ( date_obs ); 
     209CREATE INDEX vso_hmi__v_720s_date     ON vso.hmi__v_720s ( date ); 
     210 
     211GRANT SELECT ON vso.hmi__v_720s TO vso; 
     212 
     213 
     214CREATE OR REPLACE FUNCTION proc_update_vso_hmi__v_720s () 
     215RETURNS TRIGGER AS $proc_update_vso_hmi__v_720s$ 
     216    DECLARE 
     217        record_date_obs   timestamp; 
     218        record_date       timestamp; 
     219        record_rec_index  bigint; 
     220        record_recnum     bigint; 
     221        record_sunum      bigint; 
     222        record_slotnum    integer; 
     223        record_fileid     varchar(255); 
     224        record_clusterid  bigint; 
     225        deleted_record    RECORD; 
     226    BEGIN 
     227        -- this seems out of order, I know. 
     228        -- we look at the new record, and try to figure out if it's invalid 
     229        -- if it is, we still need to try to clean up the old record. 
     230        record_rec_index = NEW.t_rec_index; 
     231        record_sunum     = NEW.sunum; 
     232        -- we dont do journaling -- but we *DO* want to figure out 
     233        -- when SUs are replaced 
     234        DELETE FROM vso.hmi__v_720s 
     235            WHERE t_rec_index = record_rec_index 
     236            RETURNING sunum 
     237            INTO deleted_record; 
     238        IF FOUND THEN 
     239            IF deleted_record.sunum <> NEW.sunum THEN 
     240            -- don't flag if it's still the same sunum (headers updated?) 
     241                INSERT INTO public.sunum_replaced ( 
     242                    old_sunum, new_sunum 
     243                ) VALUES ( 
     244                    deleted_record.sunum, NEW.sunum 
     245                ); 
     246            END IF; 
     247        END IF; 
     248-- 
     249        -- ocassionally, there's a missing record ... don't process those 
     250        IF 'NaN' = NEW.date__obs  THEN 
     251            RETURN NEW; 
     252        END IF; 
     253-- 
     254        record_date_obs  = dynamical_to_unix(NEW.date__obs); 
     255        record_date      = dynamical_to_unix(NEW.date); 
     256        record_recnum    = NEW.recnum; 
     257        record_slotnum   = NEW.slotnum; 
     258 
     259        record_fileid    = 'hmi__v_720s:'||record_rec_index||':'||record_rec_index; 
     260        record_clusterid = ROUND( record_rec_index / 40 ); 
     261-- 
     262        -- I couldve done this as INSERT INTO ... SELECT NEW.* 
     263        -- but then theres that nasty concat and such. 
     264        INSERT into vso.hmi__v_720s ( 
     265            date_obs, date, t_rec_index, recnum, sunum, slotnum, clusterid, fileid 
     266        ) values ( 
     267            record_date_obs, record_date, record_rec_index, record_recnum, 
     268            record_sunum, record_slotnum, record_clusterid, record_fileid 
     269        ); 
     270-- 
     271        RETURN NEW; 
     272-- 
     273    EXCEPTION 
     274      WHEN OTHERS THEN 
     275          RAISE WARNING 'vso.hmi__v_720s : % : % : %', SQLSTATE, NEW.recnum, SQLERRM; 
     276          RETURN NEW; 
     277    END; 
     278$proc_update_vso_hmi__v_720s$ LANGUAGE 'plpgsql'; 
     279 
     280 
     281DROP TRIGGER trig_update_vso_hmi__v_720s ON hmi.v_720s; 
     282 
     283CREATE TRIGGER trig_update_vso_hmi__v_720s 
     284    BEFORE INSERT OR UPDATE 
     285    ON hmi.v_720s 
     286    FOR EACH ROW 
     287    EXECUTE PROCEDURE proc_update_vso_hmi__v_720s(); 
     288 
     289 
     290-- trigger it to run for the data already in the table 
     291UPDATE hmi.v_720s SET recnum=recnum; 
     292}}} 
     293