DB2 iseries materialized view refresh - db2

I have created the following materialized query table:
CREATE TABLE SCHEMA.TABLE AS
(SELECT * FROM SCHEMA.TABLEEXAMPLE)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY USER
DISABLE QUERY OPTIMIZATION;
When I execute a REFRESH TABLE SCHEMA.TABLE it get locked for others users to read from it.
Reading this doc from IBM https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000977.html
I tried to execute this statement:
REFRESH TABLE SCHEMA.TABLE ALLOW READ ACCESS
But I get the following error: SQL State: 42601 Unexpected keyword ALLOW
What I'm missing on statement? Is there other way to allow read access to materialized query table while it is beign updated?

MQTs on Db2 for IBM i lag behind the functionality available in Db2 for LUW.
I've never bother with them, instead an encoded vector index (EVI) with computed columns meets every need I've every considered. (Note that Db2 LUW doesn't have EVIs)
Per Mao's comment, you might try deleting an recreating the MQT with the following:
CREATE TABLE SCHEMA.TABLE AS
(SELECT * FROM SCHEMA.TABLEEXAMPLE)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY USER
DISABLE QUERY OPTIMIZATION
with NC;
But I think a refresh would still require exclusive access to the MQT.
The only options I can think of for "refreshing" an MQT while it is being used
programmatically , using either triggers on the base tables or perhaps a process that uses SQL to update a few rows at a time.
removing the DISABLE QUERY OPTIMIZATION and not accessing the MQT directly. Instead depend on the optimizer to access it when appropriate. Now you can create a version of it every few hours and the Db should start using the newer version for new queries. Once the older one is no longer being used, you delete it (or REFRESH it)

Related

How to obtain an indefinite lock on database in Rails (postgres database) for QA purposes?

I'm trying to obtain an indefinite lock on my Postgresql database (specifically on a table called orders) for QA purposes. In short, I want to know if certain locks on a table prevent or indefinitely block database migrations for adding columns (I think ALTER TABLE grabs an ACCESS EXCLUSIVE LOCK).
My plan is to:
grab a table lock or a row lock on the orders table
run the migration to add a column (an ALTER TABLE statement that grabs an ACCESS EXCLUSIVE LOCK)
issue a read statement to see if (2) is blocked (the ACCESS EXCLUSIVE LOCK blocks reads, and so this would be a problem that I'm trying to QA).
How would one do this? How do I grab a row lock on a table called orders via the Rails Console? How else could I do this?
Does my plan make sense?
UPDATE
It turns out open row-level transactions actually do block ALTER TABLE statements that grab an ACCESS EXCLUSIVE LOCK like table migrations that add columns. For example, when I run this code in one process:
Order.first.with_lock do
binding.pry
end
It blocks my migration in another process to add a column to the orders table. That migration's ACCESS EXCLUSIVE LOCK blocks all reads and select statements to the orders table, causing problems for end users.
Why is this?
Let's say you're in a transaction, selecting rows from a table with various where clauses. Halfway through, some other transaction adds a column to that table. Now you are getting back more fields than you did previously. How is your application supposed to handle this?

Postgres GRANT not applied on parent

I'm in trouble with grant in postgresql (version 9.3).
I'm trying to restrict a ROLE 'client_1'. I want it to be able to do only select for one table. But there is inheritance between tables.
Here is my table structure:
CREATE TABLE public.table_a (...);
CREATE TABLE table_a_partitions.child_1 (...) INHERITS (public.table_a);
CREATE TABLE table_a_partitions.child_2 (...) INHERITS (public.table_a);
GRANT SELECT ON table_a_child_1 TO client_1;
It's okay when I do a select on child_2, there is an error, but if I do a SELECT * FROM table_a; for example it also reads the forbidden table child_2. I would my client access only child_1 (and some other in the future) results when he does SELECT * FROM table_a;.
Is there a simple way to solve this problem ?
Thank you
You would need to use a VIEW in PostgreSQL 9.3 to solve this problem. If you upgrade to 9.5, however, you could use row-level security.
As a note as to why, the grant check only occurs on the level of the initial relation queried. This means if you query a view, you need access to the view's contents, but the view owner (NOT YOU) needs access to the underlying relations. This allows a view to be useful for information hiding. Similarly with inheritance, this structure allows you to forbid rows to be inserted or queried directly from partitions of a table, but to allow different queries via the parent table. So this is a consequence of design priorities, not a bug.
Before row-level security, you would basically create a view and fold in user privilege criteria into the view (with partitioning/inheritance this is also a good idea for other reasons since your insert/update/delete triggers can return exactly what the db would do even though it cannot on a table).
As for row-level security, PostgreSQL 9.5 does allow you to specify row-level policies (conditions that get appended to insert/select/update/delete queries) and that provides something a little more manageable in some cases than the view approach.

(MON_OBJ_METRICS) in db2

I am very much new to db2. My requirement is I just want to remove tracking system on a user table. I mean tracking of all kind of DML operations on a particular table. I read some thing from the google, according to my understanding this can be done by this parameter in (MON_OBJ_METRICS) parameter at db level.does my understanding is worth ?
How can i disable this parameter ? If i disable this parameter at db level, does all the tables under this particular database are quit from tracking ?
On sql server we can do this by set_change_tracking parameter. I am looking for same functionality in db2luw.
Kindly help me out & please excuse me , as i m a kid in db2
MON_OBJ_METRICS (and DFT_MON_TABLE, from your other post) are used for performance monitoring only. The keep track of the number of rows read, inserted, deleted and updated (among other things), but do not track actual data changes.
Change tracking in MS SQL Server is used for data capture to feed replication processes, not monitoring.
In DB2 you can set the DATA CAPTURE table parameter to NONE, but be aware that this is its default value. You can check the current value for a table with the following query:
SELECT datacapture
FROM syscat.tables
WHERE tabschema = <schema>
AND tabname = <tablename>
You can modify the setting using:
ALTER TABLE <schema>.<tablename> DATA CAPTURE NONE
In addition to the DATA CAPTURE option that Ian described, DB2 v10.1 and newer can also track changes made to tables that are enabled for system-period temporal versioning. System-period versioning is not enabled by default, but if it is, every DML change to the table is automatically captured into a designated history table with the same column layout. Unlike SQL Server's retention policy for tracking changes, the DBA is responsible for pruning old row versions out of DB2 temporal history tables.
The SYSCAT.TABLES view will reveal which tables are enabled for system-period versioning:
SELECT tabschema, tabname FROM syscat.tables
WHERE temporaltype IN ( 'B', 'S' )
The following statement will disable whichever temporal features are enabled ( system-period, business-period, or both):
ALTER TABLE <schema>.<tablename> DROP VERSIONING

db2 reorganize a table

When I alter a table in db2, I have to reorganize it
so I execute the next query:
Call Sysproc.admin_cmd ('reorg Table myTable');
I m searching an appropriate solution to reorganize a table when it s altered, or reorganize all the schema after making various modifications
You can determine when tables will require a REORG by looking at SYSIBMADM.ADMINTABINFO:
select tabschema, tabname
from sysibmadm.admintabinfo
where reorg_pending = 'Y'
You may also want to look at the NUM_REORG_REC_ALTERS column as this may show you additional tables that don't require reorganization due to various ALTER TABLE statements.
The reorg operation is similar to a defrag in hard disk. It frees empty spaces in pages, and eventually it could reorganize data according to an index. Depending on the features, it creates the compression dictionary and compress data.
As you can see, reorg operation is an administrative task, and it is not necessary each time data is modified. A database could run without reorg.
It order to ease this, DB2 included autonomic features like automatic backup, however this doesn't answer you own question. This will only trigger reorg on tables that need that.
To reorg a table explicitly you need to execute the command reorg http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.cmd.doc/doc/r0001966.html
or via the admin_cmd http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.rtn.doc/doc/r0023582.html
in db2 config we have:
Automatic reorganization (AUTO_REORG) = OFF
we can set auto_reorg to on

DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001, SQLERRMC=68

I am getting this error when I ran:
alter table tablename add column columnname varchar(1) default 'N';
DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001, SQLERRMC=68
How to solve it?
The alter statement wants to get an X lock on this row in SYSIBM.SYSTABLES. There is an open transaction that has this row/index value in an incompatible lock state. This lock that caused the timeout could even be from an open cursor that reads this row with an RS or RR isolation level.
Terminate any other SQL currently trying to query SYSTABLES and any utilities that may be trying to update SYSTABLES like reorg and runstats then try the alter again.
See DB2 Info center (I picked the one for DB2 10, most likely this error code is the same in other versions, but doublecheck!).
Seems there is a transaction open on your table, that prevents your alter command from execution.
after you have Altered a table you need to Reorg: reade up on it here:
Run the runstats script, which is a DB2 script, at regular intervals and set the script to gather RUNSTATS WITH DISTRIBUTION AND DETAILED INDEXES ALL.
In addition to running the runstats scripts regularly, you can perform the following tasks to avoid the problem:
Use REOPT ONCE or REOPT ALWAYS with the command-line interface (CLI ) packages to change the query optimization behavior.
In the DB2 database, change the table to make it volatile. Volatile tables indicate to the DB2 optimizer that the table cardinality can change significantly at run time (from empty to large and vice versa). Therefore, DB2 uses an index to access a table rather than a table scan.