Alexey Maslov · Sep 8, 2016 go to post

Kevin, in addition to Bob's point:

you can deploy mirror comprises two members: #1 - primary and #2 - async (reporting/RW). Definetely it is not real DR solution, just a way to implement two potentially different systems working with two slightly different copies of the same database.

Alexey Maslov · Sep 8, 2016 go to post

Bob, I suggested to deploy reporting async just because Kevin mentioned that his boxes have different roles: one is running production system, another is being used for development. How it can fit Kevins's needs depends on several factors, one of which: whether or not his code and data reside in separated databases.

Alexey Maslov · Sep 26, 2016 go to post

Mike,
I fully agree with you that newbies should be aware of dotted syntax and some other old idioms that can be met in legacy code, but it seems that they also need some judgment from "oldies": which coding constructions are more or less acceptable and which should be avoided by any means (like usage of $ZOrder and $ZNext functions).
P.S. (offtop) Could we meet each other in Bratislava in 1992?

Alexey Maslov · Sep 26, 2016 go to post

Stephen, thank you for the info.

May I ask you to clarify a little: should the console log messages like this one

08/29/16-09:41:03:376 (4864) 1 Operating System shutdown!  Cache performing fast shutdown.

be considered as sympthoms of this issue?

Alexey Maslov · Sep 26, 2016 go to post

Steve, 
> if I were to see this I would then check that everything closed nicely
How to do this check? Every Caché startup after its fast shutdown is corresponded with the following message in console log:

09/16/16-13:48:38:305 (2132) 2 Previous system shutdown was abnormal, system forced down or crashed

while there are no logged signs of "normal" forcing down (system tables dump, etc). Maybe this rule has exceptions, but I've never seen them.

==
Thank you,
Alex

Alexey Maslov · Sep 26, 2016 go to post

As to documentation for Caché v. 2015.1, ShutdownTimeout parameter ranges from 120 to a maximum of 100,000 seconds with the default of 300 seconds. In my case its value is 120 seconds, but in the worst cases I've managed to find in my log shutdown performed faster, approx. 40 seconds, e.g.: 

05/18/16-18:51:45:817 (3728) 1 Operating System shutdown!  Cache performing fast shutdown.
05/18/16-18:52:27:302 (3728) 1 Forced 11 user processes.  They may not have completed.
05/18/16-18:52:27:302 (3728) 0 Fast shutdown complete
05/18/16-18:52:27:474 (3728) 0 CONTROL exited due to force
05/18/16-18:52:27:630 (3656) 0 JRNDMN exited due to force
05/18/16-18:52:27:614 (3560) 0 GARCOL exited due to force
05/18/16-18:52:27:802 (1064) 0 EXPDMN exited due to force
05/18/16-18:52:27:786 (3760) 0 No blocks pending in WIJ file
05/18/16-18:52:27:880 (3760) 0 WRTDMN exited due to force

while one can see word "force" in the log... It seems that OS shutdown is a special case of forcing Caché down, without waiting ShutdownTimeout seconds. I plan to adjust the registry value as suggested in this article and check what will happen on the next OS shutdown (when I decide to do it).

Alexey Maslov · Sep 26, 2016 go to post

Checking .LCK files is useless in most cases as Caché service auto-starts with OS startup. Of course, switching auto-start off is not a problem for development/testing environment.

Frank touched another interesting question: how long WaitToKillServiceTimeout should be? If we set it to ShutdownTimeout + Typical_Real_Shutdown_Time, and Caché hangs during OS shutdown, I bet that typical Windows admin won't wait 5 minutes and finish with hardware reset...  Choosing between bad and worse, I'd set
WaitToKillServiceTimeout = Typical_Real_Shutdown_Time
letting OS to force Caché down in rare cases when it hangs.

Alexey Maslov · Sep 28, 2016 go to post

It is hard to guess what a kind of problem you have without looking at Cache Security audit records of your logon attempts.

Alexey Maslov · Sep 29, 2016 go to post

Basic and advanced mode were in an old version of another tool named ^Buttons. With ^pButtons you have an option to reduce the number of OS commands being performed, as it was shown in Tip #4.

Alexey Maslov · Oct 3, 2016 go to post

However, the Newbie can ignore it all, by using Caché SQL

If so, how do you answer the curious Newbie's question: why should I use Caché at all, as a few SQL implementations are available for free nowadays?

Usually those questions were answered like this: Caché provides Unified Data Architecture that allows several access methods to the same data (bla-bla-bla), and the quickest of them is Direct Global Access. If we answer this way, we should teach how to traverse across the globals, so you are doing the very right and useful thing!
There is only one IMHO: semantics can be more difficult to catch than syntax. Whether one writes `while (1) { ... }` or `for { ... }`, it's basically all the same, while using $order or $query changes traverse algorithm a lot, and it seems that this stuff should be discussed in more details.

Alexey Maslov · Oct 6, 2016 go to post

Hi Murray, thank you for keep writing very useful articles.

ECP is a rather complex stuff and it seems it does worth addition writing.

Just a quick comment to your point: 

For sustained throughput average write response time for journal sync must be:
<=0.5 ms with maximum of <=1 ms.

How can one distinguish journal syncs from other journal records looking at iostat log only? It seems that 0.5-1ms limit should be applied to  every journal write, not only to sync records.

And a couple of small questions. You wrote that
1) "...each SET or KILL the current journal buffer is written (or rewritten) to disk. " 
and
2) "On very busy systems journal syncs can be bundled or deferred into multiple sync requests in a single sync operation."
Having mgstat logs for a (non-ECP) system, is it possible to predict future journal syncs rate after scaling horizontally to ECP cluster? E.g., if we have average and peak mgstat Gloupds values, can we predict future journal syncs rate? What is the top rate of journal syncs when their bundling/deferring begins?

Alexey Maslov · Oct 26, 2016 go to post

Hi Anzelem,

May I ask you a couple of questions on your DR solution?

Which node would take over on Primary failure: Cache Mirror Backup or VCS secondary if both are alive?

More general: what is the main reason of mixing 2 different DR approaches?

=Thanks

Alexey Maslov · Oct 29, 2016 go to post

Certainly yes: SQL quering of Audit database (%SYS.Audit) won't help if Auditing is switched off.

Alexey Maslov · Oct 30, 2016 go to post

I've amended the testing result due to some inaccuracy found.

New results surprised me as I didn't expect to scan a local array about 10 times faster than to create a new one. 

Alexey Maslov · Oct 31, 2016 go to post

Bob,

I have a couple of questions on DR Async.

1) There is an option of DR Promotion and Manual Failover with Journal Data from Journal Files
( http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY… )
where one is advised to get journal files from one of failover members.
If both failover members are not available, is it possible to get journal files from another (DR or reporting) Async member?
If so, what preliminary configuration steps one should proceed on that member to allow this option in the case of disaster?


2) Another question is on journal files collection as well. You wrote: 

Asyncs receive journal data from the primary asynchronously, and as a result may sometimes be a few journal records behind

Is it true that Asyncs pulls journal data from Primary? If so, Primary is not aware of whether data was pulled by Async or not. Therefore, if Async was not getting journal data from Primary for several days (e.g. due to communication problems), the next unread journal file can be already purged from Primary's local storage.

Is it possible to recover from this situation without rebuilding Async? E.g., if the purged journals are available as a part of file system level backup, or those files are kept on another Async server, can it help?

==
Thanks...

Alexey Maslov · Oct 31, 2016 go to post

The version of Caché is 2015.1.4 for Windows x64, on Core i5 based laptop. When I have a time gap, I'd re-run this test on more powerful server, while I don't expect a noticeable difference.

Let's try to estimate time for both operations:
1: set max(args(i))=i ~ time_to_find_args(i)_position_in_max_array + time_to_allocate_memory_for_max(args(i)) ~  O(ln(length(args(i))) + O(length(args(i)+length(i))) ~ O(3*ln(length(args(i)))
2: max<args(i)  ~ time_to_compare_max_and_args(i) ~ O(ln(length(args(i))))

So it seems that 2 should be ~3 times quicker than 1, but we don't know real coefficients which stand behind those O() estimations. I should confess that local array node allocation penalty turned to be higher than I expected.

This speed difference should be even more would args(i) values be strings rather than numbers.

Alexey Maslov · Oct 31, 2016 go to post

Thank you, Bob, you mostly answered my questions.

you would compare the name and date of the most recent journal file from the async to the most recent journal file on the DR you are going to promote to see if you can get more recent journal data, which may not be the most recent.

At the meantime we are (internally) discussing the worst case of complete isolation of main Data Centre, so both Member A and B can be not available. In this case the only thing we can do is to check if the DR Async we are going to promote has the more recent journal data among all other available Asyncs, right?

Alexey Maslov · Oct 31, 2016 go to post

Are there any plans to introduce in 2017.1 a feature of Quick Old Primary Switching Back which seems to be of great importance for the scenario of temporary move of the Primary role to Promoted Async DR? It is known as Prodlog 142446. In a few words:

After the promotion of DR Async without partners check, the old Primary / Backup members functionality would be likely restored only after rebuilt. Copying the ~1TB backup using long distance link can take many hours or even days, so it will be nice to track a point when the databases were last time "in sync" (while I'm not sure if this term can be used in the case of DR async). After that:
- discard the SETs/KILLs that could be made on old primary after this point
- demote (?) it to be a new DR async
- having the most recent journal on this new DR async, we can promote it to be a very new primary (returning it its "native" role).

Alexey Maslov · Oct 31, 2016 go to post

Thank you, Ray.
As to our modest experience, WAN failure was the only type of disasters through two years of Krasnoyarsk Data Center of Regional HIS production life, so its potential network isolation does not seem to be non-realistic.
We hope that the mentioned enhancement would not come too late.

Alexey Maslov · Nov 17, 2016 go to post

Thank you, John. I've corrected this terminological mix which occurred due to my efforts of making introduction part as short as possible.
P.S. Of course, I remember DCP and DDP (not mentioning RVG). Cheers!

Alexey Maslov · Nov 18, 2016 go to post

Hi Wolf,

Thank you for the info. As to big string data caching enhancement, I guess that it was targeted mostly to bitmap indexes performance improvement; maybe somebody from InterSystems would like to comment it.

Alexey Maslov · Nov 22, 2016 go to post

Did it work better than what?

Both classes are really the same one, as %Library is the default package name for %-classes.

Alexey Maslov · Nov 27, 2016 go to post

Eugene mentions OMI and ECP as traditional interconnection kinds of transport. None of them is quite secure, one may check docs for proof (as to ECP: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY… ).

ECP is defined as a basic service in contrast to resource based ones. Basic services can't efficiently use resource/roles/users security model by design. It's understood as their layer is usually too low to apply it.

Eugene's services can be dealt with the same precautions as other basic services, i.e. inside secured perimeter only. Port 500x can (and should) be closed on external firewall.

Alexey Maslov · Dec 7, 2016 go to post

Thanks, Andreas.

Will Caché_for_Ubuntu Field Test kit be published on your Developer Download portal?

Alexey Maslov · Dec 8, 2016 go to post

Hi Murray,
Speaking of ECP, we usually imagine distributed data processing on several app servers. But what about distributed databases? E.g., can the solution to split the databases among several data servers just to distribute heavy journal and/or write daemon load be smart in some cases?
I see some drawbacks of this solution:
#1 AFAIK, there is no distributed transactions support in Caché.
#2 To couple it with mirroring, one should deploy N mirrors, where N is the number of (primary) data servers; having no option of "coherent mirroring", their N backup members can have different latency against their primaries, so (baring in mind #1) switching mirror members can have worse consequences as in traditional case of only one (primary) data server.

Have I missed something? Maybe you've seen some field cases when distributing databases looked smart, haven't you?

Thank you,

Alexey Maslov · Dec 26, 2016 go to post

Well done, Dima! Just my 2c: any key should be really any. The correction is easy: change exit condition to

r q:0 q:$t

Season greetings to everybody!

Alexey Maslov · Dec 29, 2016 go to post

c. Map the relevant globals to a non-journaled database

Sometimes it's being done just to conceal some typical app level drawbacks (such as missing the cases when  temporary globals can be used, (excessive) looped rewrites of persistent data, etc) although it may lead to more serious administrative level drawbacks.

Normally all app's globals (whether they are journaled or not) should by coordinated with each other; if a global should not (or may not), it is a good candidate to be mapped to CACHETEMP DB. Any fail-over scenario you may imagine includes a step of journal restoration. Believe me, it can be a great problem for admin to decide what to do with each non-journaled global after the server fault: which one can be fully (or partially) KILLed, and which one need to be ^REPAIRed. Mostly the right decision is impossible without the developer's intervention. So, the simple dev level solution can introduce much more serious admin level complications.

IMHO, a global should be considered of one of two types basing on its content type:
1. "normal" persistent data: such global should be placed in journaled DB without any exceptions;
2. temporary data which is need only during process run: map it to CACHETEMP or make it private ^||global.

Sometimes I was told by developers that a third type exists which comprises some pre-generated data that is stored to improve performance of some heavy jobs (e.g. reporting). The pre-generation process can be time (and resource) consuming, so it looks like that the best place for this 3d type globals is a non-journaled DB. After several database reparations I'd answer "No!". Depending on pre-generation process details, each of these globals can (and should) be put in one of two categories taking in account that reboots of modern servers are relatively rare events:
- if it's not too hard to regenerate the data: just automate it in your code and map the global to CACHETEMP;
- if not, consider your global as operational one and place it into journaled DB; to reduce excessive journaling during its generation, just choose between approaches "e" or "d" of Tani's article.

Alexey Maslov · Jan 3, 2017 go to post

As we say in this country, "all psychics are on vacations".
Did you notice any messages that may appear in console log or in backup log?