Changeset: babb06e8fe55 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=babb06e8fe55
Modified Files:
monetdb5/mal/mal.c
monetdb5/mal/mal_client.c
monetdb5/mal/mal_client.h
monetdb5/mal/mal_session.c
monetdb5/modules/mal/clients.c
monetdb5/modules/mal/clients.h
monetdb5/modules/mal/clients.mal
sql/backends/monet5/sql.mx
sql/scripts/22_clients.sql
Branch: default
Log Message:
Constrolled shutdown
Stopping a server should be performed by the monetdb administrator.
For this he can log onto the database using mclient and issue the
following operations.
select * from sys.sessions;
to see how many users are still active
call sys.shutdown(10);
to initiate stopping all other clients within 10 seconds
at sage MAL boundaries.
The outcome can be inspected with
select * from sys.sessions;
During shutdown no clients can establish a connection anywmore.
Upon a quiet system the last console can be closed and the server
can safely stopped with 'monetdb stop <db>'
Alternatively, the command
call sys.shutdown(10,true)
will terminate the server forcefully after 10 seconds.
diffs (truncated from 329 to 300 lines):
diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c
--- a/monetdb5/mal/mal.c
+++ b/monetdb5/mal/mal.c
@@ -305,38 +305,6 @@ int mal_init(void){
*
* Beware, mal_exit is also called during a SIGTERM from the monetdb tool
*/
-static void stopClients(void)
-{
- Client cntxt = mal_clients;
-
- MT_lock_set(&mal_contextLock,"stopClients");
- for(cntxt= mal_clients +1; cntxt < mal_clients+MAL_MAXCLIENTS; cntxt++)
- if ( cntxt->mode == RUNCLIENT)
- cntxt->mode = FINISHCLIENT;
- else if (cntxt->mode == FREECLIENT)
- cntxt->mode = BLOCKCLIENT;
- MT_lock_unset(&mal_contextLock,"stopClients");
-}
-
-int
-moreClients(int reruns)
-{
- int freeclient=0, finishing=0, running=0, blocked = 0;
- Client cntxt = mal_clients;
-
- for(cntxt= mal_clients+1; cntxt<mal_clients+MAL_MAXCLIENTS; cntxt++){
- freeclient += (cntxt->mode == FREECLIENT);
- finishing += (cntxt->mode == FINISHCLIENT);
- running += (cntxt->mode == RUNCLIENT);
- blocked += (cntxt->mode == BLOCKCLIENT);
- }
- if( reruns > 3){
- printf("MALexit: server forced exit %d free %d finishing %d
running %d blocked\n",
- freeclient, finishing,running, blocked);
- return 0;
- }
- return finishing+running;
-}
void mal_exit(void){
str err;
@@ -345,16 +313,15 @@ void mal_exit(void){
* Before continuing we should make sure that all clients
* (except the console) have left the scene.
*/
- stopClients();
+ MCstopClients(0);
#if 0
{
int reruns=0, go_on;
do{
- if ( (go_on = moreClients(reruns)) )
+ if ( (go_on = MCactiveClients()) )
MT_sleep_ms(1000);
- if(reruns)
- mnstr_printf(mal_clients->fdout,"#MALexit: clients
still active\n");
- } while (++reruns < SERVERSHUTDOWNDELAY && go_on);
+ mnstr_printf(mal_clients->fdout,"#MALexit: %d clients still
active\n", go_on);
+ } while (++reruns < SERVERSHUTDOWNDELAY && go_on > 1);
}
#endif
stopHeartbeat();
diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -373,7 +373,7 @@ freeClient(Client c)
c->stimeout = 0;
c->user = oid_nil;
c->mythread = 0;
- c->mode = FREECLIENT;
+ c->mode = MCshutdowninprogress()? BLOCKCLIENT: FREECLIENT;
GDKfree(c->glb);
c->glb = NULL;
if (t)
@@ -392,7 +392,49 @@ freeClient(Client c)
*
* Furthermore, once we enter closeClient, the process in which it is
* raised has already lost its file descriptors.
+ *
+ * When the server is about to shutdown, we should softly terminate
+ * all outstanding session.
*/
+static int shutdowninprogress = 0;
+
+int
+MCshutdowninprogress(void){
+ return shutdowninprogress;
+}
+
+void
+MCstopClients(Client cntxt)
+{
+ Client c = mal_clients;
+
+ MT_lock_set(&mal_contextLock,"stopClients");
+ for(c= mal_clients +1; c < mal_clients+MAL_MAXCLIENTS; c++)
+ if( cntxt != c){
+ if ( c->mode == RUNCLIENT)
+ c->mode = FINISHCLIENT;
+ else if (c->mode == FREECLIENT)
+ c->mode = BLOCKCLIENT;
+ }
+ shutdowninprogress =1;
+ MT_lock_unset(&mal_contextLock,"stopClients");
+}
+
+int
+MCactiveClients(void)
+{
+ int freeclient=0, finishing=0, running=0, blocked = 0;
+ Client cntxt = mal_clients;
+
+ for(cntxt= mal_clients+1; cntxt<mal_clients+MAL_MAXCLIENTS; cntxt++){
+ freeclient += (cntxt->mode == FREECLIENT);
+ finishing += (cntxt->mode == FINISHCLIENT);
+ running += (cntxt->mode == RUNCLIENT);
+ blocked += (cntxt->mode == BLOCKCLIENT);
+ }
+ return finishing+running;
+}
+
void
MCcloseClient(Client c)
{
diff --git a/monetdb5/mal/mal_client.h b/monetdb5/mal/mal_client.h
--- a/monetdb5/mal/mal_client.h
+++ b/monetdb5/mal/mal_client.h
@@ -192,6 +192,9 @@ mal_export Client MCgetClient(int id);
mal_export Client MCinitClient(oid user, bstream *fin, stream *fout);
mal_export Client MCinitClientRecord(Client c, oid user, bstream *fin, stream
*fout);
mal_export int MCinitClientThread(Client c);
+mal_export void MCstopClients(Client c);
+mal_export int MCshutdowninprogress(void);
+mal_export int MCactiveClients(void);
mal_export void MCcloseClient(Client c);
mal_export str MCsuspendClient(int id);
mal_export str MCawakeClient(int id);
diff --git a/monetdb5/mal/mal_session.c b/monetdb5/mal/mal_session.c
--- a/monetdb5/mal/mal_session.c
+++ b/monetdb5/mal/mal_session.c
@@ -283,8 +283,11 @@ MSscheduleClient(str command, str challe
c = MCinitClient(uid, fin, fout);
if (c == NULL) {
- mnstr_printf(fout, "!maximum concurrent client limit
reached "
- "(%d), please try
again later\n", MAL_MAXCLIENTS);
+ if ( MCshutdowninprogress())
+ mnstr_printf(fout, "!system shutdown in
progress, please try again later\n");
+ else
+ mnstr_printf(fout, "!maximum concurrent client
limit reached "
+ "(%d),
please try again later\n", MAL_MAXCLIENTS);
exit_streams(fin, fout);
GDKfree(command);
return;
diff --git a/monetdb5/modules/mal/clients.c b/monetdb5/modules/mal/clients.c
--- a/monetdb5/modules/mal/clients.c
+++ b/monetdb5/modules/mal/clients.c
@@ -35,6 +35,7 @@
#include "mal_instruction.h"
#include "mal_client.h"
#include "mal_authorize.h"
+#include "mal_private.h"
#include "mtime.h"
#ifdef HAVE_LIBREADLINE
@@ -545,10 +546,41 @@ str CLTgetUsers(Client cntxt, MalBlkPtr
return(MAL_SUCCEED);
}
-str CLTshutdown(int *ret, bit *forced) {
- (void) ret;
- (void) forced;
- throw(MAL,"clients.shutdown", PROGRAM_NYI);
+str
+CLTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
+ str *ret = (str*) getArgReference(stk,pci,0);
+ int delay = *(int*) getArgReference(stk,pci,1);
+ bit force = FALSE;
+ int leftover;
+ char buf[1024]={"safe to stop last connection"};
+
+ if ( pci->argc == 3)
+ force = *(bit*) getArgReference(stk,pci,2);
+
+ (void) mb;
+ switch( getArgType(mb,pci,1)){
+ case TYPE_bte:
+ case TYPE_sht:
+ delay = *(sht*) getArgReference(stk,pci,1);
+ break;
+ default:
+ delay = *(int*) getArgReference(stk,pci,1);
+ }
+
+ if ( cntxt->user != mal_clients[0].user)
+ throw(MAL,"mal.shutdown", "Administrator rights required");
+ MCstopClients(cntxt);
+ do{
+ if ( (leftover = MCactiveClients()) )
+ MT_sleep_ms(1000);
+ delay --;
+ } while (delay > 0 && leftover > 1);
+ if( delay == 0 && leftover > 1)
+ snprintf(buf, 1024,"%d client sessions still running",leftover);
+ *ret = GDKstrdup(buf);
+ if ( force)
+ mal_exit();
+ return MAL_SUCCEED;
}
str
@@ -592,7 +624,7 @@ CLTsessions(Client cntxt, MalBlkPtr mb,
MT_lock_set(&mal_contextLock, "clients.sessions");
- for (c = mal_clients; c < mal_clients + MAL_MAXCLIENTS; c++)
+ for (c = mal_clients + (GDKgetenv_isyes("monet_daemon")?1:0); c <
mal_clients + MAL_MAXCLIENTS; c++)
if (c->mode == RUNCLIENT) {
BUNappend(user, &usrname, FALSE);
(void) MTIMEunix_epoch(&ts);
diff --git a/monetdb5/modules/mal/clients.h b/monetdb5/modules/mal/clients.h
--- a/monetdb5/modules/mal/clients.h
+++ b/monetdb5/modules/mal/clients.h
@@ -56,7 +56,7 @@ clients_export str CLTsetSessionTimeout(
clients_export str CLTgetTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
clients_export str CLTwakeup(int *ret, int *id);
-clients_export str CLTshutdown(int *ret, bit *forced);
+clients_export str CLTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
clients_export str CLTmd5sum(str *ret, str *pw);
clients_export str CLTsha1sum(str *ret, str *pw);
clients_export str CLTripemd160sum(str *ret, str *pw);
diff --git a/monetdb5/modules/mal/clients.mal b/monetdb5/modules/mal/clients.mal
--- a/monetdb5/modules/mal/clients.mal
+++ b/monetdb5/modules/mal/clients.mal
@@ -91,16 +91,17 @@ comment "A query is aborted after q mill
The session timeout aborts the connection after spending too
many seconds on query processing.";
-command shutdown(forced:bit):void
-address CLTshutdown
-comment "Close all client connections. If forced=false the
-clients are moved into finishing mode, which means that
-the process stops at the next cycle of the scenario.
-If forced=true all client processes are immediately killed";
-
# @+ User administration
# These commands (except changePassword, changeUsername and
# checkPermission) can only be executed by the administrator.
+
+pattern shutdown(delay:int):str
+address CLTshutdown;
+pattern shutdown(delay:int, forced:bit):str
+address CLTshutdown
+comment "Close all other client connections. Return if it succeeds.
+If forced is set then always stop the system the hard way";
+
command md5sum(pw:str):str
address CLTmd5sum
comment "Return hex string representation of the MD5 hash of the given string";
diff --git a/sql/backends/monet5/sql.mx b/sql/backends/monet5/sql.mx
--- a/sql/backends/monet5/sql.mx
+++ b/sql/backends/monet5/sql.mx
@@ -45,6 +45,20 @@ pattern init():void
address SQLinitEnvironment
comment "Initialize the environment for MAL";
+pattern shutdown(delay:bte, force:bit):str
+address SQLshutdown_wrap;
+pattern shutdown(delay:sht, force:bit):str
+address SQLshutdown_wrap;
+pattern shutdown(delay:int, force:bit):str
+address SQLshutdown_wrap;
+
+pattern shutdown(delay:bte):str
+address SQLshutdown_wrap;
+pattern shutdown(delay:sht):str
+address SQLshutdown_wrap;
+pattern shutdown(delay:int):str
+address SQLshutdown_wrap;
+
pattern mvc():int
address SQLmvc
comment "get the multiversion catalog context, needed for correct statement
dependencies (ie sql.update, should be after sql.bind in concurrent execution)";
@@ -1366,6 +1380,7 @@ sql5_export str SQLmvc(Client cntxt, Mal
sql5_export str SQLtransaction(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
sql5_export str SQLcommit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
sql5_export str SQLabort(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
+sql5_export str SQLshutdown_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
sql5_export str SQLtransaction2(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
sql5_export str SQLcatalog(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
@@ -1973,6 +1988,18 @@ SQLabort(Client cntxt, MalBlkPtr mb, Mal
}
str
+SQLshutdown_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+ str answ = *(str*) getArgReference(stk,pci,0);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list