123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617 |
- {**************************************************************************}
- {* *}
- {* Licensed Materials - Property of IBM and/or HCL *}
- {* *}
- {* IBM Informix Dynamic Server *}
- {* (c) Copyright IBM Corporation 2001, 2016. All rights reserved. *}
- {* (c) Copyright HCL Technologies Ltd. 2017. All Rights Reserved. *}
- {* *}
- {**************************************************************************}
- DATABASE sysadmin;
- {*********************************************************
- *
- * The following section load all the parameters
- * utilized by AUS
- *
- ********************************************************
- *}
- INSERT INTO ph_threshold
- (id,name,task_name,value,value_type,description)
- VALUES
- (0,"AUS_AGE","Auto Update Statistics Evaluation","30","NUMERIC(6.2)",
- "The statistics are rebuilt after this many days.");
- INSERT INTO ph_threshold
- (id,name,task_name,value,value_type,description)
- VALUES
- (0,"AUS_CHANGE","Auto Update Statistics Evaluation","10","NUMERIC",
- "The statistics are rebuilt after this percentage of data has changed.");
- INSERT INTO ph_threshold
- (id,name,task_name,value,value_type,description)
- VALUES
- (0,"AUS_AUTO_RULES","Auto Update Statistics Evaluation","1","NUMERIC",
- "Ensures a base set of guidelines are followed when building statistics.");
- INSERT INTO ph_threshold
- (id,name,task_name,value,value_type,description)
- VALUES
- (0,"AUS_SMALL_TABLES","Auto Update Statistics Evaluation","100","NUMERIC",
- "Tables containing less than this number of rows will always have their statistics rebuilt.");
- INSERT INTO ph_threshold
- (id,name,task_name,value,value_type,description)
- VALUES
- (0,"AUS_PDQ","Auto Update Statistics Refresh","10","NUMERIC",
- "Update statistics executes with this PDQ priority.");
- {*********************************************************
- *
- * The following section creates all the procedures
- * utilized by AUS
- *
- ********************************************************
- *}
- CREATE FUNCTION informix.aus_get_realtime()
- RETURNING DATETIME YEAR TO SECOND
- DEFINE cur_time DATETIME YEAR TO SECOND;
- LET cur_time = (SELECT
- DBINFO( 'utc_to_datetime',sh_curtime)::DATETIME YEAR TO SECOND
- FROM sysmaster:sysshmvals);
- RETURN cur_time;
- END FUNCTION;
- CREATE FUNCTION informix.aus_setup_mon_table_profile(task_id INTEGER, task_seq INTEGER,
- inHDRmode INTEGER)
- RETURNING INTEGER
- DEFINE task_cnt INTEGER;
- DEFINE index_cnt INTEGER;
- --TRACE "FUNCTION aus_setup_mon_table_profile()" ;
- -- Make sure the task mon_table_profile is there an active
- SELECT count(*)
- INTO task_cnt
- FROM ph_task
- WHERE tk_name ="mon_table_profile";
- -- Check to see if index exists on (id,partnum)
- SELECT count(*)
- INTO index_cnt
- FROM sysindices
- WHERE tabid = ( SELECT tabid FROM systables
- WHERE tabname = "mon_table_profile" )
- AND ABS(ikeyextractcolno(indexkeys,0)) =
- ( SELECT colno FROM syscolumns
- WHERE tabid = ( SELECT tabid FROM systables
- WHERE tabname = "mon_table_profile"
- )
- AND colname ='id'
- )
- AND ABS(ikeyextractcolno(indexkeys,1)) =
- ( SELECT colno FROM syscolumns
- WHERE tabid = ( SELECT tabid FROM systables
- WHERE tabname = "mon_table_profile"
- )
- AND colname ='partnum'
- );
- IF task_cnt < 1 THEN
- INSERT INTO ph_alert
- (ID, alert_task_id,alert_task_seq,alert_type,
- alert_color, alert_object_type,
- alert_object_name, alert_message,alert_action)
- VALUES
- (0,task_id, task_seq, "WARNING", "green",
- "SERVER","Auto Update Statistics",
- "Built in server task (mon_table_profile) is missing. " ||
- "Auto Update Statistics proceeding with limited information.",
- NULL);
- RETURN -1;
- END IF;
- IF index_cnt < 1 THEN
- INSERT INTO ph_alert
- (ID, alert_task_id,alert_task_seq,alert_type,
- alert_color, alert_object_type,
- alert_object_name, alert_message,alert_action)
- VALUES
- (0,task_id, task_seq, "INFO", "green",
- "SERVER","Auto Update Statistics",
- "Building index on table mon_table_profile to optimize performance for Auto Update Statistics." ,
- NULL);
- IF inHDRmode = 1 THEN
- CREATE INDEX mon_table_profile_sys_ix1
- ON mon_table_profile(id,partnum) ONLINE;
- ELSE
- CREATE INDEX mon_table_profile_sys_ix1
- ON mon_table_profile(id,partnum);
- END IF;
- END IF;
- RETURN 1;
- END FUNCTION;
- CREATE FUNCTION informix.aus_get_exclusive_access(task_id INTEGER, task_seq INTEGER)
- RETURNING INTEGER
- DEFINE errnum INTEGER;
- DEFINE cnt INTEGER;
- DEFINE lk_sid INTEGER;
- --TRACE "FUNCTION aus_get_exclusive_access()" ;
- BEGIN
- ON EXCEPTION IN ( -310 ) SET errnum
- SELECT count(*) , MAX(aus_lk_sid)
- INTO cnt, lk_sid
- FROM aus_work_lock, sysmaster:sysscblst
- WHERE aus_lk_sid = sid
- AND aus_lk_task_id = task_id
- AND aus_lk_task_seq = task_seq;
- --TRACE "CNT = " || cnt || "lock SID = "||lk_sid;
- IF cnt > 0 THEN
- RAISE EXCEPTION -777, -107,
- "Current AUS tables are in use by Session ID "||lk_sid;
- END IF
- -- Fall through if count equal zero
- DELETE FROM aus_work_lock;
- END EXCEPTION WITH RESUME
- CREATE TABLE aus_work_lock (
- aus_lk_sid INTEGER,
- aus_lk_task_id INTEGER,
- aus_lk_task_seq INTEGER );
- INSERT INTO aus_work_lock(aus_lk_sid,aus_lk_task_id,aus_lk_task_seq)
- VALUES
- (DBINFO('sessionid'),task_id,task_seq);
- END
- RETURN 0;
- END FUNCTION;
- CREATE FUNCTION informix.aus_rel_exclusive_access()
- RETURNING INTEGER
- --TRACE "FUNCTION aus_rel_exclusive_access()" ;
- BEGIN
- ON EXCEPTION IN ( -206, -310 )
- END EXCEPTION
- DROP TABLE aus_work_lock;
- END
- RETURN 0;
- END FUNCTION;
- CREATE FUNCTION informix.aus_cleanup_table( save_results INTEGER )
- RETURNING INTEGER
- DEFINE errnum INTEGER;
- DEFINE cnt INTEGER;
- --TRACE "FUNCTION aus_cleanup_table()" ;
- IF save_results = 0 THEN
- SELECT COUNT(*)
- INTO cnt
- FROM ph_task
- WHERE BITAND(tk_attributes, '0x200' ) > 0
- AND tk_name like "Auto Update Statistics Refresh%"
- AND tk_next_execution <= ( SELECT tk_next_execution
- FROM ph_task
- WHERE tk_name = "Auto Update Statistics Evaluation");
- IF cnt > 0 THEN
- RAISE EXCEPTION -214, -107, "Current AUS tables are in use";
- END IF
- END IF
- /* Cleanup all the work tables */
- BEGIN
- ON EXCEPTION IN ( -214, -206, -394 ) SET errnum
- -- non-exclusive access, & table does not exist
- IF errnum = -214 THEN
- RAISE EXCEPTION -214, -107, "Current AUS tables are in use";
- END IF
- -- If error is -206 ignore the error, tables have been dropped
- END EXCEPTION WITH RESUME
- DROP TABLE aus_work_icols;
- DROP TABLE aus_work_dist;
- DROP TABLE aus_work_info;
- IF save_results == 0 THEN
- DROP TABLE aus_work_icols;
- DROP TABLE aus_work_dist;
- DROP TABLE aus_work_info;
- DROP TABLE aus_cmd_info;
- DROP VIEW aus_cmd_list;
- DROP VIEW aus_cmd_comp;
- DROP TABLE aus_command; -- drop views also
- END IF
- END
- RETURN 1;
- END FUNCTION;
- CREATE FUNCTION informix.aus_setup_table(inHDRmode INTEGER)
- RETURNING integer
- DEFINE errnum INTEGER;
- --TRACE "FUNCTION aus_setup_table()" ;
- /* Cleanup all the work tables */
- BEGIN
- ON EXCEPTION IN ( -310 ) SET errnum -- table already exists
- END EXCEPTION WITH RESUME
- CREATE TABLE informix.aus_cmd_info
- (
- aus_ci_dbs_partnum INTEGER,
- aus_ci_stime DATETIME YEAR TO SECOND
- DEFAULT CURRENT YEAR TO SECOND,
- aus_ci_etime DATETIME YEAR TO SECOND
- DEFAULT NULL,
- aus_ci_database VARCHAR(255) DEFAULT NULL,
- aus_ci_locale VARCHAR(36) DEFAULT NULL,
- aus_ci_logmode CHAR(1) DEFAULT NULL,
- aus_ci_missed_tables INTEGER DEFAULT 0,
- aus_ci_need_tables INTEGER DEFAULT 0,
- aus_ci_done_tables INTEGER DEFAULT 0
- );
- INSERT INTO aus_cmd_info(aus_ci_dbs_partnum,aus_ci_stime)
- VALUES (0,aus_get_realtime());
- IF inHDRmode = 1 THEN
- CREATE UNIQUE INDEX informix.aus_cmd_info_index1
- ON aus_cmd_info(aus_ci_dbs_partnum) ONLINE;
- CREATE UNIQUE INDEX informix.aus_cmd_info_index2
- ON aus_cmd_info(aus_ci_database) ONLINE;
- ELSE
- CREATE UNIQUE INDEX informix.aus_cmd_info_index1
- ON aus_cmd_info(aus_ci_dbs_partnum);
- CREATE UNIQUE INDEX informix.aus_cmd_info_index2
- ON aus_cmd_info(aus_ci_database);
- END IF;
- CREATE TABLE informix.aus_command
- (
- aus_cmd_id SERIAL,
- aus_cmd_state CHAR(1) DEFAULT 'P'
- CHECK (aus_cmd_state IN ("P","I","E","C")),
- -- P => Command is pending
- -- I => Command is inprogress
- -- E => Command had an Error
- -- C => Command is complete w/o Errors
- aus_cmd_type CHAR(1),
- aus_cmd_dbs_priority SMALLINT DEFAULT 2,
- aus_cmd_priority BIGINT,
- aus_cmd_dbs_partnum INTEGER,
- aus_cmd_partnum INTEGER,
- aus_cmd_err_sql INTEGER,
- aus_cmd_err_isam INTEGER,
- aus_cmd_time DATETIME YEAR TO SECOND DEFAULT CURRENT YEAR TO SECOND,
- aus_cmd_runtime INTERVAL HOUR TO SECOND DEFAULT NULL,
- aus_cmd_exe LVARCHAR(8192)
- ) LOCK MODE ROW;
- CREATE VIEW informix.aus_cmd_list AS SELECT
- aus_cmd_id, aus_cmd_type,
- aus_cmd_priority, aus_cmd_dbs_partnum,
- aus_cmd_partnum, aus_cmd_exe
- FROM aus_command
- WHERE aus_cmd_state = 'P';
- CREATE VIEW informix.aus_cmd_comp AS SELECT
- aus_cmd_id, aus_cmd_type,
- aus_cmd_priority, aus_cmd_dbs_partnum,
- aus_cmd_partnum, aus_cmd_exe,
- aus_cmd_time
- FROM aus_command
- WHERE aus_cmd_state = 'C';
- END
- BEGIN
- ON EXCEPTION IN ( -310 ) SET errnum -- table already exists
- END EXCEPTION WITH RESUME
- /*
- * This table contains both
- * index columns as wells as
- * user defined distribution columns
- */
- CREATE TABLE informix.aus_work_icols
- (
- aus_icols_tabid integer,
- aus_icols_colno integer,
- aus_icols_lkey char(1) CHECK( aus_icols_lkey IN ('Y','N')),
- aus_icols_mode char(1) DEFAULT NULL,
- aus_icols_colname varchar(128)
- ) LOCK MODE ROW;
- CREATE TABLE informix.aus_work_info
- (
- aus_info_id SERIAL,
- aus_info_db_partnum INTEGER,
- aus_info_tabname VARCHAR(128),
- aus_info_tabid INTEGER,
- aus_info_partnum INTEGER,
- aus_info_ustlowts DATETIME YEAR TO SECOND,
- aus_info_npused BIGINT,
- aus_info_nrows BIGINT,
- aus_info_nindexes smallint
- ) LOCK MODE ROW;
- CREATE TABLE informix.aus_work_dist
- (
- aus_dist_id serial,
- aus_dist_tabid INTEGER, -- this is the tabid
- aus_dist_colno INTEGER,
- aus_dist_mode CHAR(1),
- aus_dist_resolution FLOAT,
- aus_dist_confidence FLOAT,
- aus_dist_smplsize float,
- aus_dist_rowssmplde BIGINT,
- aus_dist_constr_time DATETIME YEAR TO SECOND,
- aus_dist_ustnrows BIGINT
- ) LOCK MODE ROW;
- END
- RETURN 1;
- END FUNCTION;
- CREATE FUNCTION informix.aus_refresh_stats_orig( )
- RETURNING integer
- DEFINE rc INTEGER;
- DEFINE cnt INTEGER;
- DEFINE i INTEGER;
- LET rc=1;
- LET i=1;
- WHILE ( rc <> 0 ) LOOP
- LET rc = aus_refresh_stats_orig(-1,i);
- LET i=i+1;
- END LOOP;
- RETURN rc;
- END FUNCTION;
- CREATE FUNCTION informix.aus_refresh_stats_orig(task_id INTEGER, task_seq INTEGER)
- RETURNING integer
- DEFINE rc INTEGER;
- DEFINE cnt INTEGER;
- DEFINE del INTEGER;
- DEFINE t_partnum INTEGER;
- DEFINE last_partnum INTEGER;
- DEFINE t_dbs_partnum INTEGER;
- DEFINE last_dbs_partnum INTEGER;
- DEFINE t_id INTEGER;
- DEFINE t_type CHAR(1);
- DEFINE t_cmd CHAR(8192);
- DEFINE p_cmd CHAR(200);
- DEFINE t_priority BIGINT;
- DEFINE param_pdq INTEGER;
- --TRACE "FUNCTION aus_refresh_stats_orig";
- LET rc = 0;
- LET cnt = 0;
- LET del = 0;
- LET last_partnum = 0;
- LET t_partnum = NULL;
- --SET DEBUG FILE TO "/tmp/aus.refresh."||task_seq;
- --TRACE ON;
- -- Get the config thresholds
- SELECT MAX(value::integer) INTO param_pdq
- FROM sysadmin:ph_threshold WHERE name = "AUS_PDQ";
- IF param_pdq IS NULL THEN
- LET param_pdq = 0;
- ELIF param_pdq < 0 THEN
- LET param_pdq = 0;
- ELIF param_pdq > 100 THEN
- LET param_pdq = 100;
- END IF
- IF param_pdq > 0 AND is_pdq_allowed() > 0 THEN
- LET p_cmd = "SET PDQPRIORITY " ||param_pdq;
- END IF
- BEGIN
- ON EXCEPTION IN ( -206 ) -- Exit if aus_cmd_* tables are not found
- END EXCEPTION
- FOREACH SELECT --+ FIRST_ROWS
- aus_cmd_id, RTRIM(aus_cmd_exe),aus_cmd_partnum, aus_cmd_priority,
- aus_cmd_type, aus_cmd_dbs_partnum
- INTO
- t_id, t_cmd, t_partnum, t_priority, t_type , t_dbs_partnum
- FROM aus_command
- WHERE aus_cmd_state = 'P' -- Pending
- ORDER BY aus_cmd_priority DESC, aus_cmd_partnum, aus_cmd_type DESC
- --TRACE "LAST partnum ="||last_partnum;
- IF last_partnum == 0 THEN
- LET last_partnum = t_partnum;
- LET last_dbs_partnum = t_dbs_partnum;
- LET cnt = cnt + 1;
- ELIF last_partnum <> t_partnum THEN
- LET last_partnum = t_partnum;
- IF t_priority > 100000 THEN
- IF last_dbs_partnum <> t_dbs_partnum THEN
- CONTINUE FOREACH;
- END IF
- IF cnt > 100 THEN
- EXIT FOREACH;
- END IF
- LET cnt = cnt + 1;
- ELSE
- EXIT FOREACH;
- END IF
- END IF
- --TRACE "UPDATING cmd_id="||t_id ||" TABLE "|| t_partnum||" MODE " || RTRIM(t_type)::lvarchar ||" CNT =" ||cnt;
- DELETE FROM aus_command WHERE aus_cmd_id = t_id;
- LET del = DBINFO("sqlca.sqlerrd2");
- /* If we did not delete anything then skip this row, parallel */
- IF del < 0 THEN
- CONTINUE FOREACH;
- END IF
-
- BEGIN
- ON EXCEPTION IN ( -206 ) -- IGNORE if the table is gone
- END EXCEPTION WITH RESUME
- EXECUTE IMMEDIATE p_cmd;
- EXECUTE IMMEDIATE t_cmd;
- IF is_pdq_allowed() > 0 THEN
- SET PDQPRIORITY 0;
- END IF
- END
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority, aus_cmd_state,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( t_id, t_type, t_priority, 'C', t_dbs_partnum, t_partnum, TRIM(t_cmd));
- LET rc=rc+1;
- END FOREACH
-
- IF cnt > 0 THEN
- UPDATE aus_cmd_info
- SET (aus_ci_done_tables) = (aus_ci_done_tables + cnt)
- WHERE aus_ci_dbs_partnum = last_dbs_partnum;
- ELIF task_id > 0 THEN
- /* I have no more work to and I am a real task disable my self */
- UPDATE ph_task SET ( tk_enable ) = ('F') WHERE tk_id = task_id;
- END IF
- END
- RETURN rc;
- END FUNCTION;
- CREATE FUNCTION informix.aus_enable_refresh()
- RETURNING INTEGER
- UPDATE ph_task SET ( tk_enable) =
- ('T')
- WHERE tk_name matches "Auto Update Statistics Refresh*";
- END FUNCTION;
- CREATE FUNCTION informix.aus_create_cmd_dist(dbsname char(128), dbs_partnum INTEGER,
- tabname CHAR(128), partnum INTEGER, tabid INTEGER,
- param_rules INTEGER, expire_priority BIGINT)
- RETURNING BIGINT
- DEFINE rc INTEGER;
- DEFINE cnt INTEGER;
- DEFINE collist CHAR(7600);
- DEFINE maxcollength INTEGER;
- DEFINE collistlen INTEGER;
- DEFINE collen INTEGER;
- DEFINE t_colno INTEGER;
- DEFINE t_resolution DECIMAL(5,3);
- DEFINE last_resolution DECIMAL(5,3);
- DEFINE t_confidence DECIMAL(5,3);
- DEFINE t_smplsize DECIMAL(16,3);
- DEFINE t_colname CHAR(128);
- DEFINE tmp CHAR(128);
- DEFINE lasttmp CHAR(128);
- DEFINE end_str CHAR(256);
- --TRACE "FUNCTION aus_create_cmd_dist( database=" || RTRIM(dbsname) || " tabid = " || tabid || " )" ;
- LET collist = NULL;
- LET rc = 0;
- /* Note the l must be lower case, so we
- * can order by later can get the order as
- * H, M, l
- * when building commands.
- */
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority, aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "l", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS LOW FOR TABLE " || RTRIM(dbsname) || ":"
- || RTRIM(tabname)
- );
- /* FIND ALL HIGH COLUMNS
- * The first part finds all column
- * which were previously in sysdistrib
- * The second part SQL is executed if
- * the auto rules are enable, it finds
- * the minimum set of columns for this
- * table for the optimizer
- */
- UPDATE aus_work_icols SET ( aus_icols_mode ) = ( 'H' )
- WHERE aus_icols_tabid = tabid
- AND aus_icols_colno in ( SELECT aus_dist_colno FROM aus_work_dist
- WHERE aus_dist_tabid = tabid
- AND aus_dist_mode = 'H');
- --TRACE "EXISTING HIGH ROWS UPDATED " || DBINFO("sqlca.sqlerrd2") || ")";
- IF param_rules > 0 THEN
- UPDATE aus_work_icols SET ( aus_icols_mode ) = ( decode(aus_icols_lkey,'Y','H','M') )
- WHERE aus_icols_tabid = tabid
- AND aus_icols_mode IS NULL;
- --TRACE "PARAM_RULES ROWS UPDATED " || DBINFO("sqlca.sqlerrd2") || ")";
- ELSE
- SELECT count(*) INTO cnt
- FROM aus_work_icols
- WHERE aus_icols_mode IS NULL AND aus_icols_tabid = tabid;
-
- IF cnt > 0 THEN
- UPDATE aus_cmd_info SET
- (aus_ci_missed_tables) = (aus_ci_missed_tables + 1)
- WHERE aus_ci_database = dbsname;
- END IF
- END IF
- /** HIGH COLUMNS **/
- LET collist = NULL;
- LET maxcollength = 7600;
- LET collistlen = 0;
- LET collen = 0;
- LET tmp = NULL;
- LET lasttmp = NULL;
- FOREACH SELECT
- aus_icols_colno, aus_icols_colname, NVL(aus_dist_resolution,0.5)
- INTO
- t_colno, t_colname, t_resolution
- FROM aus_work_icols , OUTER aus_work_dist
- WHERE aus_icols_tabid = aus_dist_tabid
- AND aus_icols_colno = aus_dist_colno
- AND aus_icols_tabid = tabid
- AND aus_icols_mode = 'H'
- ORDER BY aus_dist_resolution, aus_dist_colno
- IF collist IS NULL THEN
- LET collist = RTRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- LET last_resolution = t_resolution;
- LET end_str = " RESOLUTION " || t_resolution || " DISTRIBUTIONS ONLY";
- ELIF last_resolution == t_resolution THEN
- LET collen = LENGTH(RTRIM(t_colname));
- -- TRACE "collist len: " || collistlen;
- IF collen + collistlen + 2 >= maxcollength THEN
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "H", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS HIGH FOR TABLE " || RTRIM(dbsname)
- || ":" || RTRIM(tabname)
- || " ( " || TRIM(collist) || " ) " || TRIM(end_str)
- );
- LET collist = RTRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- ELSE
- LET collist = RTRIM(collist) || ", " ||
- RTRIM(t_colname);
- LET collistlen = collistlen + collen + 2;
- END IF
- ELSE
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "H", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS HIGH FOR TABLE " || RTRIM(dbsname)
- || ":" || RTRIM(tabname)
- || " ( " || TRIM(collist) || " ) " || TRIM(end_str)
- );
- LET collist = TRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- LET end_str = " RESOLUTION " || t_resolution || " DISTRIBUTIONS ONLY";
- LET last_resolution = t_resolution;
- END IF
- --TRACE "COLLIST LENGTH: " || LENGTH(TRIM(collist));
- --TRACE "HIGH Colname " || RTRIM(t_colname);
- END FOREACH
- IF collist IS NOT NULL THEN
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "H", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS HIGH FOR TABLE "|| RTRIM(dbsname)
- || ":" || RTRIM(tabname)
- || " ( "|| RTRIM(collist) || " ) " || TRIM(end_str)
- );
- END IF
- /*
- -- FIND ALL MED COLUMNS
- */
- UPDATE aus_work_icols SET ( aus_icols_mode ) = ( 'M' )
- WHERE aus_icols_tabid = tabid
- AND aus_icols_colno in ( SELECT aus_dist_colno FROM aus_work_dist
- WHERE aus_dist_tabid = tabid
- AND aus_dist_mode = 'M');
- LET collist = NULL;
- LET collistlen = 0;
- LET collen = 0;
- LET tmp = NULL;
- LET lasttmp = NULL;
- FOREACH SELECT
- aus_icols_colno, aus_icols_colname,
- NVL(aus_dist_resolution,2.0), NVL(aus_dist_confidence,0.95),
- NVL(aus_dist_smplsize,0.0),
- NVL(aus_dist_smplsize,0)::DECIMAL(16,3) || "_" ||
- NVL(aus_dist_resolution,0)::DECIMAL(5,2) || "_" ||
- NVL(aus_dist_confidence,0)::DECIMAL(4,2) AS C
- INTO
- t_colno, t_colname,
- t_resolution, t_confidence,
- t_smplsize, tmp
- FROM aus_work_icols , OUTER aus_work_dist
- WHERE aus_icols_tabid = aus_dist_tabid
- AND aus_icols_colno = aus_dist_colno
- AND aus_icols_tabid = tabid
- AND aus_icols_mode = 'M'
- ORDER BY C, aus_dist_colno
- --TRACE "MED Colname " || RTRIM(t_colname) || " tmp" || RTRIM(tmp);
- --TRACE "collist " || TRIM(NVL(collist,"NULL"));
- --TRACE "lasttmp " || TRIM(NVL(lasttmp,"NULL"));
- --TRACE "tmp " || TRIM(NVL(tmp,"NULL"));
- IF collist IS NULL THEN
- LET collist = TRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- LET lasttmp = tmp;
- LET end_str = decode(t_smplsize,0.0," "," SAMPLING SIZE "
- || t_smplsize )
- || " RESOLUTION "|| t_resolution
- || " " || t_confidence
- || " DISTRIBUTIONS ONLY";
- --TRACE "NULL collist" || TRIM(t_colname) || " tmp" || TRIM(tmp);
- ELIF lasttmp IS NULL OR lasttmp == tmp THEN
- --TRACE "equal collist" || TRIM(t_colname) || " tmp" || TRIM(tmp);
- LET collen = LENGTH(RTRIM(t_colname));
- --TRACE "collist len: " || collistlen;
- IF collen + collistlen + 2 >= maxcollength THEN
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "M", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS MEDIUM FOR TABLE "
- || RTRIM(dbsname) || ":" || TRIM(tabname)
- || " (" || TRIM(collist) || ") " || TRIM(end_str)
- );
- LET collist = RTRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- ELSE
- LET collist = RTRIM(collist) || ", "
- || RTRIM(t_colname);
- LET collistlen = collistlen + collen + 2;
- END IF
- ELSE
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "M", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS MEDIUM FOR TABLE " || RTRIM(dbsname)
- || ":" || TRIM(tabname)
- || " ("|| TRIM(collist) || ") " || TRIM(end_str)
- );
- LET collist = TRIM(t_colname);
- LET collistlen = LENGTH(TRIM(collist));
- LET lasttmp = tmp;
- LET end_str = decode(t_smplsize,0.0," "," SAMPLING SIZE "
- || t_smplsize )
- || " RESOLUTION " || t_resolution
- || " " || t_confidence
- || " DISTRIBUTIONS ONLY";
- END IF
- --TRACE "MED Colname " || TRIM(t_colname);
- END FOREACH
- IF collist IS NOT NULL THEN
- INSERT INTO aus_command
- ( aus_cmd_id, aus_cmd_type, aus_cmd_priority,
- aus_cmd_dbs_partnum, aus_cmd_partnum, aus_cmd_exe )
- VALUES
- ( 0, "M", expire_priority, dbs_partnum, partnum,
- "UPDATE STATISTICS MEDIUM FOR TABLE " ||
- TRIM(dbsname) || ":" || TRIM(tabname)
- || " (" || TRIM(collist) || ") " || TRIM(end_str)
- );
- END IF
- RETURN 0;
- END FUNCTION;
- CREATE FUNCTION informix.aus_evaluator_dbs(dbsname CHAR(128), dbs_partnum INTEGER,
- has_mon_tab_prof INTEGER, inHDRmode INTEGER)
- RETURNING integer
- DEFINE aus_if_id INTEGER;
- DEFINE aus_if_tabname CHAR(128);
- DEFINE aus_if_tabid INTEGER;
- DEFINE aus_if_partnum INTEGER;
- DEFINE aus_if_ustlowts DATETIME YEAR TO SECOND;
- DEFINE aus_if_npused BIGINT;
- DEFINE aus_if_nrows BIGINT;
- DEFINE aus_real_rows BIGINT;
- DEFINE aus_if_nindexes INTEGER;
- DEFINE oldest_time DATETIME YEAR TO SECOND;
- DEFINE expired_value BIGINT;
- DEFINE max_seq_id INTEGER;
- DEFINE min_seq_id INTEGER;
- DEFINE hours_expired BIGINT;
- DEFINE nrows, isreads, iswrite, isrwrite, isdelete FLOAT;
- DEFINE delta_time BIGINT;
- DEFINE small_tab_exp BIGINT;
- DEFINE tmin BIGINT;
- DEFINE tmp BIGINT;
- DEFINE param_age_stats INTEGER; -- Number of hours
- DEFINE param_change INTEGER;
- DEFINE param_rules INTEGER;
- DEFINE param_small_tab BIGINT;
- DEFINE row_count INTEGER;
- DEFINE cmd CHAR(1000);
- --TRACE "FUNCTION aus_evaluator_dbs(database="||TRIM(dbsname)::lvarchar||")" ;
- -- Get the config thresholds
- SELECT MAX(value::float * 24)::integer INTO param_age_stats
- FROM sysadmin:ph_threshold WHERE name = "AUS_AGE";
- SELECT MAX(value::integer) INTO param_change
- FROM sysadmin:ph_threshold WHERE name = "AUS_CHANGE";
- SELECT MAX(value::integer) INTO param_rules
- FROM sysadmin:ph_threshold WHERE name = "AUS_AUTO_RULES";
- SELECT MAX(value::bigint) INTO param_small_tab
- FROM sysadmin:ph_threshold WHERE name = "AUS_SMALL_TABLES";
- /* Default values if not found in the config table */
- LET param_age_stats = NVL(param_age_stats ,30*24);
- LET param_change = NVL(param_change ,10);
- LET param_rules = NVL(param_rules ,1);
- LET param_small_tab = NVL(param_small_tab ,100);
- IF param_small_tab > 200000 THEN
- /* Can not let be higher than 200,000 as
- * will cause overflow of variable
- */
- LET param_small_tab = 200000;
- END IF
- LET row_count = 0;
- /* Loop through the specified database */
- FOREACH SELECT
- aus_info_id, aus_info_tabname, aus_info_tabid,
- aus_info_partnum, aus_info_ustlowts, aus_info_npused,
- aus_info_nrows, aus_info_nindexes
- INTO
- aus_if_id, aus_if_tabname, aus_if_tabid,
- aus_if_partnum, aus_if_ustlowts, aus_if_npused,
- aus_if_nrows, aus_if_nindexes
- FROM aus_work_info
- WHERE aus_info_db_partnum = dbs_partnum
- ORDER BY aus_info_ustlowts
- IF aus_if_partnum = 0 THEN
- LET cmd = "UPDATE aus_work_info SET (aus_info_nrows) = ("
- || " (SELECT sum(pt.nrows)"
- || " FROM sysmaster:sysptnhdr pt"
- || " WHERE pt.partnum IN (SELECT partn FROM "
- || TRIM(dbsname)::lvarchar||":sysfragments sfg"
- || " WHERE sfg.tabid = " || aus_if_tabid
- || " AND sfg.fragtype = 'T')))"
- || " WHERE aus_info_tabid = " || aus_if_tabid ;
- EXECUTE IMMEDIATE cmd;
- LET cmd = "UPDATE aus_work_info"
- || " SET(aus_info_partnum) = ((SELECT min(lockid)"
- || " FROM sysmaster:sysptnhdr ptn, "
- || TRIM(dbsname)::lvarchar||":sysfragments"
- || " sfg WHERE ptn.partnum = sfg.partn"
- || " AND sfg.tabid = " || aus_if_tabid
- || " AND sfg.fragtype = 'T' ))"
- || " WHERE aus_info_tabid = " || aus_if_tabid ;
- EXECUTE IMMEDIATE cmd;
- SELECT aus_info_nrows
- INTO aus_real_rows
- FROM aus_work_info
- WHERE aus_info_tabid = aus_if_tabid;
- ELSE
- SELECT sum(pt.nrows)
- INTO aus_real_rows
- FROM sysmaster:sysptnhdr pt
- WHERE pt.partnum = aus_if_partnum;
- END IF
- --TRACE "Checking table "||TRIM(dbsname)::lvarchar||"." || TRIM(aus_if_tabname)::lvarchar;
- --TRACE "Number of rows "||aus_real_rows;
- LET expired_value = 0;
- /* If the table is considered a small row table
- * expire the table and create the commands.
- */
- LET tmp = param_small_tab - aus_real_rows;
- IF tmp > 0 THEN
- LET small_tab_exp = tmp + 10000 * param_small_tab;
- ELSE
- LET small_tab_exp = 0;
- END IF
- /* Calculate the oldesttime between
- * the statistics and distributions
- */
- SELECT MIN(aus_dist_constr_time)
- INTO oldest_time
- FROM aus_work_dist
- WHERE aus_dist_tabid = aus_if_tabid
- AND aus_dist_constr_time IS NOT NULL ;
- IF oldest_time IS NULL AND aus_if_ustlowts IS NULL THEN
- --TRACE "No Statistics and distributions for "|| TRIM(dbsname)::lvarchar||"." || TRIM(aus_if_tabname)::lvarchar;
- IF param_rules == 0 THEN
- /* If we have no stats or dist and we are not
- * doing auto rules then continue to the next table
- */
- UPDATE aus_cmd_info SET
- (aus_ci_missed_tables) = (aus_ci_missed_tables + 1)
- WHERE aus_ci_dbs_partnum = dbs_partnum;
- CONTINUE FOREACH;
- ELIF small_tab_exp == 0 THEN
- /* We have auto rules on, but this tables is not small.
- */
- LET expired_value = 100;
- ELSE
- /* We have auto rules on, and a small table
- */
- LET expired_value = small_tab_exp;
- END IF
- GOTO do_commands;
- END IF
- IF oldest_time IS NULL THEN
- LET oldest_time = aus_if_ustlowts;
- ELIF (aus_if_ustlowts IS NOT NULL) AND (aus_if_ustlowts < oldest_time) THEN
- LET oldest_time = aus_if_ustlowts;
- END IF
- --TRACE "Oldest time for table "|| TRIM(aus_if_tabname)::lvarchar || " is "|| oldest_time;
- /* If we have a small table and
- * we have any stats or dist OR we are doing auto rules
- * THEN goto make the commands
- */
- IF (small_tab_exp > 0) AND
- ( oldest_time IS NOT NULL OR param_rules <> 0 ) THEN
- LET expired_value = small_tab_exp;
- GOTO do_commands;
- END IF
- /* If we are not applying basic rules
- * and we have no upd stats low information
- * for this table before then skip
- * this table now and look for distributions.
- */
- IF param_rules == 0 AND (aus_if_nrows IS NULL OR aus_if_ustlowts IS NULL) THEN
- GOTO do_distribution_eval;
- END IF
- /*
- * Check the age of the statistics
- * If never been done then assign 100
- */
- --TRACE "Start statistics checking basic row count " || expired_value;
- --TRACE "aus_if_nrows "|| NVL(aus_if_nrows,"NULL");
- --TRACE "aus_real_rows "|| NVL(aus_real_rows,"NULL");
- IF aus_if_nrows IS NULL OR aus_real_rows IS NULL THEN
- LET expired_value = expired_value + 100;
- ELSE
- LET tmp = (aus_real_rows - aus_if_nrows) / (aus_if_nrows+1) * 100;
- --TRACE "Change in basic row count " || tmp ||"%";
- IF ABS(tmp) > param_change THEN
- LET expired_value = expired_value + ABS(tmp);
- END IF
- END IF
- /*
- * Check the basic row count of the statistics
- * If never been done then assign 100
- */
- --TRACE "Start statistics checking for age " || expired_value ;
- IF oldest_time IS NULL THEN
- LET expired_value = expired_value + 100;
- ELSE
- --TRACE "param_age_stats "||param_age_stats;
- LET hours_expired = (
- ( ( (CURRENT - oldest_time)::INTERVAL HOUR(5) TO HOUR
- - param_age_stats UNITS HOUR))::char(20))::BIGINT;
- --TRACE "hours_expired "||hours_expired;
- IF hours_expired > 0 THEN
- LET expired_value = expired_value + hours_expired/24;
- END IF
- END IF
- --TRACE "INFO statistics checking basic row count END " || expired_value;
- <<do_distribution_eval>>
- --TRACE "Statitics checking advanced row count START " || expired_value;
- IF oldest_time IS NOT NULL AND has_mon_tab_prof == 1 THEN
- -- Find the MAX/MIN sequence numbers to use for this table statistics
- -- Currently we do not take into account onstat -z
- SELECT MAX(run.run_task_seq),
- MIN(run.run_task_seq),
- ((((MAX(run.run_time) - MIN(run.run_time))::
- INTERVAL MINUTE(9) TO MINUTE)::char(20))::BIGINT)
- INTO max_seq_id, min_seq_id, delta_time
- FROM ph_run run, ph_task task
- WHERE task.tk_id = run.run_task_id
- AND tk_name = "mon_table_profile"
- AND run.run_time > oldest_time;
- --TRACE "Delta Time "|| delta_time ||" max task_seq "||max_seq_id||" min task_seq "||min_seq_id;
- /* If we had 0 or 1 measurement then delta_time will be 0
- * we must skip this check, not enough data
- */
- IF delta_time > 0 THEN
- LET tmin = (((CURRENT - oldest_time)::
- INTERVAL MINUTE(9) TO MINUTE)::char(20))::BIGINT;
- { Get the number of UDIS for statistics }
- --TRACE "SELECT " || aus_if_partnum ;
- SELECT
- tmin * ((SUM(aft.nrows) - SUM(bef.nrows))/delta_time),
- tmin * ((SUM(aft.pf_isread) - SUM(bef.pf_isread))/delta_time),
- tmin * ((SUM(aft.pf_iswrite) - SUM(bef.pf_iswrite))/delta_time),
- tmin * ((SUM(aft.pf_isrwrite) - SUM(bef.pf_isrwrite))/delta_time),
- tmin * ((SUM(aft.pf_isdelete) - SUM(bef.pf_isdelete))/delta_time)
- INTO nrows, isreads, iswrite, isrwrite, isdelete
- FROM mon_table_profile bef, mon_table_profile aft
- WHERE aft.id = max_seq_id
- AND bef.id = min_seq_id
- AND aft.lockid = aus_if_partnum
- AND bef.lockid = aus_if_partnum
- AND bef.lockid = aft.lockid;
-
- --TRACE "Inserts " || iswrite || "Update " || isrwrite|| "Delete " || isdelete;
- LET tmp = (iswrite + isrwrite + isdelete) - ( aus_real_rows * param_change/100);
- --TRACE "Rows Changed " || (iswrite + isrwrite + isdelete) || " Precent Changed " || (iswrite + isrwrite + isdelete) / aus_real_rows ;
- IF tmp > 0 THEN
- LET expired_value = expired_value + 100 + tmp;
- END IF
- END IF
- END IF
- /*
- * DONE calculating the statistics ranking
- */
- IF expired_value == 0 THEN
- CONTINUE FOREACH;
- END IF
- <<do_commands>>
- --TRACE "Building stats on table "||TRIM(dbsname)::lvarchar||"." || TRIM(aus_if_tabname)::lvarchar;
- /* Build the update low stats command if required */
- LET tmp = aus_create_cmd_dist(dbsname, dbs_partnum, aus_if_tabname,
- aus_if_partnum, aus_if_tabid,
- param_rules , expired_value );
- --TRACE "NEW CMD row_count="||row_count;
- IF tmp < 0 THEN
- RETURN tmp;
- END IF
- LET row_count = row_count + 1;
- END FOREACH --- End aus_dbs_list FOREACH
- RETURN row_count;
- END FUNCTION;
- CREATE FUNCTION informix.aus_load_dbs_data(aus_dbsname CHAR(128), aus_dbs_partnum INTEGER
- ,inHDRmode INTEGER)
- RETURNING bigint
- DEFINE tmp CHAR(1500);
- DEFINE nrows BIGINT;
- DEFINE drows BIGINT;
- LET nrows = 0;
- LET drows = 0;
-
- /*
- ***********************************************************
- * Load the aus_work_info table from systables
- ************************************************************
- */
- LET tmp = "INSERT INTO aus_work_info ("
- || " aus_info_id, aus_info_tabname, aus_info_tabid, aus_info_partnum, "
- || " aus_info_ustlowts, aus_info_npused, aus_info_nrows, "
- || " aus_info_nindexes, aus_info_db_partnum "
- || " ) SELECT "
- || " 0, tabname, tabid, partnum, "
- || " ustlowts, npused, nrows, "
- || " nindexes, "
- || aus_dbs_partnum
- || " FROM "
- || TRIM(aus_dbsname)::lvarchar||":systables t "
- || " WHERE "
- || " t.tabtype='T'"
- ;
- EXECUTE IMMEDIATE tmp ;
- --TRACE "Loading "||TRIM(aus_dbsname)::lvarchar||":aus_work_info with ROWS(" || DBINFO("sqlca.sqlerrd2")||")";
- LET nrows = nrows + DBINFO("sqlca.sqlerrd2");
- IF (aus_dbsname == "sysadmin") THEN
- DELETE FROM aus_work_info WHERE aus_info_tabname LIKE "aus_work_%"
- AND aus_info_db_partnum = aus_dbs_partnum;
- LET nrows = nrows - 4;
- END IF;
- IF inHDRmode = 1 THEN
- CREATE INDEX informix.aus_work_info_idx1 ON aus_work_info(aus_info_tabid)
- ONLINE;
- CREATE INDEX informix.aus_work_info_idx2 ON aus_work_info(aus_info_partnum)
- ONLINE;
- ELSE
- CREATE INDEX informix.aus_work_info_idx1 ON aus_work_info(aus_info_tabid);
- CREATE INDEX informix.aus_work_info_idx2 ON aus_work_info(aus_info_partnum);
- END IF
- /*
- ***********************************************************
- * Load the aus_work_dist table from sysdistrib table
- ************************************************************
- */
- LET tmp = "INSERT INTO aus_work_dist ("
- || " aus_dist_id, aus_dist_tabid, aus_dist_colno, "
- || " aus_dist_mode, aus_dist_resolution, aus_dist_confidence, "
- || " aus_dist_smplsize, aus_dist_rowssmplde, aus_dist_constr_time, "
- || " aus_dist_ustnrows "
- || " ) SELECT "
- || " 0, tabid, colno, "
- || " mode, resolution, confidence, "
- || " smplsize,rowssmpld,constr_time, "
- || " ustnrows"
- || " FROM " || TRIM(aus_dbsname)::lvarchar||":sysdistrib d "
- || " WHERE d.seqno=1 "
- ;
- EXECUTE IMMEDIATE tmp ;
- LET drows = drows + DBINFO("sqlca.sqlerrd2");
- IF inHDRmode = 1 THEN
- CREATE INDEX informix.aus_work_dist_idx1 ON aus_work_dist
- (aus_dist_tabid,aus_dist_colno) ONLINE;
- ELSE
- CREATE INDEX informix.aus_work_dist_idx1 ON aus_work_dist
- (aus_dist_tabid,aus_dist_colno);
- END IF
- --TRACE "Loading "||TRIM(aus_dbsname)::lvarchar||":aus_work_dist with ROWS(" || DBINFO("sqlca.sqlerrd2")||")";
- /* We need to update the fragment tables partnum with
- * the lock id, so we can reference them as one item.
- * Also get the current number of rows.
- UPDATE aus_work_info
- SET ( aus_info_partnum, aus_info_nrows) =
- ( ( SELECT MAX(lockid), SUM(nrows)
- FROM sysmaster:systabnames t, sysmaster:sysptnhdr pt
- WHERE t.partnum = pt.partnum
- AND t.partnum = aus_info_partnum
- AND t.tabname = aus_info_tabname
- AND t.dbsname = aus_dbsname) )
- WHERE aus_info_db_partnum = aus_dbs_partnum
- AND aus_info_nrows = -1
- ;
- */
- /*
- ***********************************************************
- * Load the aus_work_icols table of all index colnames
- ************************************************************
- */
- LET tmp = "CREATE VIEW informix.aus_view (tabid,colno, colname,lkey) AS "
- || " SELECT "
- || " C.tabid, C.colno, MAX(C.colname), 'N' "
- || " FROM "
- || TRIM(aus_dbsname)::lvarchar||":syscolumns AS C, "
- || TRIM(aus_dbsname)::lvarchar||":sysindices AS I "
- || " WHERE "
- || " C.tabid = I.tabid "
- || " AND C.colno in "
- || " (ABS(ikeyextractcolno(indexkeys,0)), "
- || " ABS(ikeyextractcolno(indexkeys,1)) , "
- || " ABS(ikeyextractcolno(indexkeys,2)) , "
- || " ABS(ikeyextractcolno(indexkeys,3)) , "
- || " ABS(ikeyextractcolno(indexkeys,4)) , "
- || " ABS(ikeyextractcolno(indexkeys,5)) , "
- || " ABS(ikeyextractcolno(indexkeys,6)) , "
- || " ABS(ikeyextractcolno(indexkeys,7)) , "
- || " ABS(ikeyextractcolno(indexkeys,8)) , "
- || " ABS(ikeyextractcolno(indexkeys,9)) , "
- || " ABS(ikeyextractcolno(indexkeys,10)) , "
- || " ABS(ikeyextractcolno(indexkeys,11)) , "
- || " ABS(ikeyextractcolno(indexkeys,12)) , "
- || " ABS(ikeyextractcolno(indexkeys,13)) , "
- || " ABS(ikeyextractcolno(indexkeys,14)) , "
- || " ABS(ikeyextractcolno(indexkeys,15)) ) "
- || " GROUP BY 1,2,4 "
- || "UNION "
- || "SELECT "
- || " C.tabid, C.colno, MAX(C.colname), 'N' "
- || " FROM "
- || TRIM(aus_dbsname)::lvarchar||":syscolumns AS C, "
- || "aus_work_dist AS D "
- || " WHERE C.tabid = D.aus_dist_tabid "
- || " AND C.colno = D.aus_dist_colno"
- || " GROUP BY 1,2,4 "
- ;
- EXECUTE IMMEDIATE tmp ;
- LET tmp = "INSERT INTO aus_work_icols"
- || "(aus_icols_tabid, aus_icols_colno,aus_icols_colname,aus_icols_lkey) "
- || " SELECT tabid, colno, colname,lkey FROM aus_view";
- EXECUTE IMMEDIATE tmp ;
- --TRACE "Loading "||TRIM(aus_dbsname)::lvarchar||":aus_work_icols with ROWS(" || DBINFO("sqlca.sqlerrd2")||")";
- DROP VIEW aus_view;
- IF inHDRmode = 1 THEN
- CREATE INDEX informix.aus_work_icols_idx1 ON aus_work_icols
- (aus_icols_tabid,aus_icols_colno) ONLINE;
- ELSE
- CREATE INDEX informix.aus_work_icols_idx1 ON aus_work_icols
- (aus_icols_tabid,aus_icols_colno);
- END IF
- LET tmp = "UPDATE aus_work_icols SET aus_icols_lkey = 'Y' "
- || "WHERE aus_icols_tabid*65536 + aus_icols_colno "
- || " IN ( "
- || " SELECT tabid*65536 + ABS(ikeyextractcolno(indexkeys,0)) "
- || "FROM " || TRIM(aus_dbsname)::lvarchar||":sysindices)";
- EXECUTE IMMEDIATE tmp ;
- --TRACE "Updating lead keys for aus_work_icols," || DBINFO("sqlca.sqlerrd2")||" lead keys found";
- RETURN nrows;
- END FUNCTION;
- CREATE FUNCTION informix.aus_evaluator(eval_only BOOLEAN)
- RETURNING BIGINT
- IF eval_only THEN
- RETURN aus_evaluator(-1, 1, 0);
- END IF
- RETURN aus_evaluator(-1, 1, 1);
- END FUNCTION;
- CREATE FUNCTION informix.aus_evaluator(task_id INTEGER, task_seq INTEGER)
- RETURNING BIGINT
-
- RETURN aus_evaluator( task_id, task_seq, 1);
- END FUNCTION;
- CREATE FUNCTION informix.aus_evaluator(task_id INTEGER, task_seq INTEGER,myflags INTEGER)
- RETURNING BIGINT
- DEFINE aus_dbsname CHAR(128);
- DEFINE aus_dbs_partnum INTEGER;
- DEFINE trows BIGINT;
- DEFINE nrows BIGINT;
- DEFINE has_mon_tab_prof INTEGER;
- DEFINE param_debug CHAR(128);
- DEFINE dblocale CHAR(36);
- DEFINE logmode CHAR(3);
- DEFINE errnum INTEGER;
- DEFINE inHDRmode INTEGER;
- LET nrows = 0;
- LET trows = 0;
- SELECT FIRST 1 value INTO param_debug
- FROM sysadmin:ph_threshold WHERE name = "AUS_DEBUG";
- IF param_debug IS NOT NULL THEN
- --SET DEBUG FILE TO TRIM(param_debug)::lvarchar||".prc";
- --TRACE PROCEDURE;
- --TRACE ON;
- ELSE
- --SET DEBUG FILE TO "/tmp/aus.debug.off";
- --TRACE OFF;
- --TRACE ON;
- END IF
- LET errnum = aus_get_exclusive_access(task_id, task_seq);
- LET errnum = aus_cleanup_table(0);
- SELECT FIRST 1 DECODE(type, "Primary", 1, "Standard", 0, 0) INTO inHDRmode
- FROM sysmaster:sysdri;
- IF (inHDRmode = 1) THEN
- SET LOCK MODE TO WAIT 120;
- ELSE
- SET LOCK MODE TO WAIT 5;
- END IF
- LET errnum = aus_setup_table(inHDRmode);
- SET ISOLATION TO DIRTY READ;
- LET has_mon_tab_prof = aus_setup_mon_table_profile(task_id,task_seq,inHDRmode);
- IF has_mon_tab_prof == 1 THEN
- LET nrows = exectask( "mon_table_profile" );
- END IF
- /* Loop through all the logging databases
- * loading up the aus_work_info table
- */
- --TRACE "Begin examining each logging database";
- FOREACH SELECT TRIM(name), partnum
- INTO aus_dbsname, aus_dbs_partnum
- FROM sysmaster:sysdbspartn
- WHERE partnum NOT IN
- (select partnum
- FROM sysmaster:sysdbspartn
- WHERE bitand(flags, 3 ) > 0
- AND name NOT IN (SELECT value FROM sysadmin:ph_threshold
- WHERE name = "AUS_DATABASE_DISABLED" ))
- INSERT INTO ph_alert
- (ID, alert_task_id,alert_task_seq,alert_type,
- alert_color, alert_object_type,
- alert_object_name, alert_message,alert_action)
- VALUES
- (0,task_id, task_seq, "INFO", "yellow", "DATABASE",
- "Auto Update Statistics",
- "Skipping database ["||trim(aus_dbsname)||
- "] for Auto Update Statistics. ",
- NULL);
- END FOREACH
- FOREACH SELECT TRIM(D.name), D.partnum,
- decode(bitand(D.flags,5),0,'N',4,'A','L') as logmode, T.collate
- INTO aus_dbsname, aus_dbs_partnum, logmode, dblocale
- FROM sysmaster:sysdbspartn D, sysmaster:systabnames T
- WHERE bitand(D.flags, 3 ) > 0 --- Not ansi yet need owner names
- AND D.name <> "sysmaster"
- AND D.partnum = T.partnum
- AND D.name NOT IN (SELECT value FROM sysadmin:ph_threshold
- WHERE name = "AUS_DATABASE_DISABLED" )
-
- INSERT INTO aus_cmd_info
- (aus_ci_dbs_partnum, aus_ci_need_tables,
- aus_ci_database, aus_ci_locale, aus_ci_logmode, aus_ci_stime)
- VALUES
- (aus_dbs_partnum, 0,
- aus_dbsname, dblocale, logmode, aus_get_realtime());
- --TRACE "Starting database loading " || RTRIM(aus_dbsname);
- LET nrows = aus_load_dbs_data(aus_dbsname, aus_dbs_partnum, inHDRmode);
- --TRACE "Starting database evaluation";
- LET trows = aus_evaluator_dbs(aus_dbsname, aus_dbs_partnum,
- has_mon_tab_prof, inHDRmode);
- UPDATE aus_cmd_info
- SET (aus_ci_need_tables,aus_ci_etime) =
- (aus_ci_need_tables + trows, aus_get_realtime())
- WHERE aus_ci_database = aus_dbsname;
- IF trows < 0 THEN
- EXIT FOREACH;
- END IF
- IF trows > 0 THEN
- INSERT INTO ph_alert
- (ID, alert_task_id,alert_task_seq,alert_type,
- alert_color, alert_object_type,
- alert_object_name, alert_message,alert_action)
- VALUES
- (0,task_id, task_seq, "INFO", "yellow", "DATABASE",
- "Auto Update Statistics",
- "Found "||trows||" table(s) in database ["||trim(aus_dbsname)|| "]"
- || " which need statistics updated. ",
- NULL);
- ELSE
- INSERT INTO ph_alert
- (ID, alert_task_id,alert_task_seq,alert_type,
- alert_color, alert_object_type,
- alert_object_name, alert_message,alert_action)
- VALUES
- (0,task_id, task_seq, "INFO", "green", "DATABASE",
- "Auto Update Statistics",
- "Found "||trows||" table(s) in database ["||trim(aus_dbsname)|| "]"
- || " which need statistics updated.",
- NULL);
- END IF
- DROP INDEX aus_work_info_idx1;
- DROP INDEX aus_work_info_idx2;
- DROP INDEX aus_work_dist_idx1;
- DROP INDEX aus_work_icols_idx1;
- TRUNCATE TABLE aus_work_info;
- TRUNCATE TABLE aus_work_dist;
- TRUNCATE TABLE aus_work_icols;
- END FOREACH --- End Database FOREACH
- UPDATE aus_cmd_info
- SET (aus_ci_etime) = ( aus_get_realtime())
- WHERE aus_ci_database IS NULL;
- LET errnum = aus_cleanup_table(1);
- IF inHDRmode = 1 THEN
- CREATE INDEX informix.aus_command_ix1 ON aus_command(aus_cmd_id) ONLINE;
- CREATE INDEX informix.aus_command_ix2 ON aus_command( aus_cmd_state,
- aus_cmd_priority DESC, aus_cmd_partnum, aus_cmd_type DESC)
- ONLINE;
- ELSE
- CREATE INDEX informix.aus_command_ix1 ON aus_command(aus_cmd_id);
- CREATE INDEX informix.aus_command_ix2 ON aus_command(aus_cmd_state,
- aus_cmd_priority DESC, aus_cmd_partnum, aus_cmd_type DESC);
- END IF
- LET errnum = aus_rel_exclusive_access();
- IF bitand(myflags,1) > 0 THEN
- LET errnum = aus_enable_refresh();
- END IF
- RETURN nrows;
- END FUNCTION;
- {*********************************************************
- *
- * The following section create the task in the database
- * scheduler used by the AUS feature
- *
- ********************************************************
- *}
- DELETE from ph_task WHERE tk_name = "Auto Update Statistics Evaluation";
- INSERT INTO ph_task
- (
- tk_name,
- tk_type,
- tk_group,
- tk_description,
- tk_execute,
- tk_start_time,
- tk_stop_time,
- tk_frequency,
- tk_enable
- )
- VALUES
- (
- "Auto Update Statistics Evaluation",
- "TASK",
- "PERFORMANCE",
- "To Evaluate which columns and tables should have the statistics and distributions refreshed.",
- "aus_evaluate_stats",
- DATETIME(01:00:00) HOUR TO SECOND,
- DATETIME(01:10:00) HOUR TO SECOND,
- INTERVAL ( 1 ) DAY TO DAY,
- 't'
- );
- DELETE from ph_task WHERE tk_name = "Auto Update Statistics Refresh";
- INSERT INTO ph_task
- (
- tk_name,
- tk_type,
- tk_group,
- tk_description,
- tk_execute,
- tk_start_time,
- tk_stop_time,
- tk_frequency,
- tk_monday,
- tk_Tuesday,
- tk_Wednesday,
- tk_Thursday,
- tk_Friday,
- tk_sunday,
- tk_saturday,
- tk_enable
- )
- VALUES
- (
- "Auto Update Statistics Refresh",
- "TASK",
- "PERFORMANCE",
- "Refreshes the statistics and distributions which were recommended by the evaluator.",
- "aus_refresh_stats",
- DATETIME(01:11:00) HOUR TO SECOND,
- DATETIME(05:00:00) HOUR TO SECOND,
- INTERVAL ( 1 ) DAY TO DAY,
- 'f',
- 'f',
- 'f',
- 'f',
- 'f',
- 't',
- 't',
- 't'
- );
- create function aus_evaluate_stats(task_id integer, seq_id integer)
- returns integer
- external name '(aus_evaluator)'
- language C;
- CREATE FUNCTION aus_evaluator_upgrade()
- RETURNING INTEGER
- UPDATE ph_task SET
- (tk_execute) = ( "aus_evaluate_stats")
- WHERE tk_name = 'Auto Update Statistics Evaluation';
- RETURN 0;
- END FUNCTION;
- CREATE FUNCTION aus_evaluator_downgrade()
- RETURNING INTEGER
- UPDATE ph_task SET
- (tk_execute) = ( "aus_evaluator")
- WHERE tk_name = 'Auto Update Statistics Evaluation';
- RETURN 0;
- END FUNCTION;
- create function informix.aus_refresh_stats(task_id integer, seq_id integer,
- run_time integer default 0)
- returns integer
- external name '(aus_refresh)'
- language C;
- CREATE FUNCTION informix.aus_refresh_upgrade()
- RETURNING INTEGER
- UPDATE ph_task SET
- ( tk_execute, tk_enable ) = ( "aus_refresh_stats", 't' )
- WHERE tk_name = 'Auto Update Statistics Refresh';
- UPDATE ph_task SET
- ( tk_frequency ) = ( INTERVAL ( 1 ) DAY TO DAY )
- WHERE tk_name = 'Auto Update Statistics Refresh'
- AND tk_frequency < INTERVAL ( 1 ) DAY TO DAY;
- RETURN 0;
- END FUNCTION;
- CREATE FUNCTION informix.aus_refresh_downgrade()
- RETURNING INTEGER
- UPDATE ph_task SET
- ( tk_execute, tk_enable, tk_frequency ) =
- ( "aus_refresh_stats_orig", 'f', INTERVAL ( 1 ) SECOND TO SECOND )
- WHERE tk_name = 'Auto Update Statistics Refresh';
- RETURN 0;
- END FUNCTION;
- {**************************************************************************
- MARK THE ABOVE TASKS AS SYSTEM TASKS AND FOR PRIVATE THREAD
- **************************************************************************}
- UPDATE ph_task SET tk_attributes = BITOR(tk_attributes, 12)
- WHERE tk_name
- IN ('Auto Update Statistics Evaluation',
- 'Auto Update Statistics Refresh');
- {**************************************************************************
- RECORD THE VERSION OF AUS INSTALLED
- **************************************************************************}
- DELETE FROM ph_version WHERE object = 'AUS' and type = 'version';
- INSERT INTO ph_version(object,type,value) VALUES ( 'AUS','version', 23 );
- CLOSE DATABASE;
|